diff --git a/.agents/skills/ask-matt/SKILL.md b/.agents/skills/ask-matt/SKILL.md
index 793caca7c..df014dc36 100644
--- a/.agents/skills/ask-matt/SKILL.md
+++ b/.agents/skills/ask-matt/SKILL.md
@@ -36,13 +36,13 @@ The limit on this is the **[smart zone](https://www.aihero.dev/ai-coding-diction
A starting situation that generates work, then merges onto the main flow.
-- **Bugs and requests piling up** → **`/triage`**. It moves issues through triage roles and produces agent-ready issues, which **`/implement`** later picks up.
+- **Bugs and requests piling up** → **`/triage`**. It moves issues through triage roles and produces agent-ready issues, which **`/implement`** later picks up.
Triage is only for issues **you didn't create** — bug reports, incoming feature requests, anything that arrives raw. Tickets that `/to-tickets` produced are already agent-ready, so **don't triage them**.
-- **Something's broken** → **`/diagnosing-bugs`**. For the hard ones: the bug that resists a first glance, the intermittent flake, the regression that crept in between two known-good states. It refuses to theorise until it has a **tight feedback loop** — one command that already goes red on _this_ bug — then fixes with a regression test. Its post-mortem hands off to **`/improve-codebase-architecture`** when the real finding is that there's no good seam to lock the bug down.
+- **Something's broken** → **`/diagnosing-bugs`**. For the hard ones: the bug that resists a first glance, the intermittent flake, the regression that crept in between two known-good states. It refuses to theorise until it has a **tight feedback loop** — one command that already goes red on _this_ bug — then fixes with a regression test. Its post-mortem hands off to **`/improve-codebase-architecture`** when the real finding is that there's no good seam to lock the bug down.
-- **A huge, foggy effort — a greenfield project or a huge feature build, too big for one session** → **`/wayfinder`**, the most cognitively demanding flow here. When the way from here to the destination isn't visible yet, it charts a **shared map** of **decision tickets** on the issue tracker and resolves them one at a time — producing **decisions, not deliverables** — until the fog is pushed back and the way is clear. Where **`/grill-with-docs`** sharpens an idea you can hold in one session, wayfinder is for the idea you can't — and it's slower and denser, so save it for exactly that, never a well-scoped feature.
+- **A huge, foggy effort — a greenfield project or a huge feature build, too big for one session** → **`/wayfinder`**, the most cognitively demanding flow here. When the way from here to the destination isn't visible yet, it charts a **shared map** of **decision tickets** on the issue tracker and resolves them one at a time — producing **decisions, not deliverables** — until the fog is pushed back and the way is clear. Where **`/grill-with-docs`** sharpens an idea you can hold in one session, wayfinder is for the idea you can't — and it's slower and denser, so save it for exactly that, never a well-scoped feature.
When the map clears, **it hands off, it doesn't build**: merge onto the main flow at **`/to-spec`**, which collapses the map's linked decisions into a buildable plan, then `/to-tickets` and `/implement` as usual. Looping the map straight into `/implement` skips that collapse and throws the linked detail away — go straight to `/implement` only when the effort turned out genuinely small.
@@ -50,29 +50,29 @@ A starting situation that generates work, then merges onto the main flow.
Not feature work — upkeep.
-- **`/improve-codebase-architecture`** — run whenever you have a spare moment to keep the codebase good for agents to operate in. It surfaces **deepening opportunities**; picking one _generates an idea_ you can take into the main flow at `/grill-with-docs`. It's the survey that finds the candidates; **`/codebase-design`** (below) is the bench you design the chosen one on.
+- **`/improve-codebase-architecture`** — run whenever you have a spare moment to keep the codebase good for agents to operate in. It surfaces **deepening opportunities**; picking one _generates an idea_ you can take into the main flow at `/grill-with-docs`. It's the survey that finds the candidates; **`/codebase-design`** (below) is the bench you design the chosen one on.
## Vocabulary underneath
Two model-invoked references that run _beneath_ the other skills — each the single source of truth for its vocabulary. Reach for them directly when the **words**, not the process, are the problem; or let the skills above pull them in.
-- **`/domain-modeling`** — sharpen the project's _domain_ language: challenge a fuzzy term, resolve an overloaded word ("account" doing three jobs), record a hard-to-reverse decision as an ADR. It's the active discipline `/grill-with-docs` drives to keep `CONTEXT.md` a clean glossary.
-- **`/codebase-design`** — the deep-module vocabulary (module, interface, depth, seam, adapter, leverage, locality) for designing a module's _shape_: a lot of behaviour behind a small interface at a clean seam. `/tdd` and `/improve-codebase-architecture` both speak it.
+- **`/domain-modeling`** — sharpen the project's _domain_ language: challenge a fuzzy term, resolve an overloaded word ("account" doing three jobs), record a hard-to-reverse decision as an ADR. It's the active discipline `/grill-with-docs` drives to keep `CONTEXT.md` a clean glossary.
+- **`/codebase-design`** — the deep-module vocabulary (module, interface, depth, seam, adapter, leverage, locality) for designing a module's _shape_: a lot of behaviour behind a small interface at a clean seam. `/tdd` and `/improve-codebase-architecture` both speak it.
## Crossing sessions
-- **`/handoff`** — when a thread is full or you need to branch off (e.g. into a `/prototype` session), this compacts the conversation into a markdown file. You don't continue in place — you **open a new session and reference that file** to carry the context across. It's the bridge between context windows, in either direction. Use it when you want a **fresh session** but need the **current conversation preserved**.
-- **`/compact`** (built-in) — stay in the **same conversation**, letting the earlier turns be summarized. Use it at **intentional breaks between phases**, when you don't mind losing the verbatim history. Don't compact mid-phase — the agent can lose its way. `/handoff` forks; `/compact` continues.
+- **`/handoff`** — when a thread is full or you need to branch off (e.g. into a `/prototype` session), this compacts the conversation into a markdown file. You don't continue in place — you **open a new session and reference that file** to carry the context across. It's the bridge between context windows, in either direction. Use it when you want a **fresh session** but need the **current conversation preserved**.
+- **`/compact`** (built-in) — stay in the **same conversation**, letting the earlier turns be summarized. Use it at **intentional breaks between phases**, when you don't mind losing the verbatim history. Don't compact mid-phase — the agent can lose its way. `/handoff` forks; `/compact` continues.
## Standalone
Off the main flow entirely.
-- **`/grill-me`** — the same relentless interview as `/grill-with-docs`, but for when you have **no codebase**. Stateless: it saves nothing locally, builds no `CONTEXT.md`. Reach for it to sharpen any plan or design that doesn't live in a repo.
-- **`/prototype`** — a small, throwaway program that answers one design question: does this state model feel right, or what should this UI look like. Throwaway from day one — keep the answer, delete the code. It's the detour in step 2 of the main flow, but reach for it any time a design question is hard to settle on paper.
-- **`/research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take _into_ the main flow at `/grill-with-docs` — research feeds the thinking, it doesn't replace it.
-- **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace.
-- **`/writing-great-skills`** — reference for writing and editing skills well.
+- **`/grill-me`** — the same relentless interview as `/grill-with-docs`, but for when you have **no codebase**. Stateless: it saves nothing locally, builds no `CONTEXT.md`. Reach for it to sharpen any plan or design that doesn't live in a repo.
+- **`/prototype`** — a small, throwaway program that answers one design question: does this state model feel right, or what should this UI look like. Throwaway from day one — keep the answer, delete the code. It's the detour in step 2 of the main flow, but reach for it any time a design question is hard to settle on paper.
+- **`/research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take _into_ the main flow at `/grill-with-docs` — research feeds the thinking, it doesn't replace it.
+- **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace.
+- **`/writing-great-skills`** — reference for writing and editing skills well.
## Precondition
diff --git a/.agents/skills/code-review/SKILL.md b/.agents/skills/code-review/SKILL.md
index eaf823678..fe4fefb44 100644
--- a/.agents/skills/code-review/SKILL.md
+++ b/.agents/skills/code-review/SKILL.md
@@ -5,8 +5,8 @@ description: Review the changes since a fixed point (commit, branch, tag, or mer
Two-axis review of the diff between `HEAD` and a fixed point the user supplies:
-- **Standards** — does the code conform to this repo's documented coding standards?
-- **Spec** — does the code faithfully implement the originating issue / PRD / spec?
+- **Standards** — does the code conform to this repo's documented coding standards?
+- **Spec** — does the code faithfully implement the originating issue / PRD / spec?
Both axes run as **parallel sub-agents** so they don't pollute each other's context, then this skill aggregates their findings.
@@ -37,23 +37,23 @@ Anything in the repo that documents how code should be written, such as `CODING_
On top of whatever the repo documents, the Standards axis always carries the **smell baseline** below — a fixed set of Fowler code smells (_Refactoring_, ch.3) that applies even when a repo documents nothing. Two rules bind it:
-- **The repo overrides.** A documented repo standard always wins; where it endorses something the baseline would flag, suppress the smell.
-- **Always a judgement call.** Each smell is a labelled heuristic ("possible Feature Envy"), never a hard violation — and, like any standard here, skip anything tooling already enforces.
+- **The repo overrides.** A documented repo standard always wins; where it endorses something the baseline would flag, suppress the smell.
+- **Always a judgement call.** Each smell is a labelled heuristic ("possible Feature Envy"), never a hard violation — and, like any standard here, skip anything tooling already enforces.
Each smell reads _what it is_ → _how to fix_; match it against the diff:
-- **Mysterious Name** — a function, variable, or type whose name doesn't reveal what it does or holds. → rename it; if no honest name comes, the design's murky.
-- **Duplicated Code** — the same logic shape appears in more than one hunk or file in the change. → extract the shared shape, call it from both.
-- **Feature Envy** — a method that reaches into another object's data more than its own. → move the method onto the data it envies.
-- **Data Clumps** — the same few fields or params keep travelling together (a type wanting to be born). → bundle them into one type, pass that.
-- **Primitive Obsession** — a primitive or string standing in for a domain concept that deserves its own type. → give the concept its own small type.
-- **Repeated Switches** — the same `switch`/`if`-cascade on the same type recurs across the change. → replace with polymorphism, or one map both sites share.
-- **Shotgun Surgery** — one logical change forces scattered edits across many files in the diff. → gather what changes together into one module.
-- **Divergent Change** — one file or module is edited for several unrelated reasons. → split so each module changes for one reason.
-- **Speculative Generality** — abstraction, parameters, or hooks added for needs the spec doesn't have. → delete it; inline back until a real need shows.
-- **Message Chains** — long `a.b().c().d()` navigation the caller shouldn't depend on. → hide the walk behind one method on the first object.
-- **Middle Man** — a class or function that mostly just delegates onward. → cut it, call the real target direct.
-- **Refused Bequest** — a subclass or implementer that ignores or overrides most of what it inherits. → drop the inheritance, use composition.
+- **Mysterious Name** — a function, variable, or type whose name doesn't reveal what it does or holds. → rename it; if no honest name comes, the design's murky.
+- **Duplicated Code** — the same logic shape appears in more than one hunk or file in the change. → extract the shared shape, call it from both.
+- **Feature Envy** — a method that reaches into another object's data more than its own. → move the method onto the data it envies.
+- **Data Clumps** — the same few fields or params keep travelling together (a type wanting to be born). → bundle them into one type, pass that.
+- **Primitive Obsession** — a primitive or string standing in for a domain concept that deserves its own type. → give the concept its own small type.
+- **Repeated Switches** — the same `switch`/`if`-cascade on the same type recurs across the change. → replace with polymorphism, or one map both sites share.
+- **Shotgun Surgery** — one logical change forces scattered edits across many files in the diff. → gather what changes together into one module.
+- **Divergent Change** — one file or module is edited for several unrelated reasons. → split so each module changes for one reason.
+- **Speculative Generality** — abstraction, parameters, or hooks added for needs the spec doesn't have. → delete it; inline back until a real need shows.
+- **Message Chains** — long `a.b().c().d()` navigation the caller shouldn't depend on. → hide the walk behind one method on the first object.
+- **Middle Man** — a class or function that mostly just delegates onward. → cut it, call the real target direct.
+- **Refused Bequest** — a subclass or implementer that ignores or overrides most of what it inherits. → drop the inheritance, use composition.
### 4. Spawn both sub-agents in parallel
@@ -61,15 +61,15 @@ Send a single message with two `Agent` tool calls. Use the `general-purpose` sub
**Standards sub-agent prompt** — include:
-- The full diff command and commit list.
-- The list of standards-source files you found in step 3, **plus the smell baseline from step 3** pasted in full — the sub-agent has no other access to it.
-- The brief: "Report — per file/hunk where relevant — (a) every place the diff violates a documented standard: cite the standard (file + the rule); and (b) any baseline smell you spot: name it and quote the hunk. Distinguish hard violations from judgement calls — documented-standard breaches can be hard, but baseline smells are always judgement calls, and a documented repo standard overrides the baseline. Skip anything tooling enforces. Under 400 words."
+- The full diff command and commit list.
+- The list of standards-source files you found in step 3, **plus the smell baseline from step 3** pasted in full — the sub-agent has no other access to it.
+- The brief: "Report — per file/hunk where relevant — (a) every place the diff violates a documented standard: cite the standard (file + the rule); and (b) any baseline smell you spot: name it and quote the hunk. Distinguish hard violations from judgement calls — documented-standard breaches can be hard, but baseline smells are always judgement calls, and a documented repo standard overrides the baseline. Skip anything tooling enforces. Under 400 words."
**Spec sub-agent prompt** — include:
-- The diff command and commit list.
-- The path or fetched contents of the spec.
-- The brief: "Report: (a) requirements the spec asked for that are missing or partial; (b) behaviour in the diff that wasn't asked for (scope creep); (c) requirements that look implemented but where the implementation looks wrong. Quote the spec line for each finding. Under 400 words."
+- The diff command and commit list.
+- The path or fetched contents of the spec.
+- The brief: "Report: (a) requirements the spec asked for that are missing or partial; (b) behaviour in the diff that wasn't asked for (scope creep); (c) requirements that look implemented but where the implementation looks wrong. Quote the spec line for each finding. Under 400 words."
If the spec is missing, skip the Spec sub-agent and note this in the final report.
@@ -83,7 +83,7 @@ End with a one-line summary: total findings per axis, and the worst issue _withi
A change can pass one axis and fail the other:
-- Code that follows every standard but implements the wrong thing → **Standards pass, Spec fail.**
-- Code that does exactly what the issue asked but breaks the project's conventions → **Spec pass, Standards fail.**
+- Code that follows every standard but implements the wrong thing → **Standards pass, Spec fail.**
+- Code that does exactly what the issue asked but breaks the project's conventions → **Spec pass, Standards fail.**
Reporting them separately stops one axis from masking the other.
diff --git a/.agents/skills/codebase-design/DEEPENING.md b/.agents/skills/codebase-design/DEEPENING.md
index 7f73de4d1..a3b75c671 100644
--- a/.agents/skills/codebase-design/DEEPENING.md
+++ b/.agents/skills/codebase-design/DEEPENING.md
@@ -26,12 +26,12 @@ Third-party services (Stripe, Twilio, etc.) you don't control. The deepened modu
## Seam discipline
-- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a port unless at least two adapters are justified (typically production + test). A single-adapter seam is just indirection.
-- **Internal seams vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface. Don't expose internal seams through the interface just because tests use them.
+- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a port unless at least two adapters are justified (typically production + test). A single-adapter seam is just indirection.
+- **Internal seams vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface. Don't expose internal seams through the interface just because tests use them.
## Testing strategy: replace, don't layer
-- Old unit tests on shallow modules become waste once tests at the deepened module's interface exist — delete them.
-- Write new tests at the deepened module's interface. The **interface is the test surface**.
-- Tests assert on observable outcomes through the interface, not internal state.
-- Tests should survive internal refactors — they describe behaviour, not implementation. If a test has to change when the implementation changes, it's testing past the interface.
+- Old unit tests on shallow modules become waste once tests at the deepened module's interface exist — delete them.
+- Write new tests at the deepened module's interface. The **interface is the test surface**.
+- Tests assert on observable outcomes through the interface, not internal state.
+- Tests should survive internal refactors — they describe behaviour, not implementation. If a test has to change when the implementation changes, it's testing past the interface.
diff --git a/.agents/skills/codebase-design/DESIGN-IT-TWICE.md b/.agents/skills/codebase-design/DESIGN-IT-TWICE.md
index 106ab66f8..49a7c42a2 100644
--- a/.agents/skills/codebase-design/DESIGN-IT-TWICE.md
+++ b/.agents/skills/codebase-design/DESIGN-IT-TWICE.md
@@ -10,9 +10,9 @@ Uses the vocabulary in [SKILL.md](SKILL.md) — **module**, **interface**, **sea
Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate:
-- The constraints any new interface would need to satisfy
-- The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md))
-- A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete
+- The constraints any new interface would need to satisfy
+- The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md))
+- A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete
Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel.
@@ -22,10 +22,10 @@ Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radi
Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint:
-- Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point."
-- Agent 2: "Maximise flexibility — support many use cases and extension."
-- Agent 3: "Optimise for the most common caller — make the default case trivial."
-- Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies."
+- Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point."
+- Agent 2: "Maximise flexibility — support many use cases and extension."
+- Agent 3: "Optimise for the most common caller — make the default case trivial."
+- Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies."
Include both [SKILL.md](SKILL.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language.
diff --git a/.agents/skills/codebase-design/SKILL.md b/.agents/skills/codebase-design/SKILL.md
index 0cd34b53c..814e97eb0 100644
--- a/.agents/skills/codebase-design/SKILL.md
+++ b/.agents/skills/codebase-design/SKILL.md
@@ -53,16 +53,16 @@ Use these terms exactly — don't substitute "component," "service," "API," or "
When designing an interface, ask:
-- Can I reduce the number of methods?
-- Can I simplify the parameters?
-- Can I hide more complexity inside?
+- Can I reduce the number of methods?
+- Can I simplify the parameters?
+- Can I hide more complexity inside?
## Principles
-- **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its interface.
-- **The deletion test.** Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep.
-- **The interface is the test surface.** Callers and tests cross the same seam. If you want to test _past_ the interface, the module is probably the wrong shape.
-- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something actually varies across it.
+- **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its interface.
+- **The deletion test.** Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep.
+- **The interface is the test surface.** Callers and tests cross the same seam. If you want to test _past_ the interface, the module is probably the wrong shape.
+- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something actually varies across it.
## Designing for testability
@@ -96,19 +96,19 @@ Good interfaces make testing natural:
## Relationships
-- A **Module** has exactly one **Interface** (the surface it presents to callers and tests).
-- **Depth** is a property of a **Module**, measured against its **Interface**.
-- A **Seam** is where a **Module**'s **Interface** lives.
-- An **Adapter** sits at a **Seam** and satisfies the **Interface**.
-- **Depth** produces **Leverage** for callers and **Locality** for maintainers.
+- A **Module** has exactly one **Interface** (the surface it presents to callers and tests).
+- **Depth** is a property of a **Module**, measured against its **Interface**.
+- A **Seam** is where a **Module**'s **Interface** lives.
+- An **Adapter** sits at a **Seam** and satisfies the **Interface**.
+- **Depth** produces **Leverage** for callers and **Locality** for maintainers.
## Rejected framings
-- **Depth as ratio of implementation-lines to interface-lines** (Ousterhout): rewards padding the implementation. We use depth-as-leverage instead.
-- **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow — interface here includes every fact a caller must know.
-- **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**.
+- **Depth as ratio of implementation-lines to interface-lines** (Ousterhout): rewards padding the implementation. We use depth-as-leverage instead.
+- **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow — interface here includes every fact a caller must know.
+- **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**.
## Going deeper
-- **Deepening a cluster given its dependencies** — see [DEEPENING.md](DEEPENING.md): dependency categories, seam discipline, and replace-don't-layer testing.
-- **Exploring alternative interfaces** — see [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md): spin up parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and seam placement.
+- **Deepening a cluster given its dependencies** — see [DEEPENING.md](DEEPENING.md): dependency categories, seam discipline, and replace-don't-layer testing.
+- **Exploring alternative interfaces** — see [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md): spin up parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and seam placement.
diff --git a/.agents/skills/diagnosing-bugs/SKILL.md b/.agents/skills/diagnosing-bugs/SKILL.md
index 5c0bfdb54..f400de7c1 100644
--- a/.agents/skills/diagnosing-bugs/SKILL.md
+++ b/.agents/skills/diagnosing-bugs/SKILL.md
@@ -34,9 +34,9 @@ Build the right feedback loop, and the bug is 90% fixed.
Treat the loop as a product. Once you have _a_ loop, **tighten** it:
-- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.)
-- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".)
-- Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.)
+- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.)
+- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".)
+- Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.)
A 30-second flaky loop is barely better than no loop; a 2-second deterministic one is tight — a debugging superpower.
@@ -52,10 +52,10 @@ Stop and say so explicitly. List what you tried. Ask the user for: (a) access to
Phase 1 is done when the loop is **tight** and **red-capable**: you can name **one command** — a script path, a test invocation, a curl — that you have **already run at least once** (paste the invocation and its output), and that is:
-- [ ] **Red-capable** — it drives the actual bug code path and asserts the **user's exact symptom**, so it can go red on this bug and green once fixed. Not "runs without erroring" — it must be able to _catch this specific bug_.
-- [ ] **Deterministic** — same verdict every run (flaky bugs: a pinned, high reproduction rate, per above).
-- [ ] **Fast** — seconds, not minutes.
-- [ ] **Agent-runnable** — you can run it unattended; a human in the loop only via `scripts/hitl-loop.template.sh`.
+- [ ] **Red-capable** — it drives the actual bug code path and asserts the **user's exact symptom**, so it can go red on this bug and green once fixed. Not "runs without erroring" — it must be able to _catch this specific bug_.
+- [ ] **Deterministic** — same verdict every run (flaky bugs: a pinned, high reproduction rate, per above).
+- [ ] **Fast** — seconds, not minutes.
+- [ ] **Agent-runnable** — you can run it unattended; a human in the loop only via `scripts/hitl-loop.template.sh`.
If you catch yourself reading code to build a theory before this command exists, **stop — jumping straight to a hypothesis is the exact failure this skill prevents.** No red-capable command, no Phase 2.
@@ -65,9 +65,9 @@ Run the loop. Watch it go red — the bug appears.
Confirm:
-- [ ] The loop produces the failure mode the **user** described — not a different failure that happens to be nearby. Wrong bug = wrong fix.
-- [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against).
-- [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it.
+- [ ] The loop produces the failure mode the **user** described — not a different failure that happens to be nearby. Wrong bug = wrong fix.
+- [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against).
+- [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it.
### Minimise
@@ -125,10 +125,10 @@ If a correct seam exists:
Required before declaring done:
-- [ ] Original repro no longer reproduces (re-run the Phase 1 loop)
-- [ ] Regression test passes (or absence of seam is documented)
-- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix)
-- [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location)
-- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns
+- [ ] Original repro no longer reproduces (re-run the Phase 1 loop)
+- [ ] Regression test passes (or absence of seam is documented)
+- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix)
+- [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location)
+- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns
**Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to the `/improve-codebase-architecture` skill with the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started.
diff --git a/.agents/skills/domain-modeling/ADR-FORMAT.md b/.agents/skills/domain-modeling/ADR-FORMAT.md
index 862f385c7..dc90176fa 100644
--- a/.agents/skills/domain-modeling/ADR-FORMAT.md
+++ b/.agents/skills/domain-modeling/ADR-FORMAT.md
@@ -18,9 +18,9 @@ That's it. An ADR can be a single paragraph. The value is in recording _that_ a
Only include these when they add genuine value. Most ADRs won't need them.
-- **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`) — useful when decisions are revisited
-- **Considered Options** — only when the rejected alternatives are worth remembering
-- **Consequences** — only when non-obvious downstream effects need to be called out
+- **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`) — useful when decisions are revisited
+- **Considered Options** — only when the rejected alternatives are worth remembering
+- **Consequences** — only when non-obvious downstream effects need to be called out
## Numbering
@@ -38,10 +38,10 @@ If a decision is easy to reverse, skip it — you'll just reverse it. If it's no
### What qualifies
-- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
-- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP."
-- **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out.
-- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
-- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
-- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
-- **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months.
+- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
+- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP."
+- **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out.
+- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
+- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
+- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
+- **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months.
diff --git a/.agents/skills/domain-modeling/CONTEXT-FORMAT.md b/.agents/skills/domain-modeling/CONTEXT-FORMAT.md
index d1a9e818b..eaf2a1857 100644
--- a/.agents/skills/domain-modeling/CONTEXT-FORMAT.md
+++ b/.agents/skills/domain-modeling/CONTEXT-FORMAT.md
@@ -24,10 +24,10 @@ _Avoid_: Client, buyer, account
## Rules
-- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`.
-- **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does.
-- **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs.
-- **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine.
+- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`.
+- **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does.
+- **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs.
+- **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine.
## Single vs multi-context repos
@@ -40,21 +40,21 @@ _Avoid_: Client, buyer, account
## Contexts
-- [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders
-- [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments
-- [Fulfillment](./src/fulfillment/CONTEXT.md) — manages warehouse picking and shipping
+- [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders
+- [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments
+- [Fulfillment](./src/fulfillment/CONTEXT.md) — manages warehouse picking and shipping
## Relationships
-- **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking
-- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices
-- **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
+- **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking
+- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices
+- **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
```
The skill infers which structure applies:
-- If `CONTEXT-MAP.md` exists, read it to find contexts
-- If only a root `CONTEXT.md` exists, single context
-- If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved
+- If `CONTEXT-MAP.md` exists, read it to find contexts
+- If only a root `CONTEXT.md` exists, single context
+- If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved
When multiple contexts exist, infer which one the current topic relates to. If unclear, ask.
diff --git a/.agents/skills/improve-codebase-architecture/HTML-REPORT.md b/.agents/skills/improve-codebase-architecture/HTML-REPORT.md
index a0ef381d0..568b0a431 100644
--- a/.agents/skills/improve-codebase-architecture/HTML-REPORT.md
+++ b/.agents/skills/improve-codebase-architecture/HTML-REPORT.md
@@ -53,14 +53,14 @@ The diagrams carry the weight. Prose is sparse, plain, and uses the glossary ter
Each candidate is one ``:
-- **Title** — short, names the deepening (e.g. "Collapse the Order intake pipeline").
-- **Badge row** — recommendation strength (`Strong` = emerald, `Worth exploring` = amber, `Speculative` = slate), plus a tag for the dependency category (`in-process`, `local-substitutable`, `ports & adapters`, `mock`).
-- **Files** — monospaced list, `font-mono text-sm`.
-- **Before / After diagram** — the centrepiece. Two columns, side by side. See patterns below.
-- **Problem** — one sentence. What hurts.
-- **Solution** — one sentence. What changes.
-- **Wins** — bullets, ≤6 words each. e.g. "Tests hit one interface", "Pricing logic stops leaking", "Delete 4 shallow wrappers".
-- **ADR callout** (if applicable) — one line in an amber-tinted box.
+- **Title** — short, names the deepening (e.g. "Collapse the Order intake pipeline").
+- **Badge row** — recommendation strength (`Strong` = emerald, `Worth exploring` = amber, `Speculative` = slate), plus a tag for the dependency category (`in-process`, `local-substitutable`, `ports & adapters`, `mock`).
+- **Files** — monospaced list, `font-mono text-sm`.
+- **Before / After diagram** — the centrepiece. Two columns, side by side. See patterns below.
+- **Problem** — one sentence. What hurts.
+- **Solution** — one sentence. What changes.
+- **Wins** — bullets, ≤6 words each. e.g. "Tests hit one interface", "Pricing logic stops leaking", "Delete 4 shallow wrappers".
+- **ADR callout** (if applicable) — one line in an amber-tinted box.
No paragraphs of explanation. If the diagram needs a paragraph to be understood, redraw the diagram.
@@ -81,8 +81,7 @@ Use a Mermaid `flowchart` or `graph` when the point is "X calls Y calls Z, and l
C -.leak.-> D[PricingClient]
classDef leak stroke:#dc2626,stroke-width:2px;
class C,D leak
-
+
```
@@ -104,11 +103,11 @@ Before: a tree of function calls rendered as nested boxes. After: the same tree
## Style guidance
-- Lean editorial, not corporate-dashboard. Generous whitespace. Serif optional for headings (`font-serif` works well with stone/slate).
-- Colour sparingly: one accent (emerald or indigo) plus red for leakage and amber for warnings.
-- Keep diagrams ~320px tall so before/after sits comfortably side by side without scrolling.
-- Use `text-xs uppercase tracking-wider` for module labels inside diagrams — they should read as schematic, not as UI.
-- The only scripts are the Tailwind CDN and the Mermaid ESM import. The report is otherwise static — no app code, no interactivity beyond Mermaid's own rendering.
+- Lean editorial, not corporate-dashboard. Generous whitespace. Serif optional for headings (`font-serif` works well with stone/slate).
+- Colour sparingly: one accent (emerald or indigo) plus red for leakage and amber for warnings.
+- Keep diagrams ~320px tall so before/after sits comfortably side by side without scrolling.
+- Use `text-xs uppercase tracking-wider` for module labels inside diagrams — they should read as schematic, not as UI.
+- The only scripts are the Tailwind CDN and the Mermaid ESM import. The report is otherwise static — no app code, no interactivity beyond Mermaid's own rendering.
## Top recommendation section
@@ -124,10 +123,10 @@ Plain English, concise — but the architectural nouns and verbs come straight f
**Phrasings that fit the style:**
-- "Order intake module is shallow — interface nearly matches the implementation."
-- "Pricing leaks across the seam."
-- "Deepen: one interface, one place to test."
-- "Two adapters justify the seam: HTTP in prod, in-memory in tests."
+- "Order intake module is shallow — interface nearly matches the implementation."
+- "Pricing leaks across the seam."
+- "Deepen: one interface, one place to test."
+- "Two adapters justify the seam: HTTP in prod, in-memory in tests."
**Wins bullets** name the gain in glossary terms: _"locality: bugs concentrate in one module"_, _"leverage: one interface, N call sites"_, _"interface shrinks; implementation absorbs the wrappers"_. Don't write _"easier to maintain"_ or _"cleaner code"_ — those terms aren't in the glossary and don't earn their place.
diff --git a/.agents/skills/improve-codebase-architecture/SKILL.md b/.agents/skills/improve-codebase-architecture/SKILL.md
index a84b66825..a7a5954fd 100644
--- a/.agents/skills/improve-codebase-architecture/SKILL.md
+++ b/.agents/skills/improve-codebase-architecture/SKILL.md
@@ -10,8 +10,8 @@ Surface architectural friction and propose **deepening opportunities** — refac
This command is _informed_ by the project's domain model and built on a shared design vocabulary:
-- Run the `/codebase-design` skill for the architecture vocabulary (**module**, **interface**, **depth**, **seam**, **adapter**, **leverage**, **locality**) and its principles (the deletion test, "the interface is the test surface", "one adapter = hypothetical seam, two = real"). Use these terms exactly in every suggestion — don't drift into "component," "service," "API," or "boundary."
-- The domain language in `CONTEXT.md` gives names to good seams; ADRs in `docs/adr/` record decisions this command should not re-litigate.
+- Run the `/codebase-design` skill for the architecture vocabulary (**module**, **interface**, **depth**, **seam**, **adapter**, **leverage**, **locality**) and its principles (the deletion test, "the interface is the test surface", "one adapter = hypothetical seam, two = real"). Use these terms exactly in every suggestion — don't drift into "component," "service," "API," or "boundary."
+- The domain language in `CONTEXT.md` gives names to good seams; ADRs in `docs/adr/` record decisions this command should not re-litigate.
## Process
@@ -19,18 +19,18 @@ This command is _informed_ by the project's domain model and built on a shared d
**Scope before you scan — YAGNI.** Deepening a module pays off by making future changes to it easier, so put extra weight on the parts of the codebase that have recently changed. Decide _where_ to look before you look:
-- If the user named a direction — a module, a subsystem, a pain point — take it, and skip the inference below.
-- Otherwise, walk back a good stretch of the commit history (`git log --oneline`) to find the codebase's hot spots — the files and areas that keep coming up — and let those paths pull your attention first. If the changes are scattered with no clear hot spot, widen the net.
+- If the user named a direction — a module, a subsystem, a pain point — take it, and skip the inference below.
+- Otherwise, walk back a good stretch of the commit history (`git log --oneline`) to find the codebase's hot spots — the files and areas that keep coming up — and let those paths pull your attention first. If the changes are scattered with no clear hot spot, widen the net.
Read the project's domain glossary (`CONTEXT.md`) and any ADRs in the area you're touching first.
Then use the Agent tool with `subagent_type=Explore` to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction:
-- Where does understanding one concept require bouncing between many small modules?
-- Where are modules **shallow** — interface nearly as complex as the implementation?
-- Where have pure functions been extracted just for testability, but the real bugs hide in how they're called (no **locality**)?
-- Where do tightly-coupled modules leak across their seams?
-- Which parts of the codebase are untested, or hard to test through their current interface?
+- Where does understanding one concept require bouncing between many small modules?
+- Where are modules **shallow** — interface nearly as complex as the implementation?
+- Where have pure functions been extracted just for testability, but the real bugs hide in how they're called (no **locality**)?
+- Where do tightly-coupled modules leak across their seams?
+- Which parts of the codebase are untested, or hard to test through their current interface?
Apply the **deletion test** to anything you suspect is shallow: would deleting it concentrate complexity, or just move it? A "yes, concentrates" is the signal you want.
@@ -42,12 +42,12 @@ The report uses **Tailwind via CDN** for layout and styling, and **Mermaid via C
For each candidate, render a card with:
-- **Files** — which files/modules are involved
-- **Problem** — why the current architecture is causing friction
-- **Solution** — plain English description of what would change
-- **Benefits** — explained in terms of locality and leverage, and how tests would improve
-- **Before / After diagram** — side-by-side, custom-drawn, illustrating the shallowness and the deepening
-- **Recommendation strength** — one of `Strong`, `Worth exploring`, `Speculative`, rendered as a badge
+- **Files** — which files/modules are involved
+- **Problem** — why the current architecture is causing friction
+- **Solution** — plain English description of what would change
+- **Benefits** — explained in terms of locality and leverage, and how tests would improve
+- **Before / After diagram** — side-by-side, custom-drawn, illustrating the shallowness and the deepening
+- **Recommendation strength** — one of `Strong`, `Worth exploring`, `Speculative`, rendered as a badge
End the report with a **Top recommendation** section: which candidate you'd tackle first and why.
@@ -65,7 +65,7 @@ Once the user picks a candidate, run the `/grilling` skill to walk the decision
Side effects happen inline as decisions crystallize — run the `/domain-modeling` skill to keep the domain model current as you go:
-- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md`. Create the file lazily if it doesn't exist.
-- **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there.
-- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones.
-- **Want to explore alternative interfaces for the deepened module?** Run the `/codebase-design` skill and use its design-it-twice parallel sub-agent pattern.
+- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md`. Create the file lazily if it doesn't exist.
+- **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there.
+- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones.
+- **Want to explore alternative interfaces for the deepened module?** Run the `/codebase-design` skill and use its design-it-twice parallel sub-agent pattern.
diff --git a/.agents/skills/prototype/LOGIC.md b/.agents/skills/prototype/LOGIC.md
index d16e77e2c..f83724469 100644
--- a/.agents/skills/prototype/LOGIC.md
+++ b/.agents/skills/prototype/LOGIC.md
@@ -4,10 +4,10 @@ A tiny interactive terminal app that lets the user drive a state model by hand.
## When this is the right shape
-- "I'm not sure if this state machine handles the edge case where X then Y."
-- "Does this data model actually let me represent the case where..."
-- "I want to feel out what the API should look like before writing it."
-- Anything where the user wants to **press buttons and watch state change**.
+- "I'm not sure if this state machine handles the edge case where X then Y."
+- "Does this data model actually let me represent the case where..."
+- "I want to feel out what the API should look like before writing it."
+- Anything where the user wants to **press buttons and watch state change**.
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
@@ -29,10 +29,10 @@ Put the actual logic — the bit that's answering the question — behind a smal
The right shape depends on the question:
-- **A pure reducer** — `(state, action) => state`. Good when actions are discrete events and state is a single value.
-- **A state machine** — explicit states and transitions. Good when "which actions are even legal right now" is part of the question.
-- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
-- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
+- **A pure reducer** — `(state, action) => state`. Good when actions are discrete events and state is a single value.
+- **A state machine** — explicit states and transitions. Good when "which actions are even legal right now" is part of the question.
+- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
+- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
Pick whichever shape best fits the question being asked, _not_ whichever is easiest to wire to a TUI. Keep it pure: no I/O, no terminal code, no `console.log` for control flow. The TUI imports it and calls into it; nothing flows the other direction.
@@ -72,8 +72,8 @@ Once the prototype has answered its question, capture the answer, then capture t
## Anti-patterns
-- **Don't add tests.** A prototype that needs tests is no longer a prototype.
-- **Don't wire it to the real database.** Use an in-memory store unless the question is specifically about persistence.
-- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
-- **Don't blur the logic and the TUI together.** If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable. Keep the TUI as a thin shell over a pure module.
-- **Don't ship the TUI shell into production.** The shell is optimised for being driven by hand from a terminal. The logic module behind it is the bit worth keeping.
+- **Don't add tests.** A prototype that needs tests is no longer a prototype.
+- **Don't wire it to the real database.** Use an in-memory store unless the question is specifically about persistence.
+- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
+- **Don't blur the logic and the TUI together.** If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable. Keep the TUI as a thin shell over a pure module.
+- **Don't ship the TUI shell into production.** The shell is optimised for being driven by hand from a terminal. The logic module behind it is the bit worth keeping.
diff --git a/.agents/skills/prototype/SKILL.md b/.agents/skills/prototype/SKILL.md
index 5f5ff323c..e75d5331c 100644
--- a/.agents/skills/prototype/SKILL.md
+++ b/.agents/skills/prototype/SKILL.md
@@ -11,8 +11,8 @@ A prototype is **throwaway code that answers a question**. The question decides
Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
-- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper.
-- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
+- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper.
+- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
diff --git a/.agents/skills/prototype/UI.md b/.agents/skills/prototype/UI.md
index 5c9154b74..e6b73ab24 100644
--- a/.agents/skills/prototype/UI.md
+++ b/.agents/skills/prototype/UI.md
@@ -6,10 +6,10 @@ If the question is about logic/state rather than what something looks like — w
## When this is the right shape
-- "What should this page look like?"
-- "I want to see a few options for this dashboard before committing."
-- "Try a different layout for the settings screen."
-- Any time the user would otherwise spend a day picking between three vague mockups in their head.
+- "What should this page look like?"
+- "I want to see a few options for this dashboard before committing."
+- "Try a different layout for the settings screen."
+- Any time the user would otherwise spend a day picking between three vague mockups in their head.
## Two sub-shapes — strongly prefer sub-shape A
@@ -47,9 +47,9 @@ This works whether the user is here to push back or not.
Draft each variant. Hold each one to:
-- The page's purpose and the data it has access to.
-- The project's component library / styling system (TailwindCSS, shadcn, MUI, plain CSS, whatever).
-- A clear exported component name, e.g. `VariantA`, `VariantB`, `VariantC`.
+- The page's purpose and the data it has access to.
+- The project's component library / styling system (TailwindCSS, shadcn, MUI, plain CSS, whatever).
+- A clear exported component name, e.g. `VariantA`, `VariantB`, `VariantC`.
Variants must be **structurally different** — different layout, different information hierarchy, different primary affordance, not just different colours. Three slightly-tweaked card grids isn't a UI prototype, it's wallpaper. If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance.
@@ -78,16 +78,16 @@ For sub-shape B (new page): the throwaway route under `/prototype/` mounts
A small fixed-position bar at the bottom-centre of the screen with three pieces:
-- **Left arrow** — cycles to the previous variant (wraps around).
-- **Variant label** — shows the current variant key and, if the variant exports a name, that name too. e.g. `B — Sidebar layout`.
-- **Right arrow** — cycles forward (wraps around).
+- **Left arrow** — cycles to the previous variant (wraps around).
+- **Variant label** — shows the current variant key and, if the variant exports a name, that name too. e.g. `B — Sidebar layout`.
+- **Right arrow** — cycles forward (wraps around).
Behaviour:
-- Clicking an arrow updates the URL search param (use the framework's router — `router.replace` on Next, `navigate` on React Router, etc) so the variant is shareable and reload-stable.
-- Keyboard: `←` and `→` arrow keys also cycle. Don't intercept arrow keys when an ` `, `
## Technologies Used
-- TypeScript
-- Next.js
-- MikroORM
-- Better Auth
-- Tailwind CSS
+- TypeScript
+- Next.js
+- MikroORM
+- Better Auth
+- Tailwind CSS
+
+## Demo and documentation
+
+- [Interactive demo](https://hackkit-demo.acm-utsa.workers.dev): explore a shared fictional event as a participant or organizer. [Deployment and local setup](apps/demo/README.md).
+- [Documentation](https://hackkit-docs.acm-utsa.workers.dev): setup, templates, architecture, plugins, operations, and testing. [Contributing to the docs](apps/docs/README.md).
+
+Configure the demo’s Turso credentials in `apps/demo/.dev.vars` and run its explicit database setup first; see [demo setup](apps/demo/README.md). `corepack pnpm dev:demo` then starts the demo on port 3001. `corepack pnpm dev:docs` starts Fumadocs on port 3002. The deployed apps live under `apps`; runnable workspace examples remain under `templates`.
## Development
-See [the reference app setup](apps/web/README.md) and [the persistence decision](docs/adr/0013-mikroorm-and-core-auth.md). This migration targets fresh databases.
+Use Node.js 22.17+ and the repository-pinned pnpm 12.15.0 through Corepack. Run `corepack pnpm install` from this directory.
+
+- [Full Next.js template](templates/nextjs-full/README.md): the existing app with Teams, Discord, email notifications, and configurable storage.
+- [Minimal Next.js template](templates/nextjs-minimal/README.md): Core registration, participant profiles, and basic administration with local SQLite and uploads.
+- [E2E validation](e2e/README.md): database, production HTTP, and browser integration checks against these templates.
+
+`corepack pnpm dev` and `corepack pnpm dev:full` start the full template. `corepack pnpm dev:minimal` starts the minimal template. Root `db:*` commands target the full template. Select the minimal package explicitly for its database commands. For a new project, configure the database and plugins, generate an initial migration with `db:generate --name initial`, review and apply it, then seed roles. Commit the generated migration and snapshot to your application repository. Templates ship without baseline migrations; later clones of an initialized application apply its committed history. Each template's README covers setup, owner bootstrap, and production configuration.
+
+`corepack pnpm build` builds libraries, templates, demo, and docs; configure each template for production first. `corepack pnpm test` runs package tests. `corepack pnpm test:e2e` prepares isolated configurations and runs all integration suites. Run one E2E invocation at a time because tests use fixed ports and each template's production output.
+
+Both templates remain workspace examples. [CLI init and standalone releases](docs/plans/template-distribution.md) are a separate milestone. See the [persistence decision](docs/adr/0013-mikroorm-and-core-auth.md) for database ownership.
## Join The Team
diff --git a/apps/demo/.dev.vars.example b/apps/demo/.dev.vars.example
new file mode 100644
index 000000000..6167600b2
--- /dev/null
+++ b/apps/demo/.dev.vars.example
@@ -0,0 +1,6 @@
+# Copy this file to .dev.vars in this directory. Never commit .dev.vars.
+TURSO_DATABASE_URL=libsql://your-database.turso.io
+TURSO_AUTH_TOKEN=
+BETTER_AUTH_SECRET=
+# Local application origin. The deployed origin lives in wrangler.jsonc.
+BETTER_AUTH_URL=http://localhost:3001
\ No newline at end of file
diff --git a/apps/demo/.env.example b/apps/demo/.env.example
new file mode 100644
index 000000000..b598b592d
--- /dev/null
+++ b/apps/demo/.env.example
@@ -0,0 +1 @@
+# The Worker reads .dev.vars. Copy .dev.vars.example to .dev.vars.
diff --git a/apps/demo/README.md b/apps/demo/README.md
new file mode 100644
index 000000000..bd912e6b1
--- /dev/null
+++ b/apps/demo/README.md
@@ -0,0 +1,44 @@
+# HackKit demo
+
+A public demonstration of HackKit Core, the Next integration, package UI, and Teams. Vinext runs the application on Cloudflare Workers. Turso stores application data over HTTP. A private R2 binding stores uploads. The app owns its pages and configuration and does not import either template or E2E support.
+
+## Credentials and local setup
+
+Copy `.dev.vars.example` to **`apps/demo/.dev.vars`**. Fill in `TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`, and a random `BETTER_AUTH_SECRET` of at least 32 characters. Keep `BETTER_AUTH_URL=http://localhost:3001` for local development. This ignored file is the only local credential file used by the demo. Never point it at a real event database.
+
+From the repository root:
+
+```sh
+corepack pnpm install
+corepack pnpm exec turbo run build --filter=@hackkit/demo^...
+corepack pnpm --filter @hackkit/demo plugin:sync
+corepack pnpm --filter @hackkit/demo db:migrate
+corepack pnpm --filter @hackkit/demo db:demo
+corepack pnpm dev:demo
+```
+
+Open [localhost:3001](http://localhost:3001). Local development and preview run in Workerd. They use the configured Turso database and an emulated local R2 bucket. Local uploads persist under `.wrangler`. Database setup is an explicit Node command; requests never migrate or seed the database.
+
+`db:demo` seeds fictional accounts, a team, and four schedule entries only when there are no existing users. Existing users are retained. Owner assignment is an explicit demo bootstrap operation. Neither template assigns owners automatically. `db:reset` is disabled for the shared demo database. Other database commands follow the template interface.
+
+`corepack pnpm build:demo` compiles MikroORM entity functions ahead of time and builds the Worker. It needs no database connection or credentials. `corepack pnpm --filter @hackkit/demo start` previews that production build on port 3001.
+
+## Cloudflare deployment
+
+The committed configuration targets **ACM UTSA**, account `cdc7630e53b468f56a4453af71a58ade`, Worker `hackkit-demo`, and private R2 bucket `hackkit-demo-uploads`. Verify Wrangler's account with `corepack pnpm --filter @hackkit/demo exec wrangler whoami`.
+
+Set `vars.BETTER_AUTH_URL` in `wrangler.jsonc` to the exact public origin. Default: [hackkit-demo.acm-utsa.workers.dev](https://hackkit-demo.acm-utsa.workers.dev). Set these Worker secrets through Wrangler's interactive `secret put` command or the Cloudflare dashboard:
+
+- `TURSO_DATABASE_URL`
+- `TURSO_AUTH_TOKEN`
+- `BETTER_AUTH_SECRET`
+
+For example, `corepack pnpm --filter @hackkit/demo exec wrangler secret put TURSO_AUTH_TOKEN` prompts for the token without putting it in command history. Do not upload the local `BETTER_AUTH_URL` as a secret; the deployed origin belongs in Wrangler configuration. R2 uses the `DEMO_UPLOADS` binding and requires no access keys or public bucket URL.
+
+Run `corepack pnpm deploy:demo` after building workspace libraries. Run `corepack pnpm --filter @hackkit/demo deploy:check` after a build to inspect the deployment without publishing.
+
+The hosted demo shares persistent Turso data and R2 uploads between visitors. Participant and organizer accounts are public. **Try registration** creates a new fictional account. Use fictional data only. Email delivery, OAuth, and Discord synchronization are disabled. This public demonstration is unsuitable for real participant records.
+
+## Verification
+
+Run `DEMO_TEST_URL=http://localhost:3001 corepack pnpm --filter @hackkit/demo test:smoke` against a running production preview. The checks cover role navigation, onboarding, permissions, and authenticated R2 uploads. CI uses a disposable local libSQL service and emulated R2; it never receives deployed database credentials.
diff --git a/apps/web/app/admin/check-in/page.tsx b/apps/demo/app/admin/check-in/page.tsx
similarity index 100%
rename from apps/web/app/admin/check-in/page.tsx
rename to apps/demo/app/admin/check-in/page.tsx
diff --git a/apps/web/app/admin/events/[id]/edit/page.tsx b/apps/demo/app/admin/events/[id]/edit/page.tsx
similarity index 100%
rename from apps/web/app/admin/events/[id]/edit/page.tsx
rename to apps/demo/app/admin/events/[id]/edit/page.tsx
diff --git a/apps/web/app/admin/events/new/page.tsx b/apps/demo/app/admin/events/new/page.tsx
similarity index 100%
rename from apps/web/app/admin/events/new/page.tsx
rename to apps/demo/app/admin/events/new/page.tsx
diff --git a/apps/web/app/admin/events/page.tsx b/apps/demo/app/admin/events/page.tsx
similarity index 100%
rename from apps/web/app/admin/events/page.tsx
rename to apps/demo/app/admin/events/page.tsx
diff --git a/apps/web/app/admin/layout.tsx b/apps/demo/app/admin/layout.tsx
similarity index 100%
rename from apps/web/app/admin/layout.tsx
rename to apps/demo/app/admin/layout.tsx
diff --git a/apps/web/app/admin/page.tsx b/apps/demo/app/admin/page.tsx
similarity index 100%
rename from apps/web/app/admin/page.tsx
rename to apps/demo/app/admin/page.tsx
diff --git a/apps/web/app/admin/roles/page.tsx b/apps/demo/app/admin/roles/page.tsx
similarity index 100%
rename from apps/web/app/admin/roles/page.tsx
rename to apps/demo/app/admin/roles/page.tsx
diff --git a/apps/web/app/admin/scanner/[eventId]/page.tsx b/apps/demo/app/admin/scanner/[eventId]/page.tsx
similarity index 100%
rename from apps/web/app/admin/scanner/[eventId]/page.tsx
rename to apps/demo/app/admin/scanner/[eventId]/page.tsx
diff --git a/apps/web/app/admin/settings/page.tsx b/apps/demo/app/admin/settings/page.tsx
similarity index 100%
rename from apps/web/app/admin/settings/page.tsx
rename to apps/demo/app/admin/settings/page.tsx
diff --git a/apps/web/app/admin/users/[authId]/page.tsx b/apps/demo/app/admin/users/[authId]/page.tsx
similarity index 100%
rename from apps/web/app/admin/users/[authId]/page.tsx
rename to apps/demo/app/admin/users/[authId]/page.tsx
diff --git a/apps/web/app/admin/users/page.tsx b/apps/demo/app/admin/users/page.tsx
similarity index 100%
rename from apps/web/app/admin/users/page.tsx
rename to apps/demo/app/admin/users/page.tsx
diff --git a/apps/web/app/api/admin/export/route.ts b/apps/demo/app/api/admin/export/route.ts
similarity index 100%
rename from apps/web/app/api/admin/export/route.ts
rename to apps/demo/app/api/admin/export/route.ts
diff --git a/apps/web/app/api/auth/[...all]/route.ts b/apps/demo/app/api/auth/[...all]/route.ts
similarity index 100%
rename from apps/web/app/api/auth/[...all]/route.ts
rename to apps/demo/app/api/auth/[...all]/route.ts
diff --git a/apps/demo/app/api/files/register/route.ts b/apps/demo/app/api/files/register/route.ts
new file mode 100644
index 000000000..97cf1586d
--- /dev/null
+++ b/apps/demo/app/api/files/register/route.ts
@@ -0,0 +1,23 @@
+import { NextResponse } from "next/server";
+import { z } from "zod";
+import { getAuthSession } from "@/lib/auth";
+import { createUploadTarget } from "@/lib/blob";
+
+const upload = z.object({
+ location: z.enum(["resumes", "profile-photos"]),
+ fileName: z.string().min(1).max(255),
+});
+export async function POST(request: Request) {
+ const session = await getAuthSession();
+ if (!session)
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ const input = upload.safeParse(await request.json().catch(() => null));
+ if (!input.success)
+ return NextResponse.json(
+ { error: "Choose a resume or profile photo and a file name." },
+ { status: 400 },
+ );
+ return NextResponse.json(
+ createUploadTarget({ ...input.data, ownerId: session.user.id }),
+ );
+}
diff --git a/apps/demo/app/api/files/upload/route.ts b/apps/demo/app/api/files/upload/route.ts
new file mode 100644
index 000000000..6744e2b94
--- /dev/null
+++ b/apps/demo/app/api/files/upload/route.ts
@@ -0,0 +1,36 @@
+import { NextResponse } from "next/server";
+import { getAuthSession } from "@/lib/auth";
+import { canUploadKey, getBlobStorage, readUploadBody } from "@/lib/blob";
+
+export async function PUT(request: Request) {
+ const session = await getAuthSession();
+ if (!session)
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ const key = new URL(request.url).searchParams.get("key");
+ if (!key || !canUploadKey(key, session.user.id))
+ return NextResponse.json(
+ { error: "Unsupported upload key." },
+ { status: 403 },
+ );
+ try {
+ const body = await readUploadBody(request);
+ const contentType =
+ request.headers.get("content-type") ?? "application/octet-stream";
+ if (
+ key.startsWith("profile-photos/") &&
+ !["image/png", "image/jpeg", "image/webp"].includes(contentType)
+ )
+ return NextResponse.json(
+ { error: "Choose a PNG, JPEG, or WebP image." },
+ { status: 400 },
+ );
+ await getBlobStorage().put(key, body, {
+ httpMetadata: { contentType },
+ });
+ return new NextResponse(null, { status: 204 });
+ } catch (error) {
+ if (error instanceof RangeError)
+ return NextResponse.json({ error: error.message }, { status: 413 });
+ throw error;
+ }
+}
diff --git a/apps/demo/app/api/files/view/route.ts b/apps/demo/app/api/files/view/route.ts
new file mode 100644
index 000000000..0e40822cd
--- /dev/null
+++ b/apps/demo/app/api/files/view/route.ts
@@ -0,0 +1,54 @@
+import { NextResponse } from "next/server";
+import { CorePermission } from "@hackkit/core";
+import { getAuthSession } from "@/lib/auth";
+import { getBlobStorage } from "@/lib/blob";
+import { getRuntime } from "@/lib/runtime";
+
+function storedFileReferenceForKey(key: string): string {
+ return `/api/files/view?key=${encodeURIComponent(key)}`;
+}
+
+async function canViewFile(key: string): Promise {
+ if (key.startsWith("profile-photos/")) return true;
+
+ const session = await getAuthSession();
+ if (!session) return false;
+
+ const runtime = await getRuntime();
+ const currentUser = await runtime.getCurrentUser();
+ const hacker = await runtime.hackkit.hackers.getHacker(currentUser.id);
+ if (hacker?.resumeUrl === storedFileReferenceForKey(key)) return true;
+
+ return runtime.hackkit.accessControl.hasPermission(
+ currentUser.id,
+ CorePermission.HackersView,
+ );
+}
+
+export async function GET(request: Request): Promise {
+ const url = new URL(request.url);
+ const key = url.searchParams.get("key");
+ if (!key) {
+ return NextResponse.json({ error: "key is required" }, { status: 400 });
+ }
+ if (!key.startsWith("resumes/") && !key.startsWith("profile-photos/")) {
+ return NextResponse.json({ error: "Not found" }, { status: 404 });
+ }
+ if (!(await canViewFile(key))) {
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ }
+
+ const storage = getBlobStorage();
+
+ const result = await storage.get(key);
+ if (!result)
+ return NextResponse.json({ error: "Not found" }, { status: 404 });
+ const headers = new Headers();
+ result.writeHttpMetadata(headers);
+ headers.set("Cache-Control", "private, no-store");
+ headers.set("X-Content-Type-Options", "nosniff");
+ headers.set("Content-Security-Policy", "sandbox");
+ if (!key.startsWith("profile-photos/"))
+ headers.set("Content-Disposition", "attachment");
+ return new NextResponse(result.body, { headers });
+}
diff --git a/apps/web/app/api/hackkit/[...path]/route.ts b/apps/demo/app/api/hackkit/[...path]/route.ts
similarity index 100%
rename from apps/web/app/api/hackkit/[...path]/route.ts
rename to apps/demo/app/api/hackkit/[...path]/route.ts
diff --git a/apps/web/app/app-bar.tsx b/apps/demo/app/app-bar.tsx
similarity index 96%
rename from apps/web/app/app-bar.tsx
rename to apps/demo/app/app-bar.tsx
index 55c9035d9..f5afbe76c 100644
--- a/apps/web/app/app-bar.tsx
+++ b/apps/demo/app/app-bar.tsx
@@ -42,10 +42,7 @@ export async function AppBar() {
diff --git a/apps/web/app/contact/page.tsx b/apps/demo/app/contact/page.tsx
similarity index 100%
rename from apps/web/app/contact/page.tsx
rename to apps/demo/app/contact/page.tsx
diff --git a/apps/web/app/dashboard/layout.tsx b/apps/demo/app/dashboard/layout.tsx
similarity index 100%
rename from apps/web/app/dashboard/layout.tsx
rename to apps/demo/app/dashboard/layout.tsx
diff --git a/apps/web/app/dashboard/page.tsx b/apps/demo/app/dashboard/page.tsx
similarity index 100%
rename from apps/web/app/dashboard/page.tsx
rename to apps/demo/app/dashboard/page.tsx
diff --git a/apps/demo/app/demo-actions.tsx b/apps/demo/app/demo-actions.tsx
new file mode 100644
index 000000000..d47f3abe8
--- /dev/null
+++ b/apps/demo/app/demo-actions.tsx
@@ -0,0 +1,84 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { authClient } from "@/lib/auth-client";
+import { demoAccounts, demoPassword } from "@/lib/demo-accounts";
+
+export function DemoActions() {
+ const [ready, setReady] = useState(false);
+ const [pending, setPending] = useState();
+ useEffect(() => setReady(true), []);
+ const [error, setError] = useState();
+ async function enter(role: "participant" | "organizer" | "newcomer") {
+ setPending(role);
+ setError(undefined);
+ try {
+ await authClient.signOut();
+ const result =
+ role === "newcomer"
+ ? await authClient.signUp.email({
+ name: "Demo participant",
+ email: `demo-${crypto.randomUUID()}@example.com`,
+ password: demoPassword,
+ })
+ : await authClient.signIn.email({
+ email: demoAccounts[role].email,
+ password: demoPassword,
+ });
+ if (result.error)
+ throw new Error(result.error.message ?? "Unable to open demo.");
+ window.location.assign(
+ role === "organizer" ? "/admin" : "/dashboard",
+ );
+ } catch (cause) {
+ setError(
+ cause instanceof Error ? cause.message : "Unable to open demo.",
+ );
+ setPending(undefined);
+ }
+ }
+ return (
+ <>
+
+ {(
+ [
+ [
+ "participant",
+ "Explore as a participant",
+ "Open a registered hacker’s dashboard, create a team, and manage your event pass.",
+ ],
+ [
+ "organizer",
+ "Explore as an organizer",
+ "Review applications, manage roles and settings, and edit the event schedule.",
+ ],
+ [
+ "newcomer",
+ "Try registration",
+ "Create a fresh fictional account and walk through the onboarding forms.",
+ ],
+ ] as const
+ ).map(([role, title, description]) => (
+ enter(role)}
+ disabled={!ready || !!pending}
+ className="rounded-xl border bg-card p-6 text-left shadow-sm transition hover:border-primary hover:bg-accent disabled:opacity-60"
+ >
+
+ {pending === role ? "Opening your demo…" : title}
+
+
+ {description}
+
+
+ ))}
+
+ {error && (
+
+ {error}
+
+ )}
+ >
+ );
+}
diff --git a/apps/web/app/globals.css b/apps/demo/app/globals.css
similarity index 100%
rename from apps/web/app/globals.css
rename to apps/demo/app/globals.css
diff --git a/apps/web/app/help/page.tsx b/apps/demo/app/help/page.tsx
similarity index 100%
rename from apps/web/app/help/page.tsx
rename to apps/demo/app/help/page.tsx
diff --git a/apps/web/app/i/approval/layout.tsx b/apps/demo/app/i/approval/layout.tsx
similarity index 100%
rename from apps/web/app/i/approval/layout.tsx
rename to apps/demo/app/i/approval/layout.tsx
diff --git a/apps/web/app/i/approval/page.tsx b/apps/demo/app/i/approval/page.tsx
similarity index 100%
rename from apps/web/app/i/approval/page.tsx
rename to apps/demo/app/i/approval/page.tsx
diff --git a/apps/web/app/invites/layout.tsx b/apps/demo/app/invites/layout.tsx
similarity index 100%
rename from apps/web/app/invites/layout.tsx
rename to apps/demo/app/invites/layout.tsx
diff --git a/apps/web/app/invites/page.tsx b/apps/demo/app/invites/page.tsx
similarity index 100%
rename from apps/web/app/invites/page.tsx
rename to apps/demo/app/invites/page.tsx
diff --git a/apps/demo/app/layout.tsx b/apps/demo/app/layout.tsx
new file mode 100644
index 000000000..23ab39b78
--- /dev/null
+++ b/apps/demo/app/layout.tsx
@@ -0,0 +1,45 @@
+import type * as React from "react";
+import type { Metadata } from "next";
+import { PublicSiteFooter } from "@hackkit/ui";
+import {
+ getPublicThemeStyle,
+ publicSiteConfig,
+} from "@/lib/public-site-config";
+import "./globals.css";
+import { AppBar } from "./app-bar";
+import { Providers } from "./providers";
+
+export const metadata: Metadata = {
+ title: publicSiteConfig.brand.name,
+ description: publicSiteConfig.brand.description,
+ robots: { index: false, follow: false },
+};
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+
+
+
+ {children}
+
+
+
+
+ );
+}
diff --git a/apps/web/app/onboarding/hacker/hacker-form-defaults.ts b/apps/demo/app/onboarding/hacker/hacker-form-defaults.ts
similarity index 100%
rename from apps/web/app/onboarding/hacker/hacker-form-defaults.ts
rename to apps/demo/app/onboarding/hacker/hacker-form-defaults.ts
diff --git a/apps/web/app/onboarding/hacker/hacker-registration-client.tsx b/apps/demo/app/onboarding/hacker/hacker-registration-client.tsx
similarity index 100%
rename from apps/web/app/onboarding/hacker/hacker-registration-client.tsx
rename to apps/demo/app/onboarding/hacker/hacker-registration-client.tsx
diff --git a/apps/web/app/onboarding/hacker/page.tsx b/apps/demo/app/onboarding/hacker/page.tsx
similarity index 100%
rename from apps/web/app/onboarding/hacker/page.tsx
rename to apps/demo/app/onboarding/hacker/page.tsx
diff --git a/apps/web/app/onboarding/hacktag/page.tsx b/apps/demo/app/onboarding/hacktag/page.tsx
similarity index 100%
rename from apps/web/app/onboarding/hacktag/page.tsx
rename to apps/demo/app/onboarding/hacktag/page.tsx
diff --git a/apps/web/app/onboarding/layout.tsx b/apps/demo/app/onboarding/layout.tsx
similarity index 100%
rename from apps/web/app/onboarding/layout.tsx
rename to apps/demo/app/onboarding/layout.tsx
diff --git a/apps/web/app/onboarding/onboarding-shell.tsx b/apps/demo/app/onboarding/onboarding-shell.tsx
similarity index 100%
rename from apps/web/app/onboarding/onboarding-shell.tsx
rename to apps/demo/app/onboarding/onboarding-shell.tsx
diff --git a/apps/web/app/onboarding/user-data/page.tsx b/apps/demo/app/onboarding/user-data/page.tsx
similarity index 100%
rename from apps/web/app/onboarding/user-data/page.tsx
rename to apps/demo/app/onboarding/user-data/page.tsx
diff --git a/apps/demo/app/page.tsx b/apps/demo/app/page.tsx
new file mode 100644
index 000000000..e2b0f7f01
--- /dev/null
+++ b/apps/demo/app/page.tsx
@@ -0,0 +1,55 @@
+import Link from "next/link";
+import { DemoActions } from "./demo-actions";
+
+export const dynamic = "force-dynamic";
+
+export default function HomePage() {
+ return (
+
+
+ HackKit interactive demo
+
+
+ A hackathon, from application to check-in.
+
+
+ See what participants and organizers can do with HackKit.
+ Explore a working event with fictional people, teams, and a
+ schedule.
+
+
+
+
+ A shared demo with persistent sample data.
+
+
+ Changes are visible to other visitors. Use fictional
+ information only. Email delivery and Discord synchronization
+ are disabled.
+
+
+
+
+ );
+}
diff --git a/apps/web/app/participant-layout.tsx b/apps/demo/app/participant-layout.tsx
similarity index 100%
rename from apps/web/app/participant-layout.tsx
rename to apps/demo/app/participant-layout.tsx
diff --git a/apps/web/app/pass/event-pass-shell.tsx b/apps/demo/app/pass/event-pass-shell.tsx
similarity index 100%
rename from apps/web/app/pass/event-pass-shell.tsx
rename to apps/demo/app/pass/event-pass-shell.tsx
diff --git a/apps/web/app/pass/layout.tsx b/apps/demo/app/pass/layout.tsx
similarity index 100%
rename from apps/web/app/pass/layout.tsx
rename to apps/demo/app/pass/layout.tsx
diff --git a/apps/web/app/pass/page.tsx b/apps/demo/app/pass/page.tsx
similarity index 100%
rename from apps/web/app/pass/page.tsx
rename to apps/demo/app/pass/page.tsx
diff --git a/apps/web/app/profile-menu.tsx b/apps/demo/app/profile-menu.tsx
similarity index 98%
rename from apps/web/app/profile-menu.tsx
rename to apps/demo/app/profile-menu.tsx
index 6b0a15a5c..25c01ee34 100644
--- a/apps/web/app/profile-menu.tsx
+++ b/apps/demo/app/profile-menu.tsx
@@ -40,6 +40,7 @@ export function ProfileMenu({
type="button"
onClick={() => setIsOpen((value) => !value)}
className="flex items-center gap-2 rounded-full border bg-background px-2 py-1.5 text-sm font-medium shadow-sm transition hover:bg-muted"
+ aria-label="Open account menu"
aria-haspopup="menu"
aria-expanded={isOpen}
>
diff --git a/apps/web/app/providers.tsx b/apps/demo/app/providers.tsx
similarity index 100%
rename from apps/web/app/providers.tsx
rename to apps/demo/app/providers.tsx
diff --git a/apps/web/app/register/page.tsx b/apps/demo/app/register/page.tsx
similarity index 100%
rename from apps/web/app/register/page.tsx
rename to apps/demo/app/register/page.tsx
diff --git a/apps/web/app/registration-closed/page.tsx b/apps/demo/app/registration-closed/page.tsx
similarity index 100%
rename from apps/web/app/registration-closed/page.tsx
rename to apps/demo/app/registration-closed/page.tsx
diff --git a/apps/web/app/rsvp/layout.tsx b/apps/demo/app/rsvp/layout.tsx
similarity index 100%
rename from apps/web/app/rsvp/layout.tsx
rename to apps/demo/app/rsvp/layout.tsx
diff --git a/apps/web/app/rsvp/page.tsx b/apps/demo/app/rsvp/page.tsx
similarity index 100%
rename from apps/web/app/rsvp/page.tsx
rename to apps/demo/app/rsvp/page.tsx
diff --git a/apps/web/app/schedule/[eventId]/page.tsx b/apps/demo/app/schedule/[eventId]/page.tsx
similarity index 100%
rename from apps/web/app/schedule/[eventId]/page.tsx
rename to apps/demo/app/schedule/[eventId]/page.tsx
diff --git a/apps/web/app/schedule/page.tsx b/apps/demo/app/schedule/page.tsx
similarity index 100%
rename from apps/web/app/schedule/page.tsx
rename to apps/demo/app/schedule/page.tsx
diff --git a/apps/web/app/settings/layout.tsx b/apps/demo/app/settings/layout.tsx
similarity index 100%
rename from apps/web/app/settings/layout.tsx
rename to apps/demo/app/settings/layout.tsx
diff --git a/apps/web/app/settings/page.tsx b/apps/demo/app/settings/page.tsx
similarity index 100%
rename from apps/web/app/settings/page.tsx
rename to apps/demo/app/settings/page.tsx
diff --git a/apps/web/app/settings/profile-settings-client.tsx b/apps/demo/app/settings/profile-settings-client.tsx
similarity index 100%
rename from apps/web/app/settings/profile-settings-client.tsx
rename to apps/demo/app/settings/profile-settings-client.tsx
diff --git a/apps/web/app/settings/registration/page.tsx b/apps/demo/app/settings/registration/page.tsx
similarity index 100%
rename from apps/web/app/settings/registration/page.tsx
rename to apps/demo/app/settings/registration/page.tsx
diff --git a/apps/web/app/sign-in/auth-form.tsx b/apps/demo/app/sign-in/auth-form.tsx
similarity index 100%
rename from apps/web/app/sign-in/auth-form.tsx
rename to apps/demo/app/sign-in/auth-form.tsx
diff --git a/apps/web/app/sign-in/page.tsx b/apps/demo/app/sign-in/page.tsx
similarity index 86%
rename from apps/web/app/sign-in/page.tsx
rename to apps/demo/app/sign-in/page.tsx
index aa7678afc..03f759629 100644
--- a/apps/web/app/sign-in/page.tsx
+++ b/apps/demo/app/sign-in/page.tsx
@@ -12,9 +12,7 @@ export default async function SignInPage() {
-
- HackKit UI test app
-
+
HackKit
Sign in
diff --git a/apps/web/app/sign-up/page.tsx b/apps/demo/app/sign-up/page.tsx
similarity index 89%
rename from apps/web/app/sign-up/page.tsx
rename to apps/demo/app/sign-up/page.tsx
index eb5407deb..d43a22eeb 100644
--- a/apps/web/app/sign-up/page.tsx
+++ b/apps/demo/app/sign-up/page.tsx
@@ -12,9 +12,7 @@ export default async function SignUpPage() {
-
- HackKit UI test app
-
+
HackKit
Sign up
diff --git a/apps/web/app/suspended/page.tsx b/apps/demo/app/suspended/page.tsx
similarity index 100%
rename from apps/web/app/suspended/page.tsx
rename to apps/demo/app/suspended/page.tsx
diff --git a/apps/web/app/teams/layout.tsx b/apps/demo/app/teams/layout.tsx
similarity index 100%
rename from apps/web/app/teams/layout.tsx
rename to apps/demo/app/teams/layout.tsx
diff --git a/apps/web/app/teams/page.tsx b/apps/demo/app/teams/page.tsx
similarity index 100%
rename from apps/web/app/teams/page.tsx
rename to apps/demo/app/teams/page.tsx
diff --git a/apps/web/app/user/[tag]/page.tsx b/apps/demo/app/user/[tag]/page.tsx
similarity index 100%
rename from apps/web/app/user/[tag]/page.tsx
rename to apps/demo/app/user/[tag]/page.tsx
diff --git a/apps/web/db/migrations/sqlite/.snapshot.json b/apps/demo/db/migrations/sqlite/.snapshot.json
similarity index 83%
rename from apps/web/db/migrations/sqlite/.snapshot.json
rename to apps/demo/db/migrations/sqlite/.snapshot.json
index 94c45c417..362f4d909 100644
--- a/apps/web/db/migrations/sqlite/.snapshot.json
+++ b/apps/demo/db/migrations/sqlite/.snapshot.json
@@ -2405,8 +2405,8 @@
"enumItems": [],
"mappedType": "text"
},
- "profile_photo_url": {
- "name": "profile_photo_url",
+ "image": {
+ "name": "image",
"type": "text",
"unsigned": false,
"autoincrement": false,
@@ -3005,731 +3005,6 @@
},
"comment": null
},
- {
- "name": "discord_member",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "avatar_hash": {
- "name": "avatar_hash",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "last_role_sync_at": {
- "name": "last_role_sync_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "username": {
- "name": "username",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "verified_at": {
- "name": "verified_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "discord_member_discord_user_id_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "guild_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_guild_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "updated_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_updated_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "primary",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "discord_member_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_member_auth_id_foreign",
- "localTableName": "discord_member",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_role_sync_attempt",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "error": {
- "name": "error",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "id": {
- "name": "id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "role_ids": {
- "name": "role_ids",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "role_names": {
- "name": "role_names",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [
- "synced",
- "failed",
- "skipped"
- ],
- "mappedType": "enum"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_status_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "primary",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [
- {
- "name": "discord_role_sync_attempt_status_check",
- "expression": "`status` in ('synced', 'failed', 'skipped')",
- "definition": "check (`status` in ('synced', 'failed', 'skipped'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "discord_role_sync_attempt_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_role_sync_attempt_auth_id_foreign",
- "localTableName": "discord_role_sync_attempt",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_verification",
- "columns": {
- "accepted_at": {
- "name": "accepted_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "auth_id": {
- "name": "auth_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "avatar_hash": {
- "name": "avatar_hash",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "code": {
- "name": "code",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "expires_at": {
- "name": "expires_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'pending'",
- "comment": null,
- "collation": null,
- "enumItems": [
- "pending",
- "accepted",
- "rejected",
- "expired"
- ],
- "mappedType": "enum"
- },
- "username": {
- "name": "username",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "guild_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_guild_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_status_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "code"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "primary",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [
- {
- "name": "discord_verification_status_check",
- "expression": "`status` in ('pending', 'accepted', 'rejected', 'expired')",
- "definition": "check (`status` in ('pending', 'accepted', 'rejected', 'expired'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "discord_verification_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_verification_auth_id_foreign",
- "localTableName": "discord_verification",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
{
"name": "session",
"columns": {
diff --git a/apps/demo/db/migrations/sqlite/Migration20261020221614_demo_initial.ts b/apps/demo/db/migrations/sqlite/Migration20261020221614_demo_initial.ts
new file mode 100644
index 000000000..ff282dac9
--- /dev/null
+++ b/apps/demo/db/migrations/sqlite/Migration20261020221614_demo_initial.ts
@@ -0,0 +1,258 @@
+import { Migration } from "@mikro-orm/migrations";
+
+export class Migration20261020221614_demo_initial extends Migration {
+ override name = "Migration20261020221614_demo_initial";
+
+ override up(): void | Promise
{
+ this.addSql(
+ `create table \`verification\` (\`id\` text not null primary key, \`identifier\` text not null, \`value\` text not null, \`expires_at\` datetime not null, \`created_at\` datetime null, \`updated_at\` datetime null);`,
+ );
+ this.addSql(
+ `create index \`verification_identifier_index\` on \`verification\` (\`identifier\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_event\` (\`id\` text not null primary key, \`title\` text not null, \`start_time\` datetime not null, \`end_time\` datetime not null, \`location\` text not null default 'TBD', \`description\` text not null, \`type\` text not null, \`host\` text null, \`hidden\` integer not null default false, \`created_at\` datetime not null, \`updated_at\` datetime not null);`,
+ );
+ this.addSql(
+ `create index \`core_event_start_time_index\` on \`core_event\` (\`start_time\`);`,
+ );
+ this.addSql(
+ `create index \`core_event_type_index\` on \`core_event\` (\`type\`);`,
+ );
+ this.addSql(
+ `create index \`core_event_hidden_index\` on \`core_event\` (\`hidden\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_operation_lock\` (\`key\` text not null primary key, \`token\` text not null);`,
+ );
+
+ this.addSql(
+ `create table \`core_role\` (\`id\` text not null primary key, \`name\` text not null, \`position\` integer not null, \`permissions\` json not null default '[]', \`color\` text null, \`created_at\` datetime not null, \`updated_at\` datetime not null);`,
+ );
+ this.addSql(
+ `create unique index \`core_role_name_unique\` on \`core_role\` (\`name\`);`,
+ );
+ this.addSql(
+ `create index \`core_role_position_index\` on \`core_role\` (\`position\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_user\` (\`id\` text not null primary key, \`name\` text not null, \`email\` text not null, \`email_verified\` integer not null default false, \`profile_photo_url\` text null, \`hack_tag\` text null, \`bio\` text null, \`pronouns\` text null, \`skills\` json not null default '[]', \`is_profile_searchable\` integer not null default true, \`discord_display_handle\` text null, \`role_id\` text null, \`is_approved\` integer not null default false, \`checked_in_at\` datetime null, \`created_at\` datetime not null, \`updated_at\` datetime not null, constraint \`core_user_role_id_foreign\` foreign key (\`role_id\`) references \`core_role\` (\`id\`) on delete set null);`,
+ );
+ this.addSql(
+ `create unique index \`core_user_email_unique\` on \`core_user\` (\`email\`);`,
+ );
+ this.addSql(
+ `create unique index \`core_user_hack_tag_unique\` on \`core_user\` (\`hack_tag\`);`,
+ );
+ this.addSql(
+ `create index \`core_user_hack_tag_index\` on \`core_user\` (\`hack_tag\`);`,
+ );
+ this.addSql(
+ `create index \`core_user_role_id_index\` on \`core_user\` (\`role_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_user_created_at_index\` on \`core_user\` (\`created_at\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_user_data\` (\`auth_id\` text not null primary key, \`age\` integer not null, \`gender\` text not null, \`race\` text not null, \`ethnicity\` text not null, \`shirt_size\` text not null, \`dietary_restrictions\` json not null default '[]', \`accommodation_note\` text null, \`phone_number\` text null, \`country_of_residence\` text null, \`has_accepted_mlhcode_of_conduct\` integer not null, \`has_shared_data_with_mlh\` integer not null, \`is_emailable\` integer not null, \`completed_at\` datetime not null, \`updated_at\` datetime not null, constraint \`core_user_data_auth_id_foreign\` foreign key (\`auth_id\`) references \`core_user\` (\`id\`) on update cascade on delete cascade);`,
+ );
+ this.addSql(
+ `create index \`core_user_data_auth_id_index\` on \`core_user_data\` (\`auth_id\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_user_ban\` (\`auth_id\` text not null primary key, \`reason\` text null, \`banned_by_auth_id\` text not null, \`created_at\` datetime not null, constraint \`core_user_ban_auth_id_foreign\` foreign key (\`auth_id\`) references \`core_user\` (\`id\`) on update cascade on delete cascade, constraint \`core_user_ban_banned_by_auth_id_foreign\` foreign key (\`banned_by_auth_id\`) references \`core_user\` (\`id\`));`,
+ );
+ this.addSql(
+ `create index \`core_user_ban_auth_id_index\` on \`core_user_ban\` (\`auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_user_ban_banned_by_auth_id_index\` on \`core_user_ban\` (\`banned_by_auth_id\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_setting\` (\`key\` text not null primary key, \`value\` json not null, \`created_at\` datetime not null, \`created_by_auth_id\` text null, \`updated_at\` datetime not null, \`updated_by_auth_id\` text null, constraint \`core_setting_created_by_auth_id_foreign\` foreign key (\`created_by_auth_id\`) references \`core_user\` (\`id\`) on delete set null, constraint \`core_setting_updated_by_auth_id_foreign\` foreign key (\`updated_by_auth_id\`) references \`core_user\` (\`id\`) on delete set null);`,
+ );
+ this.addSql(
+ `create index \`core_setting_created_by_auth_id_index\` on \`core_setting\` (\`created_by_auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_setting_updated_at_index\` on \`core_setting\` (\`updated_at\`);`,
+ );
+ this.addSql(
+ `create index \`core_setting_updated_by_auth_id_index\` on \`core_setting\` (\`updated_by_auth_id\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_rsvp\` (\`auth_id\` text not null primary key, \`status\` text check (\`status\` in ('confirmed', 'waitlisted', 'cancelled')) not null, \`waitlist_position\` integer null, \`created_at\` datetime not null, \`updated_at\` datetime not null, \`confirmed_at\` datetime null, \`waitlisted_at\` datetime null, \`cancelled_at\` datetime null, \`cancelled_by_auth_id\` text null, \`promoted_at\` datetime null, \`promoted_by_auth_id\` text null, constraint \`core_rsvp_auth_id_foreign\` foreign key (\`auth_id\`) references \`core_user\` (\`id\`) on update cascade on delete cascade, constraint \`core_rsvp_cancelled_by_auth_id_foreign\` foreign key (\`cancelled_by_auth_id\`) references \`core_user\` (\`id\`) on delete set null, constraint \`core_rsvp_promoted_by_auth_id_foreign\` foreign key (\`promoted_by_auth_id\`) references \`core_user\` (\`id\`) on delete set null);`,
+ );
+ this.addSql(
+ `create index \`core_rsvp_auth_id_index\` on \`core_rsvp\` (\`auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_rsvp_cancelled_by_auth_id_index\` on \`core_rsvp\` (\`cancelled_by_auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_rsvp_promoted_by_auth_id_index\` on \`core_rsvp\` (\`promoted_by_auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_rsvp_status_index\` on \`core_rsvp\` (\`status\`);`,
+ );
+ this.addSql(
+ `create index \`core_rsvp_waitlist_position_index\` on \`core_rsvp\` (\`waitlist_position\`);`,
+ );
+ this.addSql(
+ `create index \`core_rsvp_created_at_index\` on \`core_rsvp\` (\`created_at\`);`,
+ );
+ this.addSql(
+ `create index \`core_rsvp_updated_at_index\` on \`core_rsvp\` (\`updated_at\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_notification_intent\` (\`id\` text not null primary key, \`kind\` text not null, \`recipient_auth_id\` text null, \`payload\` json not null, \`status\` text check (\`status\` in ('pending', 'processing', 'delivered', 'failed', 'skipped')) not null default 'pending', \`idempotency_key\` text null, \`created_at\` datetime not null, \`updated_at\` datetime not null, constraint \`core_notification_intent_recipient_auth_id_foreign\` foreign key (\`recipient_auth_id\`) references \`core_user\` (\`id\`) on delete set null);`,
+ );
+ this.addSql(
+ `create unique index \`core_notification_intent_idempotency_key_unique\` on \`core_notification_intent\` (\`idempotency_key\`);`,
+ );
+ this.addSql(
+ `create index \`core_notification_intent_kind_index\` on \`core_notification_intent\` (\`kind\`);`,
+ );
+ this.addSql(
+ `create index \`core_notification_intent_recipient_auth_id_index\` on \`core_notification_intent\` (\`recipient_auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_notification_intent_status_index\` on \`core_notification_intent\` (\`status\`);`,
+ );
+ this.addSql(
+ `create index \`core_notification_intent_created_at_index\` on \`core_notification_intent\` (\`created_at\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_notification_delivery_attempt\` (\`id\` text not null primary key, \`intent_id\` text not null, \`channel\` text not null, \`provider\` text null, \`status\` text check (\`status\` in ('delivered', 'failed', 'skipped')) not null, \`recipient\` text null, \`external_id\` text null, \`error\` text null, \`metadata\` json not null, \`attempted_at\` datetime not null, constraint \`core_notification_delivery_attempt_intent_id_foreign\` foreign key (\`intent_id\`) references \`core_notification_intent\` (\`id\`) on delete cascade);`,
+ );
+ this.addSql(
+ `create index \`core_notification_delivery_attempt_intent_id_index\` on \`core_notification_delivery_attempt\` (\`intent_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_notification_delivery_attempt_channel_index\` on \`core_notification_delivery_attempt\` (\`channel\`);`,
+ );
+ this.addSql(
+ `create index \`core_notification_delivery_attempt_status_index\` on \`core_notification_delivery_attempt\` (\`status\`);`,
+ );
+ this.addSql(
+ `create index \`core_notification_delivery_attempt_attempted_at_index\` on \`core_notification_delivery_attempt\` (\`attempted_at\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_hacker\` (\`auth_id\` text not null primary key, \`university\` text not null, \`major\` text not null, \`school_id\` text null, \`level_of_study\` text not null, \`hackathons_attended\` integer not null, \`software_experience\` text not null, \`heard_from\` text null, \`github_url\` text null, \`linked_in_url\` text null, \`personal_website_url\` text null, \`resume_url\` text null, \`group\` text null, \`registered_at\` datetime not null, \`updated_at\` datetime not null, constraint \`core_hacker_auth_id_foreign\` foreign key (\`auth_id\`) references \`core_user\` (\`id\`) on update cascade on delete cascade);`,
+ );
+ this.addSql(
+ `create index \`core_hacker_auth_id_index\` on \`core_hacker\` (\`auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_hacker_registered_at_index\` on \`core_hacker\` (\`registered_at\`);`,
+ );
+
+ this.addSql(
+ `create table \`core_event_scan\` (\`id\` text not null primary key, \`event_id\` text not null, \`auth_id\` text not null, \`scanned_by_auth_id\` text not null, \`scanned_at\` datetime not null, constraint \`core_event_scan_event_id_foreign\` foreign key (\`event_id\`) references \`core_event\` (\`id\`) on delete cascade, constraint \`core_event_scan_auth_id_foreign\` foreign key (\`auth_id\`) references \`core_user\` (\`id\`) on delete cascade, constraint \`core_event_scan_scanned_by_auth_id_foreign\` foreign key (\`scanned_by_auth_id\`) references \`core_user\` (\`id\`));`,
+ );
+ this.addSql(
+ `create index \`core_event_scan_scanned_by_auth_id_index\` on \`core_event_scan\` (\`scanned_by_auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_event_scan_event_id_index\` on \`core_event_scan\` (\`event_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_event_scan_auth_id_index\` on \`core_event_scan\` (\`auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_event_scan_event_id_auth_id_index\` on \`core_event_scan\` (\`event_id\`, \`auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`core_event_scan_scanned_at_index\` on \`core_event_scan\` (\`scanned_at\`);`,
+ );
+
+ this.addSql(
+ `create table \`session\` (\`id\` text not null primary key, \`expires_at\` datetime not null, \`token\` text not null, \`created_at\` datetime not null, \`updated_at\` datetime not null, \`ip_address\` text null, \`user_agent\` text null, \`user_id\` text not null, constraint \`session_user_id_foreign\` foreign key (\`user_id\`) references \`core_user\` (\`id\`) on delete cascade);`,
+ );
+ this.addSql(
+ `create unique index \`session_token_unique\` on \`session\` (\`token\`);`,
+ );
+ this.addSql(
+ `create index \`session_user_id_index\` on \`session\` (\`user_id\`);`,
+ );
+
+ this.addSql(
+ `create table \`account\` (\`id\` text not null primary key, \`account_id\` text not null, \`provider_id\` text not null, \`user_id\` text not null, \`access_token\` text null, \`refresh_token\` text null, \`id_token\` text null, \`access_token_expires_at\` datetime null, \`refresh_token_expires_at\` datetime null, \`scope\` text null, \`password\` text null, \`created_at\` datetime not null, \`updated_at\` datetime not null, constraint \`account_user_id_foreign\` foreign key (\`user_id\`) references \`core_user\` (\`id\`) on delete cascade);`,
+ );
+ this.addSql(
+ `create index \`account_user_id_index\` on \`account\` (\`user_id\`);`,
+ );
+
+ this.addSql(
+ `create table \`teams_team\` (\`id\` text not null primary key, \`name\` text not null, \`tag\` text not null, \`owner_auth_id\` text not null, \`created_at\` datetime not null, constraint \`teams_team_owner_auth_id_foreign\` foreign key (\`owner_auth_id\`) references \`core_user\` (\`id\`) on delete cascade);`,
+ );
+ this.addSql(
+ `create unique index \`teams_team_tag_unique\` on \`teams_team\` (\`tag\`);`,
+ );
+ this.addSql(
+ `create index \`teams_team_tag_index\` on \`teams_team\` (\`tag\`);`,
+ );
+ this.addSql(
+ `create index \`teams_team_owner_auth_id_index\` on \`teams_team\` (\`owner_auth_id\`);`,
+ );
+
+ this.addSql(
+ `create table \`teams_member\` (\`id\` text not null primary key, \`team_id\` text not null, \`auth_id\` text not null, \`joined_at\` datetime not null, constraint \`teams_member_team_id_foreign\` foreign key (\`team_id\`) references \`teams_team\` (\`id\`) on delete cascade, constraint \`teams_member_auth_id_foreign\` foreign key (\`auth_id\`) references \`core_user\` (\`id\`) on delete cascade);`,
+ );
+ this.addSql(
+ `create unique index \`teams_member_auth_id_unique\` on \`teams_member\` (\`auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`teams_member_team_id_index\` on \`teams_member\` (\`team_id\`);`,
+ );
+ this.addSql(
+ `create index \`teams_member_auth_id_index\` on \`teams_member\` (\`auth_id\`);`,
+ );
+
+ this.addSql(
+ `create table \`teams_invite\` (\`id\` text not null primary key, \`team_id\` text not null, \`invitee_auth_id\` text not null, \`status\` text check (\`status\` in ('pending', 'accepted', 'declined')) not null default 'pending', \`created_at\` datetime not null, constraint \`teams_invite_team_id_foreign\` foreign key (\`team_id\`) references \`teams_team\` (\`id\`) on delete cascade, constraint \`teams_invite_invitee_auth_id_foreign\` foreign key (\`invitee_auth_id\`) references \`core_user\` (\`id\`) on delete cascade);`,
+ );
+ this.addSql(
+ `create index \`teams_invite_team_id_index\` on \`teams_invite\` (\`team_id\`);`,
+ );
+ this.addSql(
+ `create index \`teams_invite_invitee_auth_id_index\` on \`teams_invite\` (\`invitee_auth_id\`);`,
+ );
+ this.addSql(
+ `create index \`teams_invite_team_id_invitee_auth_id_index\` on \`teams_invite\` (\`team_id\`, \`invitee_auth_id\`);`,
+ );
+ }
+
+ override down(): void | Promise {
+ this.addSql(`drop table if exists \`verification\`;`);
+ this.addSql(`drop table if exists \`core_event\`;`);
+ this.addSql(`drop table if exists \`core_operation_lock\`;`);
+ this.addSql(`drop table if exists \`core_role\`;`);
+ this.addSql(`drop table if exists \`core_user\`;`);
+ this.addSql(`drop table if exists \`core_user_data\`;`);
+ this.addSql(`drop table if exists \`core_user_ban\`;`);
+ this.addSql(`drop table if exists \`core_setting\`;`);
+ this.addSql(`drop table if exists \`core_rsvp\`;`);
+ this.addSql(`drop table if exists \`core_notification_intent\`;`);
+ this.addSql(
+ `drop table if exists \`core_notification_delivery_attempt\`;`,
+ );
+ this.addSql(`drop table if exists \`core_hacker\`;`);
+ this.addSql(`drop table if exists \`core_event_scan\`;`);
+ this.addSql(`drop table if exists \`session\`;`);
+ this.addSql(`drop table if exists \`account\`;`);
+ this.addSql(`drop table if exists \`teams_team\`;`);
+ this.addSql(`drop table if exists \`teams_member\`;`);
+ this.addSql(`drop table if exists \`teams_invite\`;`);
+ }
+}
diff --git a/apps/demo/db/migrations/sqlite/Migration20261028120000_user_image.ts b/apps/demo/db/migrations/sqlite/Migration20261028120000_user_image.ts
new file mode 100644
index 000000000..17a095666
--- /dev/null
+++ b/apps/demo/db/migrations/sqlite/Migration20261028120000_user_image.ts
@@ -0,0 +1,13 @@
+import { Migration } from "@mikro-orm/migrations";
+
+export class Migration20261028120000_user_image extends Migration {
+ override name = "Migration20261028120000_user_image";
+
+ override up(): void {
+ this.addSql("alter table `core_user` rename column `profile_photo_url` to `image`;");
+ }
+
+ override down(): void {
+ this.addSql("alter table `core_user` rename column `image` to `profile_photo_url`;");
+ }
+}
diff --git a/apps/demo/env.ts b/apps/demo/env.ts
new file mode 100644
index 000000000..6ded78775
--- /dev/null
+++ b/apps/demo/env.ts
@@ -0,0 +1,25 @@
+// Worker secrets are exposed through process.env by nodejs_compat. Node scripts
+// explicitly load .dev.vars before importing the application configuration.
+export const env = {
+ appUrl: process.env.BETTER_AUTH_URL ?? "http://localhost:3001",
+ betterAuthUrl: process.env.BETTER_AUTH_URL ?? "http://localhost:3001",
+ betterAuthSecret: process.env.BETTER_AUTH_SECRET,
+ databaseUrl: process.env.TURSO_DATABASE_URL,
+ tursoAuthToken: process.env.TURSO_AUTH_TOKEN,
+};
+
+export function assertDemoEnvironment() {
+ if (!env.databaseUrl || !/^(libsql|https?):\/\//.test(env.databaseUrl))
+ throw new Error(
+ "Set TURSO_DATABASE_URL in apps/demo/.dev.vars or Worker secrets.",
+ );
+ if (!env.tursoAuthToken)
+ throw new Error(
+ "Set TURSO_AUTH_TOKEN in apps/demo/.dev.vars or Worker secrets.",
+ );
+ if (!env.betterAuthSecret || env.betterAuthSecret.length < 32)
+ throw new Error(
+ "Set BETTER_AUTH_SECRET to a random value of at least 32 characters.",
+ );
+ new URL(env.appUrl);
+}
diff --git a/apps/demo/hackkit.config.ts b/apps/demo/hackkit.config.ts
new file mode 100644
index 000000000..ccc9edd52
--- /dev/null
+++ b/apps/demo/hackkit.config.ts
@@ -0,0 +1,138 @@
+import { defineHackkitConfig } from "@hackkit/config";
+import { CorePermission, type PermissionKey } from "@hackkit/core";
+import { databaseOptions } from "./lib/database-config";
+import { authOptions } from "./lib/auth-options";
+import { teamsPlugin, TeamsPermission } from "@hackkit/plugin-teams";
+
+const participantPermissions = [] as PermissionKey[];
+
+const adminPermissions = [
+ ...Object.values(CorePermission),
+ ...Object.values(TeamsPermission),
+] satisfies PermissionKey[];
+
+const shirtSizeOptions = [
+ { value: "s", label: "Small" },
+ { value: "m", label: "Medium" },
+ { value: "l", label: "Large" },
+ { value: "xl", label: "Extra large" },
+ { value: "2xl", label: "2XL" },
+ { value: "3xl", label: "3XL" },
+];
+
+const countryOptions = [
+ { value: "us", label: "United States" },
+ { value: "ca", label: "Canada" },
+ { value: "mx", label: "Mexico" },
+ { value: "gb", label: "United Kingdom" },
+ { value: "other", label: "Other" },
+];
+
+const schoolOptions = [
+ {
+ value: "University of Texas at San Antonio",
+ label: "University of Texas at San Antonio",
+ },
+ {
+ value: "University of Texas at Austin",
+ label: "University of Texas at Austin",
+ },
+ { value: "Texas A&M University", label: "Texas A&M University" },
+ { value: "Rice University", label: "Rice University" },
+ { value: "other", label: "Other" },
+];
+
+const majorOptions = [
+ { value: "Computer Science", label: "Computer Science" },
+ { value: "Computer Engineering", label: "Computer Engineering" },
+ { value: "Electrical Engineering", label: "Electrical Engineering" },
+ { value: "Data Science", label: "Data Science" },
+ { value: "Design", label: "Design" },
+ { value: "Business", label: "Business" },
+ { value: "other", label: "Other" },
+];
+
+const levelsOfStudy = [
+ { value: "Freshman", label: "Freshman" },
+ { value: "Sophomore", label: "Sophomore" },
+ { value: "Junior", label: "Junior" },
+ { value: "Senior", label: "Senior" },
+ { value: "Graduate", label: "Graduate" },
+ { value: "Recent Grad", label: "Recent Grad" },
+ { value: "Other", label: "Other" },
+];
+
+const softwareExperienceOptions = [
+ { value: "Beginner", label: "Beginner" },
+ { value: "Intermediate", label: "Intermediate" },
+ { value: "Advanced", label: "Advanced" },
+ { value: "Expert", label: "Expert" },
+];
+
+const heardFromOptions = [
+ { value: "Instagram", label: "Instagram" },
+ { value: "Class Presentation", label: "Class presentation" },
+ { value: "Twitter", label: "Twitter" },
+ { value: "Event Site", label: "Event site" },
+ { value: "Friend", label: "Friend" },
+ { value: "Other", label: "Other" },
+];
+
+const groups = [
+ {
+ id: "guild-a",
+ label: "Guild A",
+ discordRoleName: "Guild A",
+ },
+ {
+ id: "guild-b",
+ label: "Guild B",
+ discordRoleName: "Guild B",
+ },
+ {
+ id: "guild-c",
+ label: "Guild C",
+ discordRoleName: "Guild C",
+ },
+] as const;
+
+export default defineHackkitConfig({
+ database: databaseOptions,
+ auth: authOptions,
+ defaultCompetitorRoleId: "core.participant",
+ groups,
+ seedRoles: [
+ {
+ id: "core.participant",
+ name: "Participant",
+ position: 10,
+ permissions: participantPermissions,
+ },
+ {
+ id: "core.owner",
+ name: "Owner",
+ position: 0,
+ permissions: adminPermissions,
+ },
+ ],
+ logger: { level: "warn" },
+ plugins: [teamsPlugin()],
+ userDataOptions: {
+ shirtSize: shirtSizeOptions,
+ countryOfResidence: countryOptions,
+ },
+ hackerRegistrationOptions: {
+ schools: schoolOptions,
+ majors: majorOptions,
+ levelsOfStudy,
+ softwareExperience: softwareExperienceOptions,
+ heardFrom: heardFromOptions,
+ },
+ eventTypes: [
+ { value: "meal", label: "Meal", color: "#FFC107" },
+ { value: "workshop", label: "Workshop", color: "#10b981" },
+ { value: "ceremony", label: "Ceremony", color: "#9C27B0" },
+ { value: "social", label: "Social", color: "#2196F3" },
+ { value: "other", label: "Other", color: "#795548" },
+ ],
+});
diff --git a/apps/demo/hackkit.lock b/apps/demo/hackkit.lock
new file mode 100644
index 000000000..40c371735
--- /dev/null
+++ b/apps/demo/hackkit.lock
@@ -0,0 +1,20 @@
+{
+ "version": 1,
+ "plugins": [
+ {
+ "id": "teams",
+ "package": "@hackkit/plugin-teams",
+ "version": "0.0.0",
+ "routes": [
+ {
+ "host": "app/invites/page.tsx",
+ "source": "@hackkit/plugin-teams/app/invites/page"
+ },
+ {
+ "host": "app/teams/page.tsx",
+ "source": "@hackkit/plugin-teams/app/teams/page"
+ }
+ ]
+ }
+ ]
+}
diff --git a/apps/demo/lib/app-config.ts b/apps/demo/lib/app-config.ts
new file mode 100644
index 000000000..0753fba17
--- /dev/null
+++ b/apps/demo/lib/app-config.ts
@@ -0,0 +1,15 @@
+import "server-only";
+
+import { resolveHackkitConfig } from "@hackkit/config";
+import hackkitConfig from "../hackkit.config";
+import { env } from "../env";
+import compiledFunctions from "./generated/orm-functions.js";
+
+export const appConfig = resolveHackkitConfig({
+ ...hackkitConfig,
+ database: { ...hackkitConfig.database, compiledFunctions },
+});
+
+export function resolveAppBaseUrl(): string {
+ return env.appUrl;
+}
diff --git a/apps/web/lib/auth-client.ts b/apps/demo/lib/auth-client.ts
similarity index 100%
rename from apps/web/lib/auth-client.ts
rename to apps/demo/lib/auth-client.ts
diff --git a/apps/demo/lib/auth-options.ts b/apps/demo/lib/auth-options.ts
new file mode 100644
index 000000000..7019da877
--- /dev/null
+++ b/apps/demo/lib/auth-options.ts
@@ -0,0 +1,8 @@
+import type { HackKitAuthOptions } from "@hackkit/core";
+import { env } from "../env";
+export const authOptions = {
+ baseURL: env.betterAuthUrl,
+ secret: env.betterAuthSecret,
+ trustedOrigins: [env.appUrl],
+ emailAndPassword: { enabled: true },
+} satisfies HackKitAuthOptions;
diff --git a/apps/web/lib/auth.ts b/apps/demo/lib/auth.ts
similarity index 100%
rename from apps/web/lib/auth.ts
rename to apps/demo/lib/auth.ts
diff --git a/apps/demo/lib/blob.ts b/apps/demo/lib/blob.ts
new file mode 100644
index 000000000..ed70dc54e
--- /dev/null
+++ b/apps/demo/lib/blob.ts
@@ -0,0 +1,65 @@
+import "server-only";
+import { env } from "cloudflare:workers";
+import { env as settings } from "../env";
+
+export const maximumUploadBytes = 10 * 1024 * 1024;
+
+export function createUploadTarget(input: {
+ ownerId: string;
+ location: string;
+ fileName: string;
+}) {
+ const extension = input.fileName
+ .split(".")
+ .pop()
+ ?.replace(/[^a-z0-9]/gi, "")
+ .slice(0, 12);
+ const key = `${input.location}/${input.ownerId}/${crypto.randomUUID()}${extension ? `.${extension}` : ""}`;
+ return {
+ uploadUrl: `${settings.appUrl}/api/files/upload?key=${encodeURIComponent(key)}`,
+ storedFileReference: `/api/files/view?key=${encodeURIComponent(key)}`,
+ };
+}
+
+export function canUploadKey(key: string, ownerId: string) {
+ return (
+ ["resumes", "profile-photos"].some((location) =>
+ key.startsWith(`${location}/${ownerId}/`),
+ ) &&
+ !key.includes("..") &&
+ key.split("/").length === 3
+ );
+}
+
+/** Read a bounded body even when a client omits Content-Length. */
+export async function readUploadBody(request: Request) {
+ const reader = request.body?.getReader();
+ if (!reader) return new Uint8Array();
+ const chunks: Uint8Array[] = [];
+ let length = 0;
+ try {
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) break;
+ length += value.byteLength;
+ if (length > maximumUploadBytes) {
+ await reader.cancel();
+ throw new RangeError("Files must be 10 MiB or smaller.");
+ }
+ chunks.push(value);
+ }
+ } finally {
+ reader.releaseLock();
+ }
+ const body = new Uint8Array(length);
+ let offset = 0;
+ for (const chunk of chunks) {
+ body.set(chunk, offset);
+ offset += chunk.byteLength;
+ }
+ return body;
+}
+
+export function getBlobStorage() {
+ return env.DEMO_UPLOADS;
+}
diff --git a/apps/demo/lib/database-config.ts b/apps/demo/lib/database-config.ts
new file mode 100644
index 000000000..5925f6fab
--- /dev/null
+++ b/apps/demo/lib/database-config.ts
@@ -0,0 +1,16 @@
+import { SqliteDriver } from "@mikro-orm/sql";
+import { HttpLibsqlDialect } from "./http-libsql-dialect";
+import type { HackKitDatabaseOptions } from "@hackkit/core";
+import { env } from "../env";
+
+// The generic SQLite driver accepts a Kysely dialect without loading native
+// SQLite binaries. The web client uses Turso's HTTP API and supports transactions.
+export const databaseOptions = {
+ driver: SqliteDriver,
+ dbName: "hackkit-demo",
+ driverOptions: () =>
+ new HttpLibsqlDialect({
+ url: env.databaseUrl ?? "http://127.0.0.1:9",
+ authToken: env.tursoAuthToken,
+ }),
+} satisfies HackKitDatabaseOptions;
diff --git a/apps/demo/lib/demo-accounts.ts b/apps/demo/lib/demo-accounts.ts
new file mode 100644
index 000000000..b54a7d496
--- /dev/null
+++ b/apps/demo/lib/demo-accounts.ts
@@ -0,0 +1,20 @@
+// Public, fictional accounts in the shared demonstration database.
+export const demoPassword = "Explore-HackKit-2026!";
+export const demoAccounts = {
+ participant: {
+ name: "Alex Rivera",
+ email: "alex@example.com",
+ tag: "alex",
+ },
+ organizer: { name: "Sam Chen", email: "sam@example.com", tag: "sam" },
+ newcomer: {
+ name: "Jordan Park",
+ email: "jordan@example.com",
+ tag: "jordan",
+ },
+ teammate: {
+ name: "Taylor Morgan",
+ email: "taylor@example.com",
+ tag: "taylor",
+ },
+};
diff --git a/apps/web/lib/hackkit-ui-routes.ts b/apps/demo/lib/hackkit-ui-routes.ts
similarity index 100%
rename from apps/web/lib/hackkit-ui-routes.ts
rename to apps/demo/lib/hackkit-ui-routes.ts
diff --git a/apps/demo/lib/http-libsql-dialect.ts b/apps/demo/lib/http-libsql-dialect.ts
new file mode 100644
index 000000000..a9cc34464
--- /dev/null
+++ b/apps/demo/lib/http-libsql-dialect.ts
@@ -0,0 +1,66 @@
+import { createClient, type Client, type Config } from "@libsql/client/web";
+import {
+ LibsqlConnection,
+ LibsqlDialect,
+ LibsqlDriver,
+} from "@libsql/kysely-libsql";
+import { CompiledQuery, SqliteAdapter, type DatabaseConnection } from "kysely";
+
+/** Complete Kysely's savepoint API for MikroORM's nested transactions. */
+class HttpLibsqlDriver extends LibsqlDriver {
+ private readonly clients = new WeakMap();
+ constructor(private readonly createClient: () => Client) {
+ super(createClient(), true);
+ }
+ // libSQL HTTP clients retain stream state. Each checkout must belong to the
+ // current Worker request, while a transaction keeps its own connection.
+ override async acquireConnection() {
+ const client = this.createClient();
+ const connection = new LibsqlConnection(client);
+ this.clients.set(connection, client);
+ return connection;
+ }
+ override async releaseConnection(connection: DatabaseConnection) {
+ this.clients.get(connection)?.close();
+ this.clients.delete(connection);
+ }
+ async savepoint(connection: DatabaseConnection, name: string) {
+ await connection.executeQuery(
+ CompiledQuery.raw(`savepoint "${name.replaceAll('"', '""')}"`),
+ );
+ }
+ async rollbackToSavepoint(connection: DatabaseConnection, name: string) {
+ await connection.executeQuery(
+ CompiledQuery.raw(
+ `rollback to savepoint "${name.replaceAll('"', '""')}"`,
+ ),
+ );
+ }
+ async releaseSavepoint(connection: DatabaseConnection, name: string) {
+ await connection.executeQuery(
+ CompiledQuery.raw(
+ `release savepoint "${name.replaceAll('"', '""')}"`,
+ ),
+ );
+ }
+}
+
+// Remote libSQL supports separate connections. Kysely's native SQLite mutex
+// would otherwise make unrelated Worker requests wait on one another's I/O.
+class HttpLibsqlAdapter extends SqliteAdapter {
+ override get supportsMultipleConnections() {
+ return true;
+ }
+}
+
+export class HttpLibsqlDialect extends LibsqlDialect {
+ constructor(private readonly options: Config) {
+ super(options);
+ }
+ override createAdapter() {
+ return new HttpLibsqlAdapter();
+ }
+ override createDriver() {
+ return new HttpLibsqlDriver(() => createClient(this.options));
+ }
+}
diff --git a/apps/web/lib/logger.ts b/apps/demo/lib/logger.ts
similarity index 100%
rename from apps/web/lib/logger.ts
rename to apps/demo/lib/logger.ts
diff --git a/apps/web/lib/onboarding.ts b/apps/demo/lib/onboarding.ts
similarity index 100%
rename from apps/web/lib/onboarding.ts
rename to apps/demo/lib/onboarding.ts
diff --git a/apps/web/lib/plugin-navigation.ts b/apps/demo/lib/plugin-navigation.ts
similarity index 100%
rename from apps/web/lib/plugin-navigation.ts
rename to apps/demo/lib/plugin-navigation.ts
diff --git a/apps/demo/lib/public-site-config.ts b/apps/demo/lib/public-site-config.ts
new file mode 100644
index 000000000..313aedddf
--- /dev/null
+++ b/apps/demo/lib/public-site-config.ts
@@ -0,0 +1,249 @@
+import type { CSSProperties } from "react";
+import type {
+ PublicLandingPageProps,
+ PublicShellLink,
+ PublicSiteFooterGroup,
+} from "@hackkit/ui";
+
+export type PublicSiteConfig = {
+ brand: {
+ name: string;
+ shortName: string;
+ description: string;
+ };
+ event: {
+ name: string;
+ dates: string;
+ location: string;
+ timezone: string;
+ };
+ theme: {
+ primary: string;
+ ring: string;
+ };
+ nav: {
+ public: PublicShellLink[];
+ participant: PublicShellLink[];
+ };
+ landing: Omit<
+ PublicLandingPageProps,
+ "primaryAction" | "secondaryAction"
+ > & {
+ primaryAction: PublicShellLink;
+ secondaryAction: PublicShellLink;
+ signedInAction: PublicShellLink;
+ };
+ help: {
+ title: string;
+ description: string;
+ contacts: PublicShellLink[];
+ resources: PublicShellLink[];
+ };
+ dashboard: {
+ primaryActions: PublicShellLink[];
+ resourceLinks: PublicShellLink[];
+ };
+ footer: {
+ linkGroups: PublicSiteFooterGroup[];
+ };
+};
+
+export const publicSiteConfig = {
+ brand: {
+ name: "HackKit Demo",
+ shortName: "HackKit",
+ description:
+ "A production-ready hackathon shell for registration, event operations, and participant support.",
+ },
+ event: {
+ name: "HackKit Demo Weekend",
+ dates: "March 21-23, 2027",
+ location: "San Antonio, Texas",
+ timezone: "America/Chicago",
+ },
+ theme: {
+ primary: "221.2 83.2% 53.3%",
+ ring: "221.2 83.2% 53.3%",
+ },
+ nav: {
+ public: [
+ { label: "Schedule", href: "/schedule" },
+ { label: "Help", href: "/help" },
+ ],
+ participant: [
+ { label: "Dashboard", href: "/dashboard" },
+ { label: "Event Pass", href: "/pass" },
+ { label: "Teams", href: "/teams" },
+ { label: "RSVP", href: "/rsvp" },
+ ],
+ },
+ landing: {
+ eyebrow: "HackKit demo event",
+ title: "Everything participants need before and during event weekend.",
+ description:
+ "Register, keep your profile current, follow the public schedule, manage your event pass, and get help from the organizing team in one place.",
+ primaryAction: { label: "Apply now", href: "/sign-up" },
+ secondaryAction: { label: "View schedule", href: "/schedule" },
+ signedInAction: { label: "Open dashboard", href: "/dashboard" },
+ stats: [
+ { value: "48h", label: "Build window" },
+ { value: "24/7", label: "Participant support" },
+ { value: "1", label: "Source of truth" },
+ { value: "Live", label: "Schedule updates" },
+ ],
+ highlights: [
+ {
+ title: "Public schedule",
+ description:
+ "Browse event programming before signing in, then open details from your dashboard during the event.",
+ },
+ {
+ title: "Participant dashboard",
+ description:
+ "Jump to event pass, RSVP, team tools, settings, and day-of resources after approval.",
+ },
+ {
+ title: "Organizer-ready routing",
+ description:
+ "Admin, settings, profile, and RSVP routes stay connected without exposing their internals on the public site.",
+ },
+ ],
+ sections: [
+ {
+ title: "Before the event",
+ description:
+ "Create your account, finish onboarding, update registration details, and watch for approval updates.",
+ },
+ {
+ title: "During the event",
+ description:
+ "Keep your event pass handy, check the latest schedule, and find support links without digging through email.",
+ },
+ {
+ title: "After launch",
+ description:
+ "App-owned content and theme tokens keep this shell adaptable for each HackKit deployment.",
+ },
+ ],
+ },
+ help: {
+ title: "Contact and help",
+ description:
+ "Need support before or during the event? Use these entry points for organizer help, technical issues, and participant resources.",
+ contacts: [
+ {
+ label: "Organizer support",
+ href: "https://hackkit-docs.acm-utsa.workers.dev/docs/demo",
+ description:
+ "Questions about registration, approvals, travel, or event logistics.",
+ },
+ {
+ label: "Report a bug",
+ href: "https://github.com/acmutsa/HackKitPlugin/issues/new",
+ description:
+ "File a HackKit issue for broken flows, confusing copy, or production shell polish.",
+ external: true,
+ },
+ {
+ label: "Discord help",
+ href: "https://hackkit-docs.acm-utsa.workers.dev/docs/demo?subject=Discord%20help",
+ description:
+ "Ask organizers for the current Discord invite or access help.",
+ },
+ {
+ label: "Emergency contact",
+ href: "https://hackkit-docs.acm-utsa.workers.dev/docs/demo?subject=Urgent%20event%20support",
+ description:
+ "Use for urgent safety or day-of operations issues.",
+ },
+ ],
+ resources: [
+ { label: "Schedule", href: "/schedule" },
+ { label: "Dashboard", href: "/dashboard" },
+ { label: "Settings", href: "/settings" },
+ { label: "Registration", href: "/settings/registration" },
+ ],
+ },
+ dashboard: {
+ primaryActions: [
+ { label: "Open event pass", href: "/pass" },
+ { label: "View schedule", href: "/schedule" },
+ { label: "Manage RSVP", href: "/rsvp" },
+ ],
+ resourceLinks: [
+ {
+ label: "Schedule",
+ href: "/schedule",
+ description:
+ "See public events and open detailed schedule pages.",
+ },
+ {
+ label: "Event pass",
+ href: "/pass",
+ description: "Use your QR pass for check-in and event scans.",
+ },
+ {
+ label: "Teams",
+ href: "/teams",
+ description:
+ "Manage team participation through the existing team route.",
+ },
+ {
+ label: "Invites",
+ href: "/invites",
+ description: "Review pending team or participant invitations.",
+ },
+ {
+ label: "Settings",
+ href: "/settings",
+ description:
+ "Update profile details and registration information.",
+ },
+ {
+ label: "Survival guide",
+ href: "/help",
+ description:
+ "Find help contacts, logistics links, and Discord instructions.",
+ },
+ {
+ label: "Discord",
+ href: "/help",
+ description:
+ "Get the current invite and access instructions from organizers.",
+ },
+ {
+ label: "Admin console",
+ href: "/admin",
+ description:
+ "Organizer tools are available to authorized users.",
+ },
+ ],
+ },
+ footer: {
+ linkGroups: [
+ {
+ title: "Event",
+ links: [
+ { label: "Schedule", href: "/schedule" },
+ { label: "Help", href: "/help" },
+ { label: "Apply", href: "/sign-up" },
+ ],
+ },
+ {
+ title: "Participant",
+ links: [
+ { label: "Dashboard", href: "/dashboard" },
+ { label: "Event pass", href: "/pass" },
+ { label: "Settings", href: "/settings" },
+ ],
+ },
+ ],
+ },
+} satisfies PublicSiteConfig;
+
+export function getPublicThemeStyle(): CSSProperties {
+ return {
+ "--primary": publicSiteConfig.theme.primary,
+ "--ring": publicSiteConfig.theme.ring,
+ } as CSSProperties;
+}
diff --git a/apps/demo/lib/runtime.ts b/apps/demo/lib/runtime.ts
new file mode 100644
index 000000000..08224fa1c
--- /dev/null
+++ b/apps/demo/lib/runtime.ts
@@ -0,0 +1,43 @@
+import "server-only";
+
+import {
+ createHackkitRuntimeFromConfig,
+ setHackkitRuntime,
+} from "@hackkit/next";
+import { appConfig } from "./app-config";
+
+import { assertDemoEnvironment } from "../env";
+
+let host:
+ | ReturnType<
+ typeof createHackkitRuntimeFromConfig
+ >
+ | undefined;
+function getHost() {
+ assertDemoEnvironment();
+ return (host ??= createHackkitRuntimeFromConfig({ config: appConfig }));
+}
+setHackkitRuntime(async () => getHost().getRuntime());
+
+export async function getRuntime() {
+ return getHost().getRuntime();
+}
+
+export async function getCurrentUser() {
+ return (await getRuntime()).getCurrentUser();
+}
+
+export async function getHackkit() {
+ return (await getRuntime()).hackkit;
+}
+
+export async function getPageGuards() {
+ return (await getRuntime()).pageGuards;
+}
+
+export function getCoreRuntime() {
+ return getHost().core;
+}
+
+export const handleHackkitRequest = (request: Request) =>
+ getHost().handler(request);
diff --git a/apps/web/lib/upload-profile-photo.ts b/apps/demo/lib/upload-profile-photo.ts
similarity index 100%
rename from apps/web/lib/upload-profile-photo.ts
rename to apps/demo/lib/upload-profile-photo.ts
diff --git a/apps/web/lib/upload-resume.ts b/apps/demo/lib/upload-resume.ts
similarity index 100%
rename from apps/web/lib/upload-resume.ts
rename to apps/demo/lib/upload-resume.ts
diff --git a/apps/web/middleware.ts b/apps/demo/middleware.ts
similarity index 100%
rename from apps/web/middleware.ts
rename to apps/demo/middleware.ts
diff --git a/apps/demo/next-env.d.ts b/apps/demo/next-env.d.ts
new file mode 100644
index 000000000..100986254
--- /dev/null
+++ b/apps/demo/next-env.d.ts
@@ -0,0 +1,7 @@
+///
+///
+import "vinext/types/augmentations";
+import "./.next/types/routes.d.ts";
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/apps/demo/next.config.mjs b/apps/demo/next.config.mjs
new file mode 100644
index 000000000..c4a407b7c
--- /dev/null
+++ b/apps/demo/next.config.mjs
@@ -0,0 +1,2 @@
+/** @type {import('next').NextConfig} */
+export default {};
diff --git a/apps/demo/package.json b/apps/demo/package.json
new file mode 100644
index 000000000..1499e372a
--- /dev/null
+++ b/apps/demo/package.json
@@ -0,0 +1,72 @@
+{
+ "name": "@hackkit/demo",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "plugin:sync": "hackkit plugin sync",
+ "db:generate": "node scripts/db.mjs generate",
+ "db:migrate": "node scripts/db.mjs migrate",
+ "db:seed": "node scripts/db.mjs seed",
+ "db:reset": "node scripts/db.mjs reset",
+ "sync": "pnpm plugin:sync",
+ "dev": "node scripts/compile-orm.mjs && vite dev --port 3001",
+ "build": "node scripts/build.mjs",
+ "verify": "pnpm sync && pnpm typecheck && pnpm build",
+ "start": "vite preview --port 3001",
+ "typecheck": "pnpm orm:compile && tsc -p tsconfig.typecheck.json --noEmit",
+ "db:status": "node scripts/db.mjs status",
+ "db:check": "node scripts/db.mjs check",
+ "db:rollback": "node scripts/db.mjs rollback",
+ "deploy": "pnpm build && wrangler deploy",
+ "deploy:check": "wrangler deploy --dry-run",
+ "cf:types": "wrangler types --include-runtime=false worker/env.d.ts",
+ "test:smoke": "playwright test",
+ "orm:compile": "node scripts/compile-orm.mjs",
+ "db:demo": "node scripts/seed.mjs",
+ "test:database": "node --test scripts/test-database.mjs"
+ },
+ "dependencies": {
+ "@hackkit/cli": "workspace:*",
+ "@hackkit/config": "workspace:*",
+ "@hackkit/core": "workspace:*",
+ "@hackkit/next": "workspace:*",
+ "@hackkit/plugin-teams": "workspace:*",
+ "@hackkit/ui": "workspace:*",
+ "better-auth": "1.7.6",
+ "next": "14.2.35",
+ "react": "19.3.1",
+ "react-dom": "19.3.1",
+ "sonner": "^1.5.0",
+ "typescript": "5.9.3",
+ "@mikro-orm/migrations": "7.2.1",
+ "@mikro-orm/core": "7.2.1",
+ "jiti": "2.4.2",
+ "@next/env": "14.2.35",
+ "@libsql/client": "0.17.4",
+ "react-server-dom-webpack": "19.3.1",
+ "vinext": "1.2.1",
+ "@mikro-orm/sql": "7.2.1",
+ "@libsql/kysely-libsql": "0.4.1",
+ "kysely": "0.29.6",
+ "zod": "^3.25.67"
+ },
+ "devDependencies": {
+ "@types/node": "22.18.6",
+ "@types/react": "19.3.0",
+ "@types/react-dom": "19.3.0",
+ "autoprefixer": "10.4.19",
+ "postcss": "8.4.39",
+ "tailwindcss": "3.4.6",
+ "tailwindcss-animate": "1.0.7",
+ "wrangler": "4.151.3",
+ "@cloudflare/workers-types": "5.20261019.1",
+ "@playwright/test": "1.64.1",
+ "vite": "8.3.4",
+ "@cloudflare/vite-plugin": "1.64.0",
+ "@vitejs/plugin-rsc": "0.5.38",
+ "@vitejs/plugin-react": "6.0.1",
+ "@mikro-orm/cli": "7.2.1",
+ "dotenv": "16.6.1"
+ }
+}
diff --git a/apps/demo/playwright.config.ts b/apps/demo/playwright.config.ts
new file mode 100644
index 000000000..8a84ec2a3
--- /dev/null
+++ b/apps/demo/playwright.config.ts
@@ -0,0 +1,31 @@
+import { defineConfig } from "@playwright/test";
+
+if (!process.env.DEMO_TEST_URL)
+ throw new Error("Set DEMO_TEST_URL to a running demo deployment.");
+
+export default defineConfig({
+ testDir: "./tests",
+ fullyParallel: false,
+ workers: 1,
+ retries: 0,
+ timeout: 120_000,
+ expect: { timeout: 30_000 },
+ reporter: [["list"], ["html", { open: "never" }]],
+ webServer: process.env.CI
+ ? {
+ command: "pnpm start > .wrangler/ci-server.log 2>&1",
+ url: process.env.DEMO_TEST_URL,
+ reuseExistingServer: false,
+ timeout: 60_000,
+ gracefulShutdown: { signal: "SIGTERM", timeout: 5_000 },
+ }
+ : undefined,
+ use: {
+ baseURL: process.env.DEMO_TEST_URL,
+ actionTimeout: 20_000,
+ navigationTimeout: 30_000,
+ browserName: "chromium",
+ screenshot: "only-on-failure",
+ trace: "retain-on-failure",
+ },
+});
diff --git a/apps/web/postcss.config.cjs b/apps/demo/postcss.config.cjs
similarity index 100%
rename from apps/web/postcss.config.cjs
rename to apps/demo/postcss.config.cjs
diff --git a/apps/demo/scripts/build.mjs b/apps/demo/scripts/build.mjs
new file mode 100644
index 000000000..c2662cb42
--- /dev/null
+++ b/apps/demo/scripts/build.mjs
@@ -0,0 +1,20 @@
+import { chmodSync, existsSync, readdirSync } from "node:fs";
+import { spawnSync } from "node:child_process";
+
+for (const args of [
+ ["scripts/compile-orm.mjs"],
+ ["node_modules/vite/bin/vite.js", "build"],
+]) {
+ const result = spawnSync(process.execPath, args, { stdio: "inherit" });
+ if (result.error) throw result.error;
+ if (result.status !== 0) process.exit(result.status ?? 1);
+}
+
+// Cloudflare copies local variables into the preview output. Keep that ignored
+// file private. Turbo excludes credential files and never caches this build.
+if (existsSync("dist/server")) {
+ for (const file of readdirSync("dist/server")) {
+ if (/^\.(dev\.vars|env)(\.|$)/.test(file))
+ chmodSync(`dist/server/${file}`, 0o600);
+ }
+}
diff --git a/apps/demo/scripts/compile-orm.mjs b/apps/demo/scripts/compile-orm.mjs
new file mode 100644
index 000000000..aa4c4b514
--- /dev/null
+++ b/apps/demo/scripts/compile-orm.mjs
@@ -0,0 +1,24 @@
+import { spawnSync } from "node:child_process";
+// Compiling entity functions never needs credentials or a database connection.
+const result = spawnSync(
+ process.execPath,
+ [
+ "node_modules/@mikro-orm/cli/cli.js",
+ "compile",
+ "--config",
+ "scripts/orm.config.mjs",
+ "--out",
+ "lib/generated/orm-functions.js",
+ ],
+ {
+ stdio: "inherit",
+ env: {
+ ...process.env,
+ TURSO_DATABASE_URL: "http://127.0.0.1:9",
+ TURSO_AUTH_TOKEN: "metadata-only",
+ BETTER_AUTH_SECRET: "build-only-secret-no-network-or-runtime-use",
+ },
+ },
+);
+if (result.error) throw result.error;
+process.exitCode = result.status ?? 1;
diff --git a/apps/demo/scripts/database.ts b/apps/demo/scripts/database.ts
new file mode 100644
index 000000000..8a665c219
--- /dev/null
+++ b/apps/demo/scripts/database.ts
@@ -0,0 +1,120 @@
+import { resolve } from "node:path";
+import { resolveHackkitConfig, type HackkitConfig } from "@hackkit/config";
+import { createOrmOptions, seedRoles } from "@hackkit/core";
+import { MikroORM } from "@mikro-orm/core";
+import { createJiti } from "jiti";
+
+const jiti = createJiti(import.meta.url);
+
+export type DatabaseCommand =
+ | { command: "generate"; name?: string; blank?: boolean }
+ | { command: "status" | "check" | "seed" | "reset" }
+ | { command: "migrate"; to?: string }
+ | { command: "rollback"; to?: string };
+
+/** Runs an explicit database operation. App startup never calls this function. */
+export async function runDatabaseCommand(
+ input: HackkitConfig,
+ request: DatabaseCommand,
+) {
+ if (request.command === "reset")
+ throw new Error(
+ "Reset is disabled for the shared Turso demo database.",
+ );
+ const config = resolveHackkitConfig({
+ ...input,
+ database: {
+ ...input.database,
+ migrations: {
+ path: resolve("db/migrations/sqlite"),
+ emit: "ts",
+ snapshot: true,
+ snapshotName: ".snapshot",
+ snapshotOnMigrate: false,
+ },
+ },
+ });
+ const orm = await MikroORM.init({
+ ...createOrmOptions(config),
+ dynamicImportProvider: (id) => jiti.import(id),
+ });
+ try {
+ // MikroORM 7 initializes lazily. History operations must establish a
+ // connection first: native getPending can otherwise report all files
+ // as pending when a snapshot exists but the database is unreachable.
+ if (request.command !== "generate") await orm.connect();
+ const migrator = orm.migrator;
+ switch (request.command) {
+ case "generate": {
+ const migration = await migrator.create(
+ undefined,
+ request.blank,
+ false,
+ request.name,
+ );
+ return {
+ command: "generate" as const,
+ migration,
+ // SQLite table rebuilding also contains DROP TABLE. Review the
+ // complete migration; this list is a warning, not an SQL parser.
+ destructiveStatements: migration.diff.up.filter((sql) =>
+ /\bdrop\s+(?:table|column|schema)\b|\btruncate\b/i.test(
+ sql,
+ ),
+ ),
+ };
+ }
+ case "status":
+ case "check": {
+ // Native migrator history calls ensure its tracking table exists.
+ const executed = await migrator.getExecuted();
+ const pending = await migrator.getPending();
+ if (request.command === "status")
+ return { command: "status" as const, executed, pending };
+ // checkSchema compares entities to the committed snapshot. Separately
+ // compare the live database so a clean snapshot cannot hide drift.
+ const needsMigration = await migrator.checkSchema();
+ const schemaSql = await orm.schema.getUpdateSchemaSQL({
+ wrap: false,
+ });
+ return {
+ command: "check" as const,
+ executed,
+ pending,
+ needsMigration,
+ schemaSql,
+ ok:
+ !needsMigration &&
+ pending.length === 0 &&
+ schemaSql.trim() === "",
+ };
+ }
+ case "migrate":
+ return {
+ command: "migrate" as const,
+ migrations: await migrator.up(
+ request.to ? { to: request.to } : undefined,
+ ),
+ };
+ case "rollback":
+ return {
+ command: "rollback" as const,
+ migrations: await migrator.down(
+ request.to
+ ? { to: request.to === "0" ? 0 : request.to }
+ : undefined,
+ ),
+ };
+ case "seed":
+ return {
+ command: "seed" as const,
+ seed: await seedRoles({
+ em: orm.em.fork(),
+ roles: config.seedRoles,
+ }),
+ };
+ }
+ } finally {
+ await orm.close();
+ }
+}
diff --git a/apps/demo/scripts/db.mjs b/apps/demo/scripts/db.mjs
new file mode 100644
index 000000000..62cd93d81
--- /dev/null
+++ b/apps/demo/scripts/db.mjs
@@ -0,0 +1,62 @@
+import { parseArgs } from "node:util";
+import { writeFile } from "node:fs/promises";
+import { fileURLToPath } from "node:url";
+import { createJiti } from "jiti";
+import { config as loadEnv } from "dotenv";
+import { loadHackkitConfig } from "@hackkit/config";
+
+loadEnv({ path: ".dev.vars", quiet: true });
+const jiti = createJiti(fileURLToPath(import.meta.url));
+const { runDatabaseCommand } = await jiti.import("./database.ts");
+const { assertDemoEnvironment } = await jiti.import("../env.ts");
+assertDemoEnvironment();
+
+try {
+ const { values, positionals } = parseArgs({
+ allowPositionals: true,
+ options: {
+ config: { type: "string", default: "hackkit.config.ts" },
+ output: { type: "string" },
+ name: { type: "string" },
+ blank: { type: "boolean", default: false },
+ to: { type: "string" },
+ },
+ });
+ const [command] = positionals;
+ const commands = [
+ "generate",
+ "status",
+ "check",
+ "migrate",
+ "rollback",
+ "reset",
+ "seed",
+ ];
+ if (positionals.length !== 1 || !commands.includes(command)) {
+ throw new Error(`Choose a database command: ${commands.join(", ")}.`);
+ }
+ if ((values.name !== undefined || values.blank) && command !== "generate") {
+ throw new Error("--name and --blank are only supported by generate.");
+ }
+ if (values.to !== undefined && !["migrate", "rollback"].includes(command)) {
+ throw new Error("--to is only supported by migrate and rollback.");
+ }
+ if (values.to !== undefined && !values.to.trim()) {
+ throw new Error("--to requires a migration name (or 0 for rollback).");
+ }
+ const config = await loadHackkitConfig(values.config);
+ const result = await runDatabaseCommand(config, { command, ...values });
+ // Native drivers can write diagnostics to stdout. A separate result file
+ // gives release jobs structured output without parsing their logs.
+ if (values.output) {
+ await writeFile(values.output, `${JSON.stringify(result, null, 2)}\n`);
+ }
+ console.log(JSON.stringify(result, null, 2));
+ if (result.command === "check" && !result.ok) process.exitCode = 1;
+} catch (error) {
+ // Print the operation's error without printing the config or connection URL.
+ console.error(
+ error instanceof Error ? error.message : "Database command failed.",
+ );
+ process.exitCode = 1;
+}
diff --git a/apps/demo/scripts/orm.config.mjs b/apps/demo/scripts/orm.config.mjs
new file mode 100644
index 000000000..7ae139587
--- /dev/null
+++ b/apps/demo/scripts/orm.config.mjs
@@ -0,0 +1,5 @@
+import { createJiti } from "jiti";
+import { createOrmOptions } from "@hackkit/core";
+const jiti = createJiti(import.meta.url);
+const { default: config } = await jiti.import("../hackkit.config.ts");
+export default { ...createOrmOptions(config), connect: false };
diff --git a/apps/demo/scripts/seed.mjs b/apps/demo/scripts/seed.mjs
new file mode 100644
index 000000000..f326f06c7
--- /dev/null
+++ b/apps/demo/scripts/seed.mjs
@@ -0,0 +1,9 @@
+import { config as loadEnv } from "dotenv";
+import { createJiti } from "jiti";
+loadEnv({ path: ".dev.vars", quiet: true });
+const jiti = createJiti(import.meta.url);
+const { assertDemoEnvironment } = await jiti.import("../env.ts");
+assertDemoEnvironment();
+const { seedDemo } = await jiti.import("./seed.ts");
+await seedDemo();
+console.log("Demo setup complete. Existing users were retained.");
diff --git a/apps/demo/scripts/seed.ts b/apps/demo/scripts/seed.ts
new file mode 100644
index 000000000..b95072554
--- /dev/null
+++ b/apps/demo/scripts/seed.ts
@@ -0,0 +1,101 @@
+import { initializeHackkit, HackKitUser, CoreSetting } from "@hackkit/core";
+import { RequestContext } from "@mikro-orm/core";
+import { resolveHackkitConfig } from "@hackkit/config";
+import config from "../hackkit.config";
+import { demoAccounts, demoPassword } from "../lib/demo-accounts";
+import { runDatabaseCommand } from "./database";
+
+/** Explicit setup for an empty demo database. Never replaces existing users. */
+export async function seedDemo() {
+ await runDatabaseCommand(config, { command: "migrate" });
+ await runDatabaseCommand(config, { command: "seed" });
+ const core = await initializeHackkit(resolveHackkitConfig(config));
+ try {
+ const scope = core.createScope();
+ await RequestContext.create(scope.em, async () => {
+ if (await scope.em.count(HackKitUser, {})) return;
+ const users = new Map();
+ for (const key of Object.keys(
+ demoAccounts,
+ ) as (keyof typeof demoAccounts)[]) {
+ const account = demoAccounts[key];
+ const { user } = await core.auth.api.signUpEmail({
+ body: {
+ name: account.name,
+ email: account.email,
+ password: demoPassword,
+ },
+ });
+ users.set(key, user.id);
+ if (key === "newcomer") continue;
+ await scope.hackkit.users.claimHackTag({
+ authId: user.id,
+ hackTag: account.tag,
+ });
+ await scope.hackkit.userData.completeUserData({
+ authId: user.id,
+ age: 21,
+ gender: "prefer_not_to_answer",
+ race: "prefer_not_to_answer",
+ ethnicity: "prefer_not_to_answer",
+ shirtSize: "m",
+ dietaryRestrictions: ["none"],
+ hasAcceptedMLHCodeOfConduct: true,
+ hasSharedDataWithMLH: true,
+ isEmailable: false,
+ });
+ await scope.hackkit.hackers.registerHacker({
+ userId: user.id,
+ university: "University of Texas at San Antonio",
+ major: "Computer Science",
+ levelOfStudy: "Senior",
+ hackathonsAttended: 2,
+ softwareExperience: "Intermediate",
+ });
+ }
+ const organizerId = users.get("organizer")!;
+ await scope.em.nativeUpdate(
+ HackKitUser,
+ { id: organizerId },
+ { roleId: "core.owner", isApproved: true },
+ );
+ scope.em.clear();
+ await scope.hackkit.settings.set({
+ actorAuthId: organizerId,
+ key: CoreSetting.RsvpOpen,
+ value: true,
+ });
+ for (const [title, type, hour, location] of [
+ ["Opening ceremony", "ceremony", 9, "Main auditorium"],
+ [
+ "Build your first HackKit plugin",
+ "workshop",
+ 11,
+ "Workshop room A",
+ ],
+ ["Lunch and team matching", "meal", 12, "Student union"],
+ ["Project showcase", "ceremony", 17, "Main auditorium"],
+ ] as const) {
+ await scope.hackkit.events.createEvent({
+ actorAuthId: organizerId,
+ title,
+ type,
+ location,
+ description:
+ "A fictional event for exploring HackKit. Try editing this event in the organizer console.",
+ startTime: new Date(Date.UTC(2027, 2, 21, hour + 5)),
+ endTime: new Date(Date.UTC(2027, 2, 21, hour + 6)),
+ host: "Demo organizers",
+ hidden: false,
+ });
+ }
+ await scope.hackkit.plugins.teams.createTeam({
+ actorAuthId: users.get("teammate")!,
+ name: "Weekend Builders",
+ tag: "weekend-builders",
+ });
+ });
+ } finally {
+ await core.orm.close();
+ }
+}
diff --git a/apps/demo/scripts/test-database.mjs b/apps/demo/scripts/test-database.mjs
new file mode 100644
index 000000000..1c2489a60
--- /dev/null
+++ b/apps/demo/scripts/test-database.mjs
@@ -0,0 +1,56 @@
+import assert from "node:assert/strict";
+import { randomUUID } from "node:crypto";
+import { test } from "node:test";
+import { config as loadEnv } from "dotenv";
+import { createJiti } from "jiti";
+import { Kysely, sql } from "kysely";
+
+loadEnv({ path: ".dev.vars", quiet: true });
+const jiti = createJiti(import.meta.url);
+const { HttpLibsqlDialect } = await jiti.import(
+ "../lib/http-libsql-dialect.ts",
+);
+const { env, assertDemoEnvironment } = await jiti.import("../env.ts");
+assertDemoEnvironment();
+
+test("HTTP libSQL isolates connections and rolls back nested and outer transactions", async () => {
+ const dialect = new HttpLibsqlDialect({
+ url: env.databaseUrl,
+ authToken: env.tursoAuthToken,
+ });
+ assert.equal(dialect.createAdapter().supportsMultipleConnections, true);
+ const db = new Kysely({ dialect });
+ const key = `demo-transaction-test:${randomUUID()}`;
+ try {
+ const transaction = await db.startTransaction().execute();
+ try {
+ await sql`insert into core_operation_lock (key, token) values (${key}, ${"outer"})`.execute(
+ transaction,
+ );
+ const nested = await transaction.savepoint("nested").execute();
+ await sql`update core_operation_lock set token = ${"inner"} where key = ${key}`.execute(
+ nested,
+ );
+ await nested.rollbackToSavepoint("nested").execute();
+ const result =
+ await sql`select token from core_operation_lock where key = ${key}`.execute(
+ nested,
+ );
+ assert.equal(result.rows[0].token, "outer");
+ await nested.releaseSavepoint("nested").execute();
+ } finally {
+ await transaction.rollback().execute();
+ }
+ const result =
+ await sql`select token from core_operation_lock where key = ${key}`.execute(
+ db,
+ );
+ assert.equal(result.rows.length, 0);
+ const reads = await Promise.all(
+ Array.from({ length: 4 }, () => sql`select 1 as value`.execute(db)),
+ );
+ assert.ok(reads.every((result) => result.rows[0].value === 1));
+ } finally {
+ await db.destroy();
+ }
+});
diff --git a/apps/demo/tailwind.config.ts b/apps/demo/tailwind.config.ts
new file mode 100644
index 000000000..cff883b9f
--- /dev/null
+++ b/apps/demo/tailwind.config.ts
@@ -0,0 +1,60 @@
+import type { Config } from "tailwindcss";
+
+const config = {
+ darkMode: ["class"],
+ content: [
+ "./app/**/*.{ts,tsx}",
+ "./components/**/*.{ts,tsx}",
+ "./lib/**/*.{ts,tsx}",
+ "../../packages/ui/src/**/*.{ts,tsx}",
+ "../../packages/plugin-*/src/**/*.{ts,tsx}",
+ "../../packages/plugin-*/app/**/*.{ts,tsx}",
+ ],
+ theme: {
+ extend: {
+ colors: {
+ border: "hsl(var(--border))",
+ input: "hsl(var(--input))",
+ ring: "hsl(var(--ring))",
+ background: "hsl(var(--background))",
+ foreground: "hsl(var(--foreground))",
+ primary: {
+ DEFAULT: "hsl(var(--primary))",
+ foreground: "hsl(var(--primary-foreground))",
+ },
+ secondary: {
+ DEFAULT: "hsl(var(--secondary))",
+ foreground: "hsl(var(--secondary-foreground))",
+ },
+ destructive: {
+ DEFAULT: "hsl(var(--destructive))",
+ foreground: "hsl(var(--destructive-foreground))",
+ },
+ muted: {
+ DEFAULT: "hsl(var(--muted))",
+ foreground: "hsl(var(--muted-foreground))",
+ },
+ accent: {
+ DEFAULT: "hsl(var(--accent))",
+ foreground: "hsl(var(--accent-foreground))",
+ },
+ popover: {
+ DEFAULT: "hsl(var(--popover))",
+ foreground: "hsl(var(--popover-foreground))",
+ },
+ card: {
+ DEFAULT: "hsl(var(--card))",
+ foreground: "hsl(var(--card-foreground))",
+ },
+ },
+ borderRadius: {
+ lg: "var(--radius)",
+ md: "calc(var(--radius) - 2px)",
+ sm: "calc(var(--radius) - 4px)",
+ },
+ },
+ },
+ plugins: [require("tailwindcss-animate")],
+} satisfies Config;
+
+export default config;
diff --git a/apps/demo/tests/demo.spec.ts b/apps/demo/tests/demo.spec.ts
new file mode 100644
index 000000000..7b7b60e7b
--- /dev/null
+++ b/apps/demo/tests/demo.spec.ts
@@ -0,0 +1,235 @@
+import { test, expect } from "@playwright/test";
+import { z } from "zod";
+import { demoPassword } from "../lib/demo-accounts";
+
+const sessionSchema = z.object({
+ user: z.object({ email: z.string().email() }),
+});
+const uploadTargetSchema = z.object({
+ uploadUrl: z.string().url(),
+ storedFileReference: z.string(),
+});
+
+test("launcher opens the participant, organizer, and onboarding experiences", async ({
+ page,
+}) => {
+ await page.goto("/");
+ await expect(
+ page.getByRole("heading", {
+ name: "A hackathon, from application to check-in.",
+ }),
+ ).toBeVisible();
+ await page
+ .getByRole("button", { name: "Explore as a participant" })
+ .click();
+ await expect(page).toHaveURL(/\/dashboard$/);
+ await page.goto("/teams");
+ await expect(
+ page.getByRole("heading", { name: "Your team" }).first(),
+ ).toBeVisible();
+ await page.goto("/");
+ await page.getByRole("button", { name: "Explore as an organizer" }).click();
+ await expect(page).toHaveURL(/\/admin$/);
+ await page.goto("/admin/users");
+ await expect(page.getByText("Taylor Morgan").first()).toBeVisible();
+ await page.goto("/schedule");
+ await expect(
+ page.getByText("Build your first HackKit plugin").first(),
+ ).toBeVisible();
+ await page.goto("/");
+ await page.getByRole("button", { name: "Try registration" }).click();
+ await expect(page).toHaveURL(/\/onboarding\/hacktag$/);
+ const tag = `wk${crypto.randomUUID().replaceAll("-", "").slice(0, 16)}`;
+ const session = sessionSchema.parse(
+ await (await page.request.get("/api/auth/get-session")).json(),
+ );
+ await page.getByLabel("HackTag", { exact: true }).fill(tag);
+ await page.getByRole("button", { name: "Claim HackTag" }).click();
+ await expect(page).toHaveURL(/\/onboarding\/user-data$/);
+ await page.getByLabel("Age", { exact: true }).fill("22");
+ for (const [label, option] of [
+ ["Gender", "Prefer not to answer"],
+ ["Race", "Prefer not to answer"],
+ ["Ethnicity", "Prefer not to answer"],
+ ["Shirt size", "Medium"],
+ ["Country of residence", "United States"],
+ ]) {
+ await page.getByRole("combobox", { name: label, exact: true }).click();
+ await page.getByRole("option", { name: option, exact: true }).click();
+ }
+ await page
+ .getByRole("checkbox", { name: "No dietary restrictions", exact: true })
+ .check();
+ await page
+ .getByRole("checkbox", {
+ name: "I have read and agree to the MLH Code of Conduct.",
+ })
+ .check();
+ await page.getByRole("checkbox", { name: /I authorize sharing/ }).check();
+ await page
+ .getByRole("checkbox", { name: /I agree to receive email/ })
+ .check();
+ await page.getByRole("button", { name: "Save user data" }).click();
+ await expect(page).toHaveURL(/\/onboarding\/hacker$/);
+ for (const [label, option] of [
+ ["University", "University of Texas at San Antonio"],
+ ["Major", "Computer Science"],
+ ["Level of study", "Freshman"],
+ ["Software experience", "Beginner"],
+ ]) {
+ await page.getByRole("combobox", { name: label, exact: true }).click();
+ await page.getByRole("option", { name: option, exact: true }).click();
+ }
+ await page.getByLabel("Hackathons attended", { exact: true }).fill("0");
+ await page.getByLabel("Resume (optional, PDF)").setInputFiles({
+ name: "fictional-resume.pdf",
+ mimeType: "application/pdf",
+ buffer: Buffer.from("%PDF-1.4 fictional browser upload"),
+ });
+ const uploadRegistration = page.waitForResponse(
+ (response) =>
+ response.url().includes("/api/files/register") &&
+ response.request().method() === "POST",
+ );
+ await page.getByRole("button", { name: "Complete registration" }).click();
+ await expect(page).toHaveURL(/\/dashboard$/);
+ const upload = uploadTargetSchema.parse(
+ await (await uploadRegistration).json(),
+ );
+ const ownerRead = await page.request.get(upload.storedFileReference);
+ expect(ownerRead.status()).toBe(200);
+ expect(await ownerRead.text()).toContain("fictional browser upload");
+ await page.getByRole("button", { name: "Open account menu" }).click();
+ await page.getByRole("menuitem", { name: "Log out" }).click();
+ await expect(page).toHaveURL(/\/sign-in$/);
+ await page.getByLabel("Email", { exact: true }).fill(session.user.email);
+ await page.getByLabel("Password", { exact: true }).fill(demoPassword);
+ await page.getByRole("button", { name: "Sign in", exact: true }).click();
+ await expect(page).toHaveURL(/\/$/);
+ await page.goto("/settings/registration");
+ await expect(
+ page.getByRole("combobox", { name: "University", exact: true }),
+ ).toContainText("University of Texas at San Antonio");
+});
+
+test("Worker sessions stay independent and private R2 uploads enforce ownership", async ({
+ browser,
+ baseURL,
+}) => {
+ const participant = await browser.newContext({ baseURL });
+ const teammate = await browser.newContext({ baseURL });
+ const organizer = await browser.newContext({ baseURL });
+ const anonymous = await browser.newContext({ baseURL });
+ const contexts = [participant, teammate, organizer, anonymous];
+ const headers = { origin: baseURL! };
+ try {
+ for (const [context, email] of [
+ [participant, "alex@example.com"],
+ [teammate, "taylor@example.com"],
+ [organizer, "sam@example.com"],
+ ] as const) {
+ const login = await context.request.post(
+ "/api/auth/sign-in/email",
+ {
+ headers,
+ data: { email, password: demoPassword },
+ timeout: 20_000,
+ },
+ );
+ expect(login.status()).toBe(200);
+ }
+ // Repeated, concurrent requests catch HTTP clients retaining another
+ // Worker invocation's stream state.
+ for (let round = 0; round < 2; round++) {
+ const sessions = await Promise.all(
+ [participant, teammate].map((context) =>
+ context.request.get("/api/auth/get-session", {
+ timeout: 20_000,
+ }),
+ ),
+ );
+ const users = await Promise.all(
+ sessions.map(async (response) => {
+ expect(response.status()).toBe(200);
+ return sessionSchema.parse(await response.json()).user
+ .email;
+ }),
+ );
+ expect(users).toEqual(["alex@example.com", "taylor@example.com"]);
+ }
+ const blocked = await participant.request.post(
+ "/api/hackkit/settings/list",
+ { headers },
+ );
+ expect(blocked.status()).toBe(403);
+ const protectedPage = await anonymous.request.get("/admin", {
+ maxRedirects: 0,
+ });
+ expect(protectedPage.status()).toBe(307);
+ expect(protectedPage.headers().location).toContain("/sign-in");
+ const anonymousUpload = await anonymous.request.post(
+ "/api/files/register",
+ {
+ headers,
+ data: { location: "profile-photos", fileName: "sample.png" },
+ },
+ );
+ expect(anonymousUpload.status()).toBe(401);
+ for (const location of ["profile-photos", "resumes"] as const) {
+ const registration = await organizer.request.post(
+ "/api/files/register",
+ {
+ headers,
+ data: {
+ location,
+ fileName:
+ location === "resumes"
+ ? "sample.pdf"
+ : "sample.png",
+ },
+ },
+ );
+ expect(registration.status()).toBe(200);
+ const target = uploadTargetSchema.parse(await registration.json());
+ const upload = await organizer.request.put(target.uploadUrl, {
+ headers: {
+ ...headers,
+ "content-type":
+ location === "resumes"
+ ? "application/pdf"
+ : "image/png",
+ },
+ data: Buffer.from(
+ location === "resumes"
+ ? "%PDF-1.4 fictional resume"
+ : "fictional profile photo",
+ ),
+ });
+ expect(upload.status()).toBe(204);
+ const spoof = await participant.request.put(target.uploadUrl, {
+ headers,
+ data: "overwrite",
+ });
+ expect(spoof.status()).toBe(403);
+ const read = await organizer.request.get(
+ target.storedFileReference,
+ );
+ expect(read.status()).toBe(200);
+ expect(await read.text()).toContain("fictional");
+ const anonymousRead = await anonymous.request.get(
+ target.storedFileReference,
+ );
+ expect(anonymousRead.status()).toBe(
+ location === "resumes" ? 401 : 200,
+ );
+ if (location === "resumes") {
+ const participantRead = await participant.request.get(
+ target.storedFileReference,
+ );
+ expect(participantRead.status()).toBe(401);
+ }
+ }
+ } finally {
+ await Promise.all(contexts.map((context) => context.close()));
+ }
+});
diff --git a/apps/demo/tsconfig.json b/apps/demo/tsconfig.json
new file mode 100644
index 000000000..b1063234e
--- /dev/null
+++ b/apps/demo/tsconfig.json
@@ -0,0 +1,44 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": [
+ "./*"
+ ]
+ },
+ "types": [
+ "node",
+ "@cloudflare/workers-types"
+ ]
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist"
+ ]
+}
diff --git a/apps/demo/tsconfig.typecheck.json b/apps/demo/tsconfig.typecheck.json
new file mode 100644
index 000000000..0daf0c4fd
--- /dev/null
+++ b/apps/demo/tsconfig.typecheck.json
@@ -0,0 +1,22 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "paths": {
+ "@/*": [
+ "./*"
+ ],
+ "react": [
+ "./node_modules/@types/react/index.d.ts"
+ ],
+ "react/*": [
+ "./node_modules/@types/react/*"
+ ],
+ "react-dom": [
+ "./node_modules/@types/react-dom/index.d.ts"
+ ],
+ "react-dom/*": [
+ "./node_modules/@types/react-dom/*"
+ ]
+ }
+ }
+}
diff --git a/apps/demo/vite.config.ts b/apps/demo/vite.config.ts
new file mode 100644
index 000000000..e8479eff5
--- /dev/null
+++ b/apps/demo/vite.config.ts
@@ -0,0 +1,31 @@
+import { defineConfig } from "vite";
+import vinext from "vinext";
+import { cloudflare } from "@cloudflare/vite-plugin";
+
+export default defineConfig({
+ optimizeDeps: {
+ // Zod 3 in HackKit and Zod 4 in Better Auth must resolve per importer.
+ // MikroORM's optional filesystem imports cannot be prebundled for Workers.
+ exclude: [
+ "zod",
+ "@mikro-orm/core",
+ "@mikro-orm/sql",
+ "@mikro-orm/migrations",
+ ],
+ },
+ plugins: [
+ vinext(),
+ cloudflare({
+ viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
+ }),
+ ],
+ resolve: {
+ dedupe: [
+ "react",
+ "react-dom",
+ "react-server-dom-webpack",
+ "@mikro-orm/core",
+ "kysely",
+ ],
+ },
+});
diff --git a/apps/demo/worker/env.d.ts b/apps/demo/worker/env.d.ts
new file mode 100644
index 000000000..2a52f5431
--- /dev/null
+++ b/apps/demo/worker/env.d.ts
@@ -0,0 +1,43 @@
+/* eslint-disable */
+// Generated by Wrangler by running `wrangler types --include-runtime=false worker/env.d.ts` (hash: 26abef5bcb8c811327312c7f4cc02a6b)
+interface __BaseEnv_Env {
+ DEMO_UPLOADS: R2Bucket;
+ TURSO_DATABASE_URL: string;
+ TURSO_AUTH_TOKEN: string;
+ BETTER_AUTH_SECRET: string;
+ BETTER_AUTH_URL: string;
+}
+declare namespace Cloudflare {
+ interface Env extends __BaseEnv_Env {}
+}
+interface Env extends __BaseEnv_Env {}
+type StringifyValues> = {
+ [Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
+};
+declare namespace NodeJS {
+ interface ProcessEnv extends StringifyValues> {}
+}
+declare module "*.txt" {
+ const value: string;
+ export default value;
+}
+declare module "*.html" {
+ const value: string;
+ export default value;
+}
+declare module "*.sql" {
+ const value: string;
+ export default value;
+}
+declare module "*.bin" {
+ const value: ArrayBuffer;
+ export default value;
+}
+declare module "*.wasm" {
+ const value: WebAssembly.Module;
+ export default value;
+}
+declare module "*.wasm?module" {
+ const value: WebAssembly.Module;
+ export default value;
+}
\ No newline at end of file
diff --git a/apps/demo/wrangler.jsonc b/apps/demo/wrangler.jsonc
new file mode 100644
index 000000000..af350b618
--- /dev/null
+++ b/apps/demo/wrangler.jsonc
@@ -0,0 +1,15 @@
+{
+ "$schema": "node_modules/wrangler/config-schema.json",
+ "name": "hackkit-demo",
+ "account_id": "cdc7630e53b468f56a4453af71a58ade",
+ "main": "vinext/server/app-router-entry",
+ "compatibility_date": "2026-10-19",
+ "compatibility_flags": ["nodejs_compat"],
+ "workers_dev": true,
+ "observability": { "enabled": true },
+ "vars": { "BETTER_AUTH_URL": "https://hackkit-demo.acm-utsa.workers.dev" },
+ "assets": { "not_found_handling": "none" },
+ "r2_buckets": [
+ { "binding": "DEMO_UPLOADS", "bucket_name": "hackkit-demo-uploads" },
+ ],
+}
diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore
new file mode 100644
index 000000000..9e429e498
--- /dev/null
+++ b/apps/docs/.gitignore
@@ -0,0 +1,26 @@
+# deps
+/node_modules
+
+# generated content
+.source
+
+# test & build
+/coverage
+/.next/
+/out/
+/build
+*.tsbuildinfo
+
+# misc
+.DS_Store
+*.pem
+/.pnp
+.pnp.js
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# others
+.env*.local
+.vercel
+next-env.d.ts
\ No newline at end of file
diff --git a/apps/docs/README.md b/apps/docs/README.md
new file mode 100644
index 000000000..17958583c
--- /dev/null
+++ b/apps/docs/README.md
@@ -0,0 +1,16 @@
+# HackKit documentation
+
+Fumadocs MDX with local search, a documentation sidebar, dark mode, and static export. Source pages live in `content/docs`. Generated MDX output and `out` are ignored.
+
+From the repository root:
+
+- `corepack pnpm dev:docs`: develop at http://localhost:3002.
+- `corepack pnpm build:docs`: export the complete site to `apps/docs/out`.
+- `corepack pnpm --filter @hackkit/docs typecheck`: generate route types and check TypeScript.
+- `corepack pnpm deploy:docs`: build and publish static assets to ACM UTSA's `hackkit-docs` Worker.
+
+No environment variables, database, or runtime secrets are required. Wrangler pins the ACM UTSA account. Verify the signed-in identity before deployment. The Worker is independent of ACM's existing `docs` Worker.
+
+Public URL: https://hackkit-docs.acm-utsa.workers.dev. The site's demo link targets the separate `hackkit-demo` deployment.
+
+The docs use Next.js static export rather than a Workers SSR adapter. Fumadocs' generated search index and Markdown endpoints are exported as files. No Next.js server runs in production. This app has its own current Fumadocs/Next/React/Tailwind dependencies; the template versions remain unchanged.
diff --git a/apps/docs/app/(home)/layout.tsx b/apps/docs/app/(home)/layout.tsx
new file mode 100644
index 000000000..5959b87d9
--- /dev/null
+++ b/apps/docs/app/(home)/layout.tsx
@@ -0,0 +1,6 @@
+import { HomeLayout } from "fumadocs-ui/layouts/home";
+import { baseOptions } from "@/lib/layout.shared";
+
+export default function Layout({ children }: LayoutProps<"/">) {
+ return {children} ;
+}
diff --git a/apps/docs/app/(home)/page.tsx b/apps/docs/app/(home)/page.tsx
new file mode 100644
index 000000000..c6b279761
--- /dev/null
+++ b/apps/docs/app/(home)/page.tsx
@@ -0,0 +1,76 @@
+import Link from "next/link";
+import { BookOpen, Puzzle, Terminal, ArrowRight } from "lucide-react";
+
+export default function HomePage() {
+ return (
+
+
+ Open source hackathon software
+
+
+ Your event.
+
+ Your HackKit.
+
+
+ Build a hackathon portal around your event. Start with
+ registration and profiles, then add teams, event operations, and
+ the integrations you need.
+
+
+
+ Get started
+
+
+ Explore the demo
+
+
+
+ {[
+ {
+ icon: Terminal,
+ title: "Runnable templates",
+ description:
+ "Choose minimal Core registration or the full example. Run either locally with the workspace.",
+ href: "/docs/templates",
+ },
+ {
+ icon: Puzzle,
+ title: "A shared Core, optional plugins",
+ description:
+ "Keep domain rules and permissions in Core. Configure features and pages in your application.",
+ href: "/docs/architecture",
+ },
+ {
+ icon: BookOpen,
+ title: "Operate with confidence",
+ description:
+ "Use reviewed migrations, explicit roles, and integration checks against the actual templates.",
+ href: "/docs/testing",
+ },
+ ].map(({ icon: Icon, title, description, href }) => (
+
+
+
{title}
+
+ {description}
+
+
+ ))}
+
+
+ );
+}
diff --git a/apps/docs/app/api/search/route.ts b/apps/docs/app/api/search/route.ts
new file mode 100644
index 000000000..6aab6e1dc
--- /dev/null
+++ b/apps/docs/app/api/search/route.ts
@@ -0,0 +1,9 @@
+import { source } from "@/lib/source";
+import { createFromSource } from "fumadocs-core/search/server";
+
+export const revalidate = false;
+
+export const { staticGET: GET } = createFromSource(source, {
+ // https://docs.orama.com/docs/orama-js/supported-languages
+ language: "english",
+});
diff --git a/apps/docs/app/docs/[[...slug]]/page.tsx b/apps/docs/app/docs/[[...slug]]/page.tsx
new file mode 100644
index 000000000..fb04b6d6a
--- /dev/null
+++ b/apps/docs/app/docs/[[...slug]]/page.tsx
@@ -0,0 +1,64 @@
+import { source } from "@/lib/source";
+import {
+ DocsBody,
+ DocsDescription,
+ DocsPage,
+ DocsTitle,
+ MarkdownCopyButton,
+ ViewOptionsPopover,
+} from "fumadocs-ui/layouts/docs/page";
+import { notFound } from "next/navigation";
+import { getMDXComponents } from "@/components/mdx";
+import type { Metadata } from "next";
+import { createRelativeLink } from "fumadocs-ui/mdx";
+import { getPageImageUrl, getPageMarkdownUrl } from "@/lib/shared";
+
+export default async function Page(props: PageProps<"/docs/[[...slug]]">) {
+ const params = await props.params;
+ const page = source.getPage(params.slug);
+ if (!page) notFound();
+
+ const MDX = page.data.body;
+ const markdownUrl = getPageMarkdownUrl(page).url;
+
+ return (
+
+ {page.data.title}
+
+ {page.data.description}
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export async function generateStaticParams() {
+ return source.generateParams();
+}
+
+export async function generateMetadata(
+ props: PageProps<"/docs/[[...slug]]">,
+): Promise {
+ const params = await props.params;
+ const page = source.getPage(params.slug);
+ if (!page) notFound();
+
+ return {
+ title: page.data.title,
+ description: page.data.description,
+ openGraph: {
+ images: getPageImageUrl(page).url,
+ },
+ };
+}
diff --git a/apps/docs/app/docs/layout.tsx b/apps/docs/app/docs/layout.tsx
new file mode 100644
index 000000000..b162e3594
--- /dev/null
+++ b/apps/docs/app/docs/layout.tsx
@@ -0,0 +1,11 @@
+import { source } from "@/lib/source";
+import { DocsLayout } from "fumadocs-ui/layouts/docs";
+import { baseOptions } from "@/lib/layout.shared";
+
+export default function Layout({ children }: LayoutProps<"/docs">) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css
new file mode 100644
index 000000000..69090c62c
--- /dev/null
+++ b/apps/docs/app/global.css
@@ -0,0 +1,12 @@
+@import "tailwindcss";
+@import "fumadocs-ui/css/neutral.css";
+@import "fumadocs-ui/css/preset.css";
+
+html {
+ scrollbar-gutter: stable;
+}
+
+html > body[data-scroll-locked] {
+ margin-right: 0px !important;
+ --removed-body-scroll-bar-size: 0px !important;
+}
diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx
new file mode 100644
index 000000000..336aa033f
--- /dev/null
+++ b/apps/docs/app/layout.tsx
@@ -0,0 +1,18 @@
+import { Provider } from "@/components/provider";
+import "./global.css";
+
+export const metadata = {
+ title: { default: "HackKit documentation", template: "%s | HackKit" },
+ description:
+ "Build and operate a hackathon with HackKit. Runnable templates, authentication, registration, plugins, and event operations.",
+};
+
+export default function Layout({ children }: LayoutProps<"/">) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/apps/docs/app/llms-full.txt/route.ts b/apps/docs/app/llms-full.txt/route.ts
new file mode 100644
index 000000000..92f8382ef
--- /dev/null
+++ b/apps/docs/app/llms-full.txt/route.ts
@@ -0,0 +1,7 @@
+import { docsLlms } from "@/lib/source";
+
+export const revalidate = false;
+
+export async function GET() {
+ return new Response(await docsLlms.full());
+}
diff --git a/apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts b/apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts
new file mode 100644
index 000000000..3770c523e
--- /dev/null
+++ b/apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts
@@ -0,0 +1,27 @@
+import { docsLlms, source } from "@/lib/source";
+import { getPageMarkdownUrl } from "@/lib/shared";
+import { notFound } from "next/navigation";
+
+export const revalidate = false;
+
+export async function GET(
+ _req: Request,
+ { params }: RouteContext<"/llms.mdx/docs/[[...slug]]">,
+) {
+ const { slug } = await params;
+ // remove the appended "content.md"
+ const page = source.getPage(slug?.slice(0, -1));
+ if (!page) notFound();
+
+ return new Response(await docsLlms.page(page), {
+ headers: {
+ "Content-Type": "text/markdown",
+ },
+ });
+}
+
+export function generateStaticParams() {
+ return source.getPages().map((page) => ({
+ slug: getPageMarkdownUrl(page).segments,
+ }));
+}
diff --git a/apps/docs/app/llms.txt/route.ts b/apps/docs/app/llms.txt/route.ts
new file mode 100644
index 000000000..e8017f6f8
--- /dev/null
+++ b/apps/docs/app/llms.txt/route.ts
@@ -0,0 +1,7 @@
+import { docsLlms } from "@/lib/source";
+
+export const revalidate = false;
+
+export async function GET() {
+ return new Response(await docsLlms.index());
+}
diff --git a/apps/docs/app/og/docs/[...slug]/route.tsx b/apps/docs/app/og/docs/[...slug]/route.tsx
new file mode 100644
index 000000000..66f6bad8b
--- /dev/null
+++ b/apps/docs/app/og/docs/[...slug]/route.tsx
@@ -0,0 +1,28 @@
+import { source } from "@/lib/source";
+import { notFound } from "next/navigation";
+import { generateOGImage } from "fumadocs-ui/og";
+import { appName, getPageImageUrl } from "@/lib/shared";
+
+export const revalidate = false;
+
+export async function GET(
+ _req: Request,
+ { params }: RouteContext<"/og/docs/[...slug]">,
+) {
+ const { slug } = await params;
+ const page = source.getPage(slug.slice(0, -1));
+ if (!page) notFound();
+
+ return generateOGImage({
+ title: page.data.title,
+ description: page.data.description,
+ site: appName,
+ });
+}
+
+export function generateStaticParams() {
+ return source.getPages().map((page) => ({
+ lang: page.locale,
+ slug: getPageImageUrl(page).segments,
+ }));
+}
diff --git a/apps/docs/components/mdx.tsx b/apps/docs/components/mdx.tsx
new file mode 100644
index 000000000..a154b4f33
--- /dev/null
+++ b/apps/docs/components/mdx.tsx
@@ -0,0 +1,15 @@
+import defaultMdxComponents from "fumadocs-ui/mdx";
+import type { MDXComponents } from "mdx/types";
+
+export function getMDXComponents(components?: MDXComponents) {
+ return {
+ ...defaultMdxComponents,
+ ...components,
+ } satisfies MDXComponents;
+}
+
+export const useMDXComponents = getMDXComponents;
+
+declare global {
+ type MDXProvidedComponents = ReturnType;
+}
diff --git a/apps/docs/components/provider.tsx b/apps/docs/components/provider.tsx
new file mode 100644
index 000000000..3ae060d5c
--- /dev/null
+++ b/apps/docs/components/provider.tsx
@@ -0,0 +1,8 @@
+"use client";
+import SearchDialog from "@/components/search";
+import { RootProvider } from "fumadocs-ui/provider/next";
+import { type ReactNode } from "react";
+
+export function Provider({ children }: { children: ReactNode }) {
+ return {children} ;
+}
diff --git a/apps/docs/components/search.tsx b/apps/docs/components/search.tsx
new file mode 100644
index 000000000..03f92d0ec
--- /dev/null
+++ b/apps/docs/components/search.tsx
@@ -0,0 +1,35 @@
+"use client";
+import {
+ SearchDialog,
+ SearchDialogClose,
+ SearchDialogContent,
+ SearchDialogHeader,
+ SearchDialogIcon,
+ SearchDialogInput,
+ SearchDialogList,
+ SearchDialogOverlay,
+ type SharedProps,
+} from "fumadocs-ui/components/dialog/search";
+import { useStaticSearch } from "fumadocs-core/search/client";
+import { useI18n } from "fumadocs-ui/contexts/i18n";
+
+export default function DefaultSearchDialog(props: SharedProps) {
+ const { locale } = useI18n(); // (optional) for i18n
+ const search = useStaticSearch({
+ locale,
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/docs/content/docs/administration.mdx b/apps/docs/content/docs/administration.mdx
new file mode 100644
index 000000000..e211d2a3d
--- /dev/null
+++ b/apps/docs/content/docs/administration.mdx
@@ -0,0 +1,20 @@
+---
+title: "Administration"
+description: "Bootstrap an owner explicitly, then manage access through the console."
+---
+
+Creating an account does not grant organizer access. `db:seed` creates roles but never automatically assigns an owner.
+
+For a real installation, create the intended account, verify its canonical Core user ID, and use a controlled administrative database operation to assign the seeded `core.owner` role to that ID. Keep this operation outside public application routes. The template README describes this bootstrap boundary.
+
+Once bootstrapped, an owner can open `/admin`, inspect users, manage roles and settings, and export participant data. Full also provides event administration, check-in, and scanner pages.
+
+## Registration policy
+
+Settings control whether registration is open, whether approval is required, registration limits, and event capacity. Guards route incomplete accounts back to onboarding. Approval-pending and suspended accounts have dedicated states. Core checks these policies on the server.
+
+Use a separate participant account to confirm permissions after changing roles. Hiding an admin navigation link does not replace permission checks.
+
+## Demo access
+
+The public demo seeds a fictional organizer through an explicit database command. This is a demo-specific bootstrap operation. It does not add automatic owner assignment to either template.
diff --git a/apps/docs/content/docs/architecture.mdx b/apps/docs/content/docs/architecture.mdx
new file mode 100644
index 000000000..5a796da11
--- /dev/null
+++ b/apps/docs/content/docs/architecture.mdx
@@ -0,0 +1,27 @@
+---
+title: "Architecture"
+description: "Core owns rules. Applications own presentation and deployment."
+---
+
+The repository separates libraries, runnable examples, integration tests, and deployed applications.
+
+| Directory | Responsibility |
+| ------------------- | ------------------------------------------------------------------------------- |
+| `packages/core` | Domain rules, permissions, native entities, Better Auth mapping, HTTP contracts |
+| `packages/next` | Next.js request context, handlers, guards, runtime integration |
+| `packages/ui` | Reusable React forms and views |
+| `packages/plugin-*` | Optional domain features and their contracts |
+| `templates` | Runnable minimal and full workspace examples |
+| `e2e` | Real database, production HTTP, and browser checks |
+| `apps/demo` | Public demonstration on Workers |
+| `apps/docs` | This Fumadocs site |
+
+## Request lifecycle
+
+The application initializes shared database connections and authentication once. Each execution creates a scoped entity manager and HackKit instance. Authentication identifies the canonical Core user. Core APIs enforce permissions and policy. HTTP handlers derive the actor from the session, rather than accepting a privileged actor supplied by a browser.
+
+The Next integration binds this runtime to route handlers and server-rendered pages. Browser code uses the typed HackKit HTTP client. Do not import a database driver, server runtime, or secret-bearing config into a client component.
+
+## Data ownership
+
+A Better Auth user ID is the Core user ID. Roles grant explicit permissions. A team is owned by its plugin; Core does not require Teams to register a participant. Adding a plugin can change the application registry and therefore its migrations.
diff --git a/apps/docs/content/docs/configuration.mdx b/apps/docs/content/docs/configuration.mdx
new file mode 100644
index 000000000..d3a55f3ef
--- /dev/null
+++ b/apps/docs/content/docs/configuration.mdx
@@ -0,0 +1,22 @@
+---
+title: "Configuration"
+description: "Keep event configuration and credentials inside the application."
+---
+
+`hackkit.config.ts` declares the database driver, Better Auth options, seed roles, blob adapter, registration options, event types, and plugins. The application's `env.ts` validates environment variables before the runtime starts.
+
+## Minimal
+
+Local defaults use SQLite and local uploads. In production, set an explicit application URL and a random `BETTER_AUTH_SECRET` of at least 32 characters. SQLite and uploads require persistent disk storage. An ephemeral serverless filesystem will lose them.
+
+## Full
+
+The full example keeps stricter production requirements: an explicit application URL and authentication secret, S3 configuration, and the Discord bot integration settings. Its `.env.example` separates local defaults, required production variables, and optional integrations.
+
+Email defaults to no external delivery. Enable Resend or SMTP only when you have configured that provider. OAuth credentials must be provided as matching client ID and secret pairs.
+
+## Secrets
+
+Use each application's `.env.example` as the variable reference. Keep actual credentials in ignored local files or the hosting provider's secret storage. Never put secrets in `NEXT_PUBLIC_*` variables; those values can reach the browser.
+
+Restart or redeploy after changing configuration. Do not copy a developer database or uploads into a demo deployment.
diff --git a/apps/docs/content/docs/database.mdx b/apps/docs/content/docs/database.mdx
new file mode 100644
index 000000000..5025c6868
--- /dev/null
+++ b/apps/docs/content/docs/database.mdx
@@ -0,0 +1,37 @@
+---
+title: "Database operations"
+description: "Use reviewed migrations and explicit administrative commands."
+---
+
+Core uses MikroORM's native entity registry. Migration files and snapshots belong to the application because its plugin registry determines its schema.
+
+## First setup
+
+Templates ship without migrations or snapshots. Configure an empty development database and select the plugins before running the selected application's `db:generate --name initial`. Review and apply the generated migration, seed roles, then commit the migration and snapshot to your application repository.
+
+Run initial generation once for a new project. Later clones and deployments apply its committed history. Existing applications, including the demo, keep their history. Initial generation does not replace an upgrade or data migration.
+
+## Routine commands
+
+From the repository root, `corepack pnpm db:migrate` and `corepack pnpm db:seed` target full. Seed creates configured roles and does not assign an owner.
+
+For minimal, select its package explicitly:
+
+```sh
+corepack pnpm --filter @hackkit/template-nextjs-minimal db:migrate
+corepack pnpm --filter @hackkit/template-nextjs-minimal db:seed
+corepack pnpm --filter @hackkit/template-nextjs-minimal db:status
+corepack pnpm --filter @hackkit/template-nextjs-minimal db:check
+```
+
+`db:status` reports executed and pending migrations. `db:check` verifies migration history, entity/snapshot agreement, and live schema drift.
+
+## Change the schema
+
+After changing registered entities, run `db:generate` in the selected application. Review every generated statement and the snapshot before committing. Test the upgrade against existing data as well as a fresh database.
+
+`db:rollback` rolls back the most recent migration. Review the down migration and take a backup first. `db:reset` drops local SQLite data and is restricted to development and test environments; it is not a production recovery tool.
+
+## Drivers
+
+Full supports SQLite, libSQL, PostgreSQL, and MySQL. Integration coverage includes both local and HTTP libSQL. Minimal intentionally uses SQLite. Each application generates and maintains the history for its own selected database and plugins. `HACKKIT_MIGRATIONS_PATH` optionally overrides the default directory. Do not copy full's plugin tables into minimal.
diff --git a/apps/docs/content/docs/demo.mdx b/apps/docs/content/docs/demo.mdx
new file mode 100644
index 000000000..46f75985a
--- /dev/null
+++ b/apps/docs/content/docs/demo.mdx
@@ -0,0 +1,32 @@
+---
+title: "Interactive demo"
+description: "Explore HackKit with fictional accounts and shared sample data."
+---
+
+[Open the live demo](https://hackkit-demo.acm-utsa.workers.dev).
+
+The application lives in `apps/demo`. It uses the same Core, Next integration, UI, and Teams packages as the full workspace example. Vinext runs it on Cloudflare Workers, with Turso for application data and private R2 storage for uploads.
+
+The launcher offers a registered participant and an organizer. **Try registration** creates a new fictional account for onboarding. The organizer can inspect users, roles, settings, and events. Seeded fictional people and schedule entries make these screens useful immediately.
+
+## Local demo
+
+Copy `apps/demo/.dev.vars.example` to `apps/demo/.dev.vars`. Supply your demo Turso URL, Turso token, and an authentication secret of at least 32 characters. Keep the local application URL as `http://localhost:3001`.
+
+Build workspace libraries, then run the demo's explicit database setup:
+
+```sh
+corepack pnpm exec turbo run build --filter=@hackkit/demo^...
+corepack pnpm --filter @hackkit/demo plugin:sync
+corepack pnpm --filter @hackkit/demo db:migrate
+corepack pnpm --filter @hackkit/demo db:demo
+corepack pnpm dev:demo
+```
+
+Open [localhost:3001](http://localhost:3001). Workerd uses the configured Turso database and local R2 emulation. Use a separate development database when you need isolated changes. Database setup never runs inside a request.
+
+## Hosted behavior
+
+The demo shares persistent data between visitors. Changes to sample accounts, teams, and settings are visible to other visitors. Use fictional information only. Demo account passwords are public by design. Email delivery, OAuth, and Discord synchronization are disabled.
+
+Uploads pass through authenticated application routes to a private R2 bucket. Resume access retains HackKit's owner and organizer permission checks. Profile photos can be viewed publicly.
diff --git a/apps/docs/content/docs/deployment.mdx b/apps/docs/content/docs/deployment.mdx
new file mode 100644
index 000000000..9b76d2015
--- /dev/null
+++ b/apps/docs/content/docs/deployment.mdx
@@ -0,0 +1,37 @@
+---
+title: "Deployment"
+description: "Deploy the documentation and interactive demo to Cloudflare."
+---
+
+## Account selection
+
+Run Wrangler's `whoami` command in the application directory and verify the intended ACM account before publishing. If you belong to several accounts, set `CLOUDFLARE_ACCOUNT_ID` explicitly. Do not deploy these applications into a personal account accidentally.
+
+## Documentation
+
+`apps/docs` uses Fumadocs MDX, local search, and Next.js static export. It needs no database, secrets, or Worker runtime adapter.
+
+```sh
+corepack pnpm deploy:docs
+```
+
+Wrangler uploads `apps/docs/out` as Worker static assets. `apps/docs/wrangler.jsonc` owns its Worker name and routing configuration. Custom domains can be added once their ACM zone is selected.
+
+## Demo
+
+The demo runs directly on Cloudflare Workers through Vinext. It uses Turso's HTTP client and a private R2 binding. MikroORM entity functions are compiled during the build because Workers prohibit runtime code generation.
+
+Put the Turso URL, Turso token, and authentication secret in the ignored `apps/demo/.dev.vars` file for local setup and database commands. See `apps/demo/.dev.vars.example` for required names. Migrate explicitly using `db:migrate`, then run `db:demo` to populate an empty demo database with fictional accounts. Existing users are retained.
+
+For deployment, configure `TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`, and `BETTER_AUTH_SECRET` as Worker secrets. Use Wrangler's interactive `secret put` commands or the Cloudflare dashboard. Set `vars.BETTER_AUTH_URL` in `apps/demo/wrangler.jsonc` to the public HTTPS origin. Keep the local URL out of deployed secrets.
+
+The `DEMO_UPLOADS` R2 binding targets `hackkit-demo-uploads`. It requires no S3 credentials or public bucket access. Create the bucket before the first deployment if deploying to another account.
+
+```sh
+corepack pnpm exec turbo run build --filter=@hackkit/demo^...
+corepack pnpm deploy:demo
+```
+
+The hosted demo shares persistent Turso data and R2 uploads. Its sample organizer credentials are public. Use fictional information only. Do not connect a real event database to this demonstration.
+
+Run the selected application's `deploy:check` script after building to inspect packaging without publishing. Verify the launcher, participant and organizer access, onboarding, and upload permissions on the hosted URL.
diff --git a/apps/docs/content/docs/getting-started.mdx b/apps/docs/content/docs/getting-started.mdx
new file mode 100644
index 000000000..ed2fb0a7a
--- /dev/null
+++ b/apps/docs/content/docs/getting-started.mdx
@@ -0,0 +1,41 @@
+---
+title: "Getting started"
+description: "Run the minimal workspace example with SQLite and local uploads."
+---
+
+## Prerequisites
+
+Use Node.js 22.17 or newer and the repository-pinned pnpm 12.15.0 through Corepack. Start from the repository root.
+
+```sh
+corepack enable
+corepack pnpm install
+corepack pnpm exec turbo run build --filter='./packages/*'
+```
+
+## Configure the minimal template
+
+```sh
+cp templates/nextjs-minimal/.env.example templates/nextjs-minimal/.env
+corepack pnpm --filter @hackkit/template-nextjs-minimal plugin:sync
+corepack pnpm --filter @hackkit/template-nextjs-minimal db:generate --name initial
+corepack pnpm --filter @hackkit/template-nextjs-minimal db:migrate
+corepack pnpm --filter @hackkit/template-nextjs-minimal db:seed
+corepack pnpm dev:minimal
+```
+
+Review the generated migration before applying it. Commit the migration and snapshot to your application repository. Templates ship without migration history. Generate the initial baseline only for a new project; later clones apply the existing history.
+
+Open [localhost:3000](http://localhost:3000). Create an account and complete HackTag, user data, and hacker registration. No cloud credentials are needed for local development.
+
+The committed `.env.example` documents the variables. The local `.env` is empty until you configure it and is ignored by Git.
+
+## Run the full template
+
+Repeat the setup using `templates/nextjs-full`, the package filter `@hackkit/template-nextjs-full`, and `corepack pnpm dev:full`. Run one template at a time on port 3000.
+
+Root `db:*` commands target the full template. Use an explicit package filter when working with minimal. Each template stores its own SQLite database and uploads in its own `.data` directory.
+
+## Next steps
+
+Read [configuration](/docs/configuration), [database operations](/docs/database), and [owner access](/docs/administration). New accounts never become owners automatically.
diff --git a/apps/docs/content/docs/index.mdx b/apps/docs/content/docs/index.mdx
new file mode 100644
index 000000000..b1ccd2227
--- /dev/null
+++ b/apps/docs/content/docs/index.mdx
@@ -0,0 +1,25 @@
+---
+title: "Introduction"
+description: "Hackathon software you can adapt to your event."
+---
+
+HackKit provides authentication, registration, participant profiles, permissions, event operations, and optional plugins. Applications own their pages and configuration. Core owns the domain rules and database model.
+
+Start with a runnable workspace example. Use **minimal** for Core registration and basic administration. Use **full** when you also want Teams, Discord, email adapters, schedules, RSVP, and event passes.
+
+
+
+ Install dependencies and start a local application.
+
+
+ Compare the two workspace examples.
+
+
+ Learn where configuration, permissions, and HTTP handlers belong.
+
+
+ Explore a fictional event as a participant or organizer.
+
+
+
+The packages are private workspace packages. A standalone installer and published package distribution are a separate milestone. There is no supported `hackkit init` command yet.
diff --git a/apps/docs/content/docs/meta.json b/apps/docs/content/docs/meta.json
new file mode 100644
index 000000000..545ca0448
--- /dev/null
+++ b/apps/docs/content/docs/meta.json
@@ -0,0 +1,16 @@
+{
+ "title": "Documentation",
+ "pages": [
+ "index",
+ "getting-started",
+ "templates",
+ "configuration",
+ "database",
+ "architecture",
+ "plugins",
+ "administration",
+ "testing",
+ "demo",
+ "deployment"
+ ]
+}
diff --git a/apps/docs/content/docs/plugins.mdx b/apps/docs/content/docs/plugins.mdx
new file mode 100644
index 000000000..a9eba28a2
--- /dev/null
+++ b/apps/docs/content/docs/plugins.mdx
@@ -0,0 +1,30 @@
+---
+title: "Plugins"
+description: "Enable optional features through the application registry."
+---
+
+Full demonstrates the Teams, Discord, and email notification plugins. Minimal has an empty plugin registry.
+
+## Synchronize after configuration changes
+
+```sh
+corepack pnpm --filter @hackkit/template-nextjs-full plugin:sync
+```
+
+Synchronization updates the application-owned generated plugin files and lock information. Review those changes. Schema changes also require reviewed migrations; synchronization does not replace migration generation or execution.
+
+## Teams
+
+Participants can create teams, invite another registered participant by HackTag, and accept invitations. The plugin enforces membership rules through its APIs and typed HTTP endpoints.
+
+## Discord
+
+The Discord plugin supports verification and role synchronization. The full production example requires its bot configuration. A local or demo application can omit the provider, but must describe that limitation in its UI.
+
+## Email notifications
+
+The notification plugin queues local domain notifications and can deliver through configured providers. A missing provider must not be described as successful external delivery. Tests keep provider operations local and never send real email.
+
+## Client boundaries
+
+Import a plugin's client contract for browser calls. Keep providers, entities, and runtime setup in server code. Integration checks verify that browser bundles exclude MikroORM and other server-only dependencies.
diff --git a/apps/docs/content/docs/templates.mdx b/apps/docs/content/docs/templates.mdx
new file mode 100644
index 000000000..46b192781
--- /dev/null
+++ b/apps/docs/content/docs/templates.mdx
@@ -0,0 +1,23 @@
+---
+title: "Templates"
+description: "Choose a starting point without changing the shared libraries."
+---
+
+| Capability | Minimal | Full |
+| ----------------------------------------- | ------- | ----------- |
+| Authentication and onboarding | Yes | Yes |
+| Dashboard, profiles, registration editing | Yes | Yes |
+| Users, roles, settings, CSV export | Yes | Yes |
+| Local SQLite and file storage | Yes | Development |
+| Teams and invitations | No | Yes |
+| Discord and email adapters | No | Yes |
+| Schedule, RSVP, passes, scanners | No | Yes |
+| Production S3 adapter | No | Yes |
+
+The examples live at `templates/nextjs-minimal` and `templates/nextjs-full`. Each provides pages, configuration, and database scripts. A new application generates its own initial migration and snapshot after selecting a database and plugins, then commits and maintains that history. Templates ship without pre-generated migrations. Neither imports the other or E2E support.
+
+Minimal registers no plugins. It seeds participant and owner roles with Core permissions. Full registers Teams, Discord, and email notifications, with provider choices in its configuration.
+
+Reuse `@hackkit/ui` components when adapting a template. Keep event-specific copy and navigation in the application. Plugins contribute their declared schemas and HTTP contracts through the registry.
+
+Both examples remain part of this workspace. Copying a folder outside the monorepo is not yet a supported installation flow.
diff --git a/apps/docs/content/docs/testing.mdx b/apps/docs/content/docs/testing.mdx
new file mode 100644
index 000000000..d5b6ac8d9
--- /dev/null
+++ b/apps/docs/content/docs/testing.mdx
@@ -0,0 +1,28 @@
+---
+title: "Testing"
+description: "Run package checks and integration suites against actual templates."
+---
+
+## Package checks
+
+```sh
+corepack pnpm test
+corepack pnpm typecheck
+```
+
+Focused tests live beside the libraries. Repository integration tests live in `e2e`, which runs the actual templates rather than maintaining a separate test application.
+
+## End-to-end checks
+
+```sh
+corepack pnpm --filter @hackkit/e2e exec playwright install chromium
+corepack pnpm test:e2e
+```
+
+The runner builds libraries, synchronizes plugins, checks generated-file drift, typechecks, generates temporary migration histories, prepares and checks disposable build databases, and builds both templates once. Runtime fixtures use fresh databases and uploads. They do not reuse developer `.env` values or databases.
+
+Use `test:e2e:db`, `test:e2e:http`, or `test:e2e:browser` for a selected suite. Browser and HTTP checks use one Playwright worker, no automatic retries, and ports 33017 and 33018. An occupied port fails instead of attaching to another server.
+
+Database checks cover SQLite, local libSQL, PostgreSQL, MySQL, and HTTP libSQL. Unavailable external targets may skip locally; CI requires the complete matrix. Browser journeys cover onboarding, persistent accounts, redirects, approval, permissions, and organizer access. Full also exercises team invitations across sessions.
+
+The public demo has a separate smoke test for its launcher, seeded roles, schedule, and onboarding. It is not a replacement for template integration tests.
diff --git a/apps/docs/lib/cn.ts b/apps/docs/lib/cn.ts
new file mode 100644
index 000000000..fe0d16987
--- /dev/null
+++ b/apps/docs/lib/cn.ts
@@ -0,0 +1 @@
+export { cn } from "cn";
diff --git a/apps/docs/lib/layout.shared.tsx b/apps/docs/lib/layout.shared.tsx
new file mode 100644
index 000000000..dc0b01328
--- /dev/null
+++ b/apps/docs/lib/layout.shared.tsx
@@ -0,0 +1,12 @@
+import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
+import { appName, gitConfig } from "./shared";
+
+export function baseOptions(): BaseLayoutProps {
+ return {
+ nav: {
+ // JSX supported
+ title: appName,
+ },
+ githubUrl: `https://github.com/${gitConfig.user}/${gitConfig.repo}`,
+ };
+}
diff --git a/apps/docs/lib/shared.ts b/apps/docs/lib/shared.ts
new file mode 100644
index 000000000..a8532ebbb
--- /dev/null
+++ b/apps/docs/lib/shared.ts
@@ -0,0 +1,29 @@
+import { createGetUrl } from "fumadocs-core/source";
+
+export const appName = "HackKit";
+export const docsRoute = "/docs";
+export const docsImageRoute = "/og/docs";
+export const docsContentRoute = "/llms.mdx/docs";
+
+// fill this with your actual GitHub info, for example:
+export const gitConfig = {
+ user: "acmutsa",
+ repo: "HackKitPlugin",
+ branch: "dev",
+};
+
+const getContentUrl = createGetUrl(docsContentRoute);
+
+export function getPageMarkdownUrl(page: { slugs: string[]; locale?: string }) {
+ const segments = [...page.slugs, "content.md"];
+
+ return { segments, url: getContentUrl(segments, page.locale) };
+}
+
+const getImageUrl = createGetUrl(docsImageRoute);
+
+export function getPageImageUrl(page: { slugs: string[]; locale?: string }) {
+ const segments = [...page.slugs, "image.png"];
+
+ return { segments, url: getImageUrl(segments, page.locale) };
+}
diff --git a/apps/docs/lib/source.ts b/apps/docs/lib/source.ts
new file mode 100644
index 000000000..08932db6e
--- /dev/null
+++ b/apps/docs/lib/source.ts
@@ -0,0 +1,30 @@
+import { llms, loader } from "fumadocs-core/source";
+import { docsContentRoute, docsImageRoute, docsRoute } from "./shared";
+import { defineDocs } from "fumadocs-mdx/macro";
+import { metaSchema, pageSchema } from "fumadocs-core/source/schema";
+
+const docs = defineDocs({
+ dir: "content/docs",
+ docs: {
+ schema: pageSchema,
+ postprocess: {
+ includeProcessedMarkdown: true,
+ },
+ },
+ meta: {
+ schema: metaSchema,
+ },
+});
+
+// See https://fumadocs.dev/docs/headless/source-api for more info
+export const source = loader({
+ baseUrl: docsRoute,
+ source: docs.toFumadocsSource(),
+ plugins: [],
+});
+
+export const docsLlms = llms(source, {
+ renderPage: async (page) => `# ${page.data.title} (${page.url})
+
+${await page.data.getText("processed")}`,
+});
diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs
new file mode 100644
index 000000000..9ac496d5b
--- /dev/null
+++ b/apps/docs/next.config.mjs
@@ -0,0 +1,11 @@
+import { createMDX } from "fumadocs-mdx/next";
+
+const withMDX = createMDX();
+
+/** @type {import('next').NextConfig} */
+const config = {
+ output: "export",
+ reactStrictMode: true,
+};
+
+export default withMDX(config);
diff --git a/apps/docs/package.json b/apps/docs/package.json
new file mode 100644
index 000000000..4c6848ef7
--- /dev/null
+++ b/apps/docs/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "@hackkit/docs",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "build": "next build",
+ "dev": "next dev -p 3002",
+ "start": "serve out",
+ "typecheck": "next typegen && tsc --noEmit",
+ "deploy": "pnpm build && wrangler deploy",
+ "deploy:check": "wrangler deploy --dry-run"
+ },
+ "dependencies": {
+ "cn": "^0.5.0",
+ "fumadocs-core": "16.17.7",
+ "fumadocs-mdx": "15.4.9",
+ "fumadocs-ui": "npm:@fumadocs/base-ui@16.17.7",
+ "lucide-react": "^1.59.0",
+ "next": "16.4.2",
+ "react": "^19.3.1",
+ "react-dom": "^19.3.1"
+ },
+ "devDependencies": {
+ "@tailwindcss/postcss": "^4.3.3",
+ "@types/mdx": "^2.0.14",
+ "@types/node": "^26.6.5",
+ "@types/react": "^19.3.0",
+ "@types/react-dom": "^19.3.0",
+ "postcss": "^8.5.31",
+ "serve": "^14.2.6",
+ "tailwindcss": "^4.3.3",
+ "typescript": "^7.0.2",
+ "wrangler": "4.151.3"
+ }
+}
diff --git a/apps/docs/postcss.config.mjs b/apps/docs/postcss.config.mjs
new file mode 100644
index 000000000..c42f31cab
--- /dev/null
+++ b/apps/docs/postcss.config.mjs
@@ -0,0 +1,7 @@
+const config = {
+ plugins: {
+ "@tailwindcss/postcss": {},
+ },
+};
+
+export default config;
diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json
new file mode 100644
index 000000000..67086f3f1
--- /dev/null
+++ b/apps/docs/tsconfig.json
@@ -0,0 +1,34 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "paths": {
+ "@/*": ["./*"]
+ },
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts"
+ ],
+ "exclude": ["node_modules"]
+}
diff --git a/apps/docs/wrangler.jsonc b/apps/docs/wrangler.jsonc
new file mode 100644
index 000000000..0bac4db30
--- /dev/null
+++ b/apps/docs/wrangler.jsonc
@@ -0,0 +1,12 @@
+{
+ "$schema": "node_modules/wrangler/config-schema.json",
+ "name": "hackkit-docs",
+ "account_id": "cdc7630e53b468f56a4453af71a58ade",
+ "compatibility_date": "2026-10-20",
+ "workers_dev": true,
+ "assets": {
+ "directory": "./out",
+ "html_handling": "auto-trailing-slash",
+ "not_found_handling": "404-page",
+ },
+}
diff --git a/apps/web/README.md b/apps/web/README.md
deleted file mode 100644
index 6d1ace8d7..000000000
--- a/apps/web/README.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# HackKit reference web app
-
-Next.js app using MikroORM, Core-owned Better Auth, HackKit UI, Teams, Discord verification, and notifications. This migration targets a fresh database. Existing databases and user accounts are not converted.
-
-## Local setup
-
-Use Node.js 22.17 or newer and pnpm 8.3.1. Run these commands from the repository root:
-
-1. Install dependencies with `pnpm install`.
-2. Build workspace packages with `pnpm exec turbo run build --filter=web^...`.
-3. Sync plugin routes with `pnpm --filter web sync`.
-4. Apply committed migrations with `pnpm --filter web db:migrate`.
-5. Insert configured roles with `pnpm --filter web db:seed`.
-6. Start Next.js with `pnpm --filter web dev`.
-
-Development defaults use `http://localhost:3000`, SQLite at `apps/web/.data/web.db`, and local blob storage. OAuth, email, and Discord providers are optional locally. The runtime does not migrate or seed on startup. Plugin sync only updates routes and `hackkit.lock`.
-
-After signup, bootstrap an owner explicitly by assigning `core.owner` to that user's `role_id` in `core_user`, selected by `id`. Better Auth's `user.id` is the canonical ID. The runtime does not infer ownership from email.
-
-`pnpm --filter web db:reset` drops registered tables and migration history in the selected local SQLite database, then migrates and seeds. It refuses production and non-SQLite drivers. Never use it for data you need to retain.
-
-## Database selection
-
-| Driver | DATABASE_URL | HACKKIT_DATABASE_DIALECT |
-| ---------------------- | ------------------------------------------ | ---------------------------------- |
-| SQLite | `file:.data/web.db` | `sqlite` (default for local paths) |
-| local libSQL | `file:.data/web.db` | `libsql` (explicit) |
-| network libSQL / Turso | `libsql://...` or `https://...` | `libsql` (inferred) |
-| PostgreSQL | `postgresql://user:password@host/database` | `postgresql` (inferred) |
-| MySQL | `mysql://user:password@host/database` | `mysql` (inferred) |
-
-Set `TURSO_AUTH_TOKEN` when the libSQL endpoint requires authentication. Driver options live in [lib/database-config.ts](lib/database-config.ts).
-
-## Entity and migration workflow
-
-Core, Better Auth, installed plugins (including disabled plugins), and application entities form one native MikroORM registry. Add app-owned `defineEntity` definitions through `entities` in `hackkit.config.ts`; plugins expose an `entities` array. Runtime and app migration scripts use the same registry. Auth plugins requiring extra tables or fields must declare them before initialization; undeclared schema fails early.
-
-Migrations and snapshots are committed under `db/migrations/postgresql`, `db/migrations/mysql`, and `db/migrations/sqlite`. libSQL uses the SQLite chain. After changing entities:
-
-1. Select a disposable development database for the dialect using the variables above.
-2. Run `pnpm --filter web db:generate --name describe-change`.
-3. Review the generated TypeScript migration and snapshot. Repeat generation for the other dialects.
-4. Apply with `pnpm --filter web db:migrate` and validate against fresh databases.
-5. Commit every dialect's reviewed migration and snapshot.
-
-Set `enabled: false` on a registered plugin to disable behavior while keeping its schema and data. Removing it can generate table drops. Review data retention before applying them. `db:seed` only inserts missing configured role IDs; it does not update existing roles or assign them to users.
-
-The database commands now use application-owned utility scripts, independently of the CLI. Use `db:status`, `db:check`, staged `db:migrate --to`, `db:rollback`, and `db:generate --blank` for upgrades. See [the migration guide](../../docs/guides/database-migrations.md) for exact commands, data transformations, MySQL recovery, and plugin retention.
-
-## Authentication and request scope
-
-[lib/auth-options.ts](lib/auth-options.ts) supplies secrets, origins, and OAuth providers. Core owns Better Auth construction, native entities, and the pinned community adapter. Better Auth identity and HackKit profile fields share the canonical `core_user` row.
-
-[lib/runtime.ts](lib/runtime.ts) initializes shared connections and registers a function that creates request-scoped domain APIs. Next owns cookies, headers, guards, and redirects. Browser mutations use the package-owned HTTP handler and return JSON DTOs. Browser code uses `@hackkit/core/client`; it does not import the ORM.
-
-## Production configuration
-
-Set explicit `DATABASE_URL`, `NEXT_PUBLIC_APP_URL`, `BETTER_AUTH_URL`, and `BETTER_AUTH_SECRET` (at least 32 characters). Configure `BETTER_AUTH_TRUSTED_ORIGINS` as a comma-separated list when needed. The app's production checks also require:
-
-- `HACKKIT_BLOB_ADAPTER=s3`, bucket, region, access key, and secret key; set `HACKKIT_S3_ENDPOINT` for compatible stores.
-- `DISCORD_GUILD_ID`, `DISCORD_BOT_API_URL`, `DISCORD_INTERNAL_AUTH_KEY`, and `DISCORD_PARTICIPANT_ROLE_ID` (or role name).
-- Optional email through `HACKKIT_EMAIL_PROVIDER=resend` plus `RESEND_API_KEY`, or `smtp` plus SMTP settings.
-
-See [env.ts](env.ts) for exact variable names. Database storage must persist across application restarts. Apply migrations and seed as explicit release steps. Builds must have valid configuration but do not apply schema changes.
-
-## Validation
-
-Build dependencies before tests. Run `pnpm --filter web test` for committed migrations, auth, and existing-data upgrade/replay checks with SQLite/local libSQL. `pnpm --filter web test:db-workflow` verifies that sync does not connect and reset affects only its selected file. `pnpm --filter web verify` syncs generated files, typechecks, and builds Next.js. After building, `pnpm --filter web test:runtime` starts the production server on loopback port 33017 with an isolated temporary SQLite database, verifies HTTP auth and access control, then stops the server and removes its test data.
-
-`pnpm --filter web test:db-matrix` always runs SQLite and local libSQL. For the complete matrix, supply URLs for **empty, disposable** databases:
-
-- `HACKKIT_TEST_POSTGRESQL_URL`
-- `HACKKIT_TEST_MYSQL_URL`
-- `HACKKIT_TEST_LIBSQL_URL` (a real HTTP/libSQL server)
-- `HACKKIT_REQUIRE_DATABASE_MATRIX=1` to fail if any URL is missing.
-
-The matrix writes test accounts and domain records; it never drops the target database. Use fresh databases for every run. CI requires all five targets, checks schema agreement and existing-data upgrades, runs package tests, typechecks, and builds Next.js. External OAuth, hosted Turso credentials/TLS, and real email/Discord delivery require deployment-specific validation.
-
-## Architecture
-
-- [Next integration guide](../../docs/guides/next-integration.md)
-- [MikroORM and Core auth decision](../../docs/adr/0013-mikroorm-and-core-auth.md)
-- [hackkit.config.ts](hackkit.config.ts): plugins, database, auth, settings, and seed roles.
-- [db/migrations](db/migrations): reviewed app-owned migrations.
-
-The UI provider receives a typed better-call path client created at module scope in `app/providers.tsx`. Plugin components bind their endpoint types using the provider's HTTP settings. `hackkit plugin sync` installs page reexports and updates `hackkit.lock`; it generates no client metadata. The single `/api/hackkit/[...path]` route forwards POST to the host handler. No app-level action wrappers or action maps are needed.
diff --git a/apps/web/db/migrations/mysql/.snapshot.json b/apps/web/db/migrations/mysql/.snapshot.json
deleted file mode 100644
index 55491d32b..000000000
--- a/apps/web/db/migrations/mysql/.snapshot.json
+++ /dev/null
@@ -1,4483 +0,0 @@
-{
- "namespaces": [],
- "tables": [
- {
- "name": "account",
- "columns": {
- "access_token": {
- "name": "access_token",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "access_token_expires_at": {
- "name": "access_token_expires_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "account_id": {
- "name": "account_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id_token": {
- "name": "id_token",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "password": {
- "name": "password",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "provider_id": {
- "name": "provider_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "refresh_token": {
- "name": "refresh_token",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "refresh_token_expires_at": {
- "name": "refresh_token_expires_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "scope": {
- "name": "scope",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "user_id": {
- "name": "user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "account_user_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "account_user_id_foreign": {
- "columnNames": [
- "user_id"
- ],
- "constraintName": "account_user_id_foreign",
- "localTableName": "account",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "core_event",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "description": {
- "name": "description",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "end_time": {
- "name": "end_time",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "hidden": {
- "name": "hidden",
- "type": "tinyint(1)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "false",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "host": {
- "name": "host",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "location": {
- "name": "location",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": "'TBD'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "start_time": {
- "name": "start_time",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "title": {
- "name": "title",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "type": {
- "name": "type",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "hidden"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_hidden_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "start_time"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_start_time_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "type"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_type_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- },
- {
- "name": "core_event_scan",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "event_id": {
- "name": "event_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "scanned_at": {
- "name": "scanned_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "scanned_by_auth_id": {
- "name": "scanned_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_scan_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "event_id",
- "auth_id"
- ],
- "composite": true,
- "constraint": false,
- "keyName": "core_event_scan_event_id_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "event_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_scan_event_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "scanned_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_scan_scanned_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "scanned_by_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_scan_scanned_by_auth_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_event_scan_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_event_scan_auth_id_foreign",
- "localTableName": "core_event_scan",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- },
- "core_event_scan_event_id_foreign": {
- "columnNames": [
- "event_id"
- ],
- "constraintName": "core_event_scan_event_id_foreign",
- "localTableName": "core_event_scan",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_event",
- "deleteRule": "cascade"
- },
- "core_event_scan_scanned_by_auth_id_foreign": {
- "columnNames": [
- "scanned_by_auth_id"
- ],
- "constraintName": "core_event_scan_scanned_by_auth_id_foreign",
- "localTableName": "core_event_scan",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user"
- }
- },
- "comment": null
- },
- {
- "name": "core_hacker",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "github_url": {
- "name": "github_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "group": {
- "name": "group",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "hackathons_attended": {
- "name": "hackathons_attended",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "heard_from": {
- "name": "heard_from",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "level_of_study": {
- "name": "level_of_study",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "linked_in_url": {
- "name": "linked_in_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "major": {
- "name": "major",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "personal_website_url": {
- "name": "personal_website_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "registered_at": {
- "name": "registered_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "resume_url": {
- "name": "resume_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "school_id": {
- "name": "school_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "software_experience": {
- "name": "software_experience",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "university": {
- "name": "university",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_hacker_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "registered_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_hacker_registered_at_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_hacker_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_hacker_auth_id_foreign",
- "localTableName": "core_hacker",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "core_notification_delivery_attempt",
- "columns": {
- "attempted_at": {
- "name": "attempted_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "channel": {
- "name": "channel",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "error": {
- "name": "error",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "external_id": {
- "name": "external_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "intent_id": {
- "name": "intent_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "metadata": {
- "name": "metadata",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "provider": {
- "name": "provider",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "recipient": {
- "name": "recipient",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "enum('delivered','failed','skipped')",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [
- "delivered",
- "failed",
- "skipped"
- ],
- "mappedType": "enum"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "attempted_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_attempted_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "channel"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_channel_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "intent_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_intent_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_notification_delivery_attempt_intent_id_foreign": {
- "columnNames": [
- "intent_id"
- ],
- "constraintName": "core_notification_delivery_attempt_intent_id_foreign",
- "localTableName": "core_notification_delivery_attempt",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_notification_intent",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "core_notification_intent",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "idempotency_key": {
- "name": "idempotency_key",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "kind": {
- "name": "kind",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "payload": {
- "name": "payload",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "recipient_auth_id": {
- "name": "recipient_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "enum('pending','processing','delivered','failed','skipped')",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'pending'",
- "comment": null,
- "collation": null,
- "enumItems": [
- "pending",
- "processing",
- "delivered",
- "failed",
- "skipped"
- ],
- "mappedType": "enum"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "idempotency_key"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_notification_intent_idempotency_key_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "kind"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_kind_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "recipient_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_recipient_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_notification_intent_recipient_auth_id_foreign": {
- "columnNames": [
- "recipient_auth_id"
- ],
- "constraintName": "core_notification_intent_recipient_auth_id_foreign",
- "localTableName": "core_notification_intent",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_operation_lock",
- "columns": {
- "key": {
- "name": "key",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "token": {
- "name": "token",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "key"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- },
- {
- "name": "core_role",
- "columns": {
- "color": {
- "name": "color",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "name": {
- "name": "name",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "permissions": {
- "name": "permissions",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "position": {
- "name": "position",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "name"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_role_name_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "position"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_role_position_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- },
- {
- "name": "core_rsvp",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "cancelled_at": {
- "name": "cancelled_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "cancelled_by_auth_id": {
- "name": "cancelled_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "confirmed_at": {
- "name": "confirmed_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "promoted_at": {
- "name": "promoted_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "promoted_by_auth_id": {
- "name": "promoted_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "enum('confirmed','waitlisted','cancelled')",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [
- "confirmed",
- "waitlisted",
- "cancelled"
- ],
- "mappedType": "enum"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "waitlist_position": {
- "name": "waitlist_position",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "waitlisted_at": {
- "name": "waitlisted_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "cancelled_by_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_cancelled_by_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "promoted_by_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_promoted_by_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_status_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "updated_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_updated_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "waitlist_position"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_waitlist_position_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_rsvp_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_rsvp_auth_id_foreign",
- "localTableName": "core_rsvp",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- },
- "core_rsvp_cancelled_by_auth_id_foreign": {
- "columnNames": [
- "cancelled_by_auth_id"
- ],
- "constraintName": "core_rsvp_cancelled_by_auth_id_foreign",
- "localTableName": "core_rsvp",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "set null"
- },
- "core_rsvp_promoted_by_auth_id_foreign": {
- "columnNames": [
- "promoted_by_auth_id"
- ],
- "constraintName": "core_rsvp_promoted_by_auth_id_foreign",
- "localTableName": "core_rsvp",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_setting",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "created_by_auth_id": {
- "name": "created_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "key": {
- "name": "key",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "updated_by_auth_id": {
- "name": "updated_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "value": {
- "name": "value",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "key"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "created_by_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_setting_created_by_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "updated_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_setting_updated_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "updated_by_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_setting_updated_by_auth_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_setting_created_by_auth_id_foreign": {
- "columnNames": [
- "created_by_auth_id"
- ],
- "constraintName": "core_setting_created_by_auth_id_foreign",
- "localTableName": "core_setting",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "set null"
- },
- "core_setting_updated_by_auth_id_foreign": {
- "columnNames": [
- "updated_by_auth_id"
- ],
- "constraintName": "core_setting_updated_by_auth_id_foreign",
- "localTableName": "core_setting",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_user",
- "columns": {
- "bio": {
- "name": "bio",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "checked_in_at": {
- "name": "checked_in_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_display_handle": {
- "name": "discord_display_handle",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "email": {
- "name": "email",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "email_verified": {
- "name": "email_verified",
- "type": "tinyint(1)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "false",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "hack_tag": {
- "name": "hack_tag",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "is_approved": {
- "name": "is_approved",
- "type": "tinyint(1)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "false",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "is_profile_searchable": {
- "name": "is_profile_searchable",
- "type": "tinyint(1)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "true",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "name": {
- "name": "name",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "profile_photo_url": {
- "name": "profile_photo_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "pronouns": {
- "name": "pronouns",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "role_id": {
- "name": "role_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "skills": {
- "name": "skills",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "email"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_user_email_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "hack_tag"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_hack_tag_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "hack_tag"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_user_hack_tag_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "role_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_role_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_user_role_id_foreign": {
- "columnNames": [
- "role_id"
- ],
- "constraintName": "core_user_role_id_foreign",
- "localTableName": "core_user",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_role",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_user_ban",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "banned_by_auth_id": {
- "name": "banned_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "reason": {
- "name": "reason",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_ban_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "banned_by_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_ban_banned_by_auth_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_user_ban_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_user_ban_auth_id_foreign",
- "localTableName": "core_user_ban",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- },
- "core_user_ban_banned_by_auth_id_foreign": {
- "columnNames": [
- "banned_by_auth_id"
- ],
- "constraintName": "core_user_ban_banned_by_auth_id_foreign",
- "localTableName": "core_user_ban",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user"
- }
- },
- "comment": null
- },
- {
- "name": "core_user_data",
- "columns": {
- "accommodation_note": {
- "name": "accommodation_note",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "age": {
- "name": "age",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "completed_at": {
- "name": "completed_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "country_of_residence": {
- "name": "country_of_residence",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "dietary_restrictions": {
- "name": "dietary_restrictions",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "ethnicity": {
- "name": "ethnicity",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "gender": {
- "name": "gender",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "has_accepted_mlhcode_of_conduct": {
- "name": "has_accepted_mlhcode_of_conduct",
- "type": "tinyint(1)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "has_shared_data_with_mlh": {
- "name": "has_shared_data_with_mlh",
- "type": "tinyint(1)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "is_emailable": {
- "name": "is_emailable",
- "type": "tinyint(1)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "phone_number": {
- "name": "phone_number",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "race": {
- "name": "race",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "shirt_size": {
- "name": "shirt_size",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_data_auth_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_user_data_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_user_data_auth_id_foreign",
- "localTableName": "core_user_data",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_member",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "avatar_hash": {
- "name": "avatar_hash",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "last_role_sync_at": {
- "name": "last_role_sync_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "username": {
- "name": "username",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "verified_at": {
- "name": "verified_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "discord_member_discord_user_id_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "guild_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_guild_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "updated_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_updated_at_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "discord_member_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_member_auth_id_foreign",
- "localTableName": "discord_member",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_role_sync_attempt",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "error": {
- "name": "error",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "role_ids": {
- "name": "role_ids",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "role_names": {
- "name": "role_names",
- "type": "json",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "status": {
- "name": "status",
- "type": "enum('synced','failed','skipped')",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [
- "synced",
- "failed",
- "skipped"
- ],
- "mappedType": "enum"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "discord_role_sync_attempt_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_role_sync_attempt_auth_id_foreign",
- "localTableName": "discord_role_sync_attempt",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_verification",
- "columns": {
- "accepted_at": {
- "name": "accepted_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "avatar_hash": {
- "name": "avatar_hash",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "code": {
- "name": "code",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "expires_at": {
- "name": "expires_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "enum('pending','accepted','rejected','expired')",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'pending'",
- "comment": null,
- "collation": null,
- "enumItems": [
- "pending",
- "accepted",
- "rejected",
- "expired"
- ],
- "mappedType": "enum"
- },
- "username": {
- "name": "username",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "code"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "guild_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_guild_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "discord_verification_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_verification_auth_id_foreign",
- "localTableName": "discord_verification",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "session",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "expires_at": {
- "name": "expires_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "ip_address": {
- "name": "ip_address",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "token": {
- "name": "token",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "user_agent": {
- "name": "user_agent",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "user_id": {
- "name": "user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "token"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "session_token_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "session_user_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "session_user_id_foreign": {
- "columnNames": [
- "user_id"
- ],
- "constraintName": "session_user_id_foreign",
- "localTableName": "session",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "teams_invite",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "invitee_auth_id": {
- "name": "invitee_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "enum('pending','accepted','declined')",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'pending'",
- "comment": null,
- "collation": null,
- "enumItems": [
- "pending",
- "accepted",
- "declined"
- ],
- "mappedType": "enum"
- },
- "team_id": {
- "name": "team_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "invitee_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_invite_invitee_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "team_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_invite_team_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "team_id",
- "invitee_auth_id"
- ],
- "composite": true,
- "constraint": false,
- "keyName": "teams_invite_team_id_invitee_auth_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "teams_invite_invitee_auth_id_foreign": {
- "columnNames": [
- "invitee_auth_id"
- ],
- "constraintName": "teams_invite_invitee_auth_id_foreign",
- "localTableName": "teams_invite",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- },
- "teams_invite_team_id_foreign": {
- "columnNames": [
- "team_id"
- ],
- "constraintName": "teams_invite_team_id_foreign",
- "localTableName": "teams_invite",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "teams_team",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "teams_member",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "joined_at": {
- "name": "joined_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "team_id": {
- "name": "team_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_member_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "teams_member_auth_id_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "team_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_member_team_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "teams_member_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "teams_member_auth_id_foreign",
- "localTableName": "teams_member",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- },
- "teams_member_team_id_foreign": {
- "columnNames": [
- "team_id"
- ],
- "constraintName": "teams_member_team_id_foreign",
- "localTableName": "teams_member",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "teams_team",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "teams_team",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "name": {
- "name": "name",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "owner_auth_id": {
- "name": "owner_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "tag": {
- "name": "tag",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "owner_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_team_owner_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "tag"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_team_tag_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "tag"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "teams_team_tag_unique",
- "primary": false,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "teams_team_owner_auth_id_foreign": {
- "columnNames": [
- "owner_auth_id"
- ],
- "constraintName": "teams_team_owner_auth_id_foreign",
- "localTableName": "teams_team",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "verification",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "expires_at": {
- "name": "expires_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "identifier": {
- "name": "identifier",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "datetime",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "value": {
- "name": "value",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "PRIMARY",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "identifier"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "verification_identifier_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- }
- ],
- "views": [],
- "nativeEnums": {}
-}
\ No newline at end of file
diff --git a/apps/web/db/migrations/mysql/Migration20260927180400_initial.ts b/apps/web/db/migrations/mysql/Migration20260927180400_initial.ts
deleted file mode 100644
index 9160bcbf2..000000000
--- a/apps/web/db/migrations/mysql/Migration20260927180400_initial.ts
+++ /dev/null
@@ -1,171 +0,0 @@
-import { Migration } from "@mikro-orm/migrations";
-
-export class Migration20260927180400_initial extends Migration {
- override name = "Migration20260927180400_initial";
-
- override up(): void {
- this.addSql("create table `verification` (`id` varchar(255) not null, `identifier` varchar(255) not null, `value` text not null, `expires_at` datetime not null, `created_at` datetime null, `updated_at` datetime null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `verification` add index `verification_identifier_index` (`identifier`);");
- this.addSql("create table `core_event` (`id` varchar(255) not null, `title` varchar(255) not null, `start_time` datetime not null, `end_time` datetime not null, `location` varchar(255) not null default 'TBD', `description` text not null, `type` varchar(255) not null, `host` varchar(255) null, `hidden` tinyint(1) not null default false, `created_at` datetime not null, `updated_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_event` add index `core_event_start_time_index` (`start_time`);");
- this.addSql("alter table `core_event` add index `core_event_type_index` (`type`);");
- this.addSql("alter table `core_event` add index `core_event_hidden_index` (`hidden`);");
- this.addSql("create table `core_operation_lock` (`key` varchar(255) not null, `token` varchar(255) not null, primary key (`key`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("create table `core_role` (`id` varchar(255) not null, `name` varchar(255) not null, `position` int not null, `permissions` json not null default ('[]'), `color` varchar(255) null, `created_at` datetime not null, `updated_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_role` add unique `core_role_name_unique` (`name`);");
- this.addSql("alter table `core_role` add index `core_role_position_index` (`position`);");
- this.addSql("create table `core_user` (`id` varchar(255) not null, `name` varchar(255) not null, `email` varchar(255) not null, `email_verified` tinyint(1) not null default false, `profile_photo_url` text null, `hack_tag` varchar(255) null, `bio` text null, `pronouns` varchar(255) null, `skills` json not null default ('[]'), `is_profile_searchable` tinyint(1) not null default true, `discord_display_handle` varchar(255) null, `role_id` varchar(255) null, `is_approved` tinyint(1) not null default false, `checked_in_at` datetime null, `created_at` datetime not null, `updated_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_user` add unique `core_user_email_unique` (`email`);");
- this.addSql("alter table `core_user` add unique `core_user_hack_tag_unique` (`hack_tag`);");
- this.addSql("alter table `core_user` add index `core_user_hack_tag_index` (`hack_tag`);");
- this.addSql("alter table `core_user` add index `core_user_role_id_index` (`role_id`);");
- this.addSql("alter table `core_user` add index `core_user_created_at_index` (`created_at`);");
- this.addSql("create table `discord_verification` (`code` varchar(255) not null, `discord_user_id` varchar(255) not null, `guild_id` varchar(255) not null, `username` varchar(255) not null, `avatar_hash` varchar(255) null, `auth_id` varchar(255) null, `status` enum('pending','accepted','rejected','expired') not null default 'pending', `expires_at` datetime not null, `created_at` datetime not null, `accepted_at` datetime null, primary key (`code`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `discord_verification` add index `discord_verification_discord_user_id_index` (`discord_user_id`);");
- this.addSql("alter table `discord_verification` add index `discord_verification_guild_id_index` (`guild_id`);");
- this.addSql("alter table `discord_verification` add index `discord_verification_auth_id_index` (`auth_id`);");
- this.addSql("alter table `discord_verification` add index `discord_verification_status_index` (`status`);");
- this.addSql("alter table `discord_verification` add index `discord_verification_created_at_index` (`created_at`);");
- this.addSql("create table `discord_role_sync_attempt` (`id` varchar(255) not null, `auth_id` varchar(255) not null, `discord_user_id` varchar(255) not null, `guild_id` varchar(255) not null, `status` enum('synced','failed','skipped') not null, `role_ids` json not null default ('[]'), `role_names` json not null default ('[]'), `error` text null, `created_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `discord_role_sync_attempt` add index `discord_role_sync_attempt_auth_id_index` (`auth_id`);");
- this.addSql("alter table `discord_role_sync_attempt` add index `discord_role_sync_attempt_discord_user_id_index` (`discord_user_id`);");
- this.addSql("alter table `discord_role_sync_attempt` add index `discord_role_sync_attempt_status_index` (`status`);");
- this.addSql("alter table `discord_role_sync_attempt` add index `discord_role_sync_attempt_created_at_index` (`created_at`);");
- this.addSql("create table `discord_member` (`auth_id` varchar(255) not null, `discord_user_id` varchar(255) not null, `guild_id` varchar(255) not null, `username` varchar(255) not null, `avatar_hash` varchar(255) null, `verified_at` datetime not null, `updated_at` datetime not null, `last_role_sync_at` datetime null, primary key (`auth_id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `discord_member` add index `discord_member_auth_id_index` (`auth_id`);");
- this.addSql("alter table `discord_member` add unique `discord_member_discord_user_id_unique` (`discord_user_id`);");
- this.addSql("alter table `discord_member` add index `discord_member_discord_user_id_index` (`discord_user_id`);");
- this.addSql("alter table `discord_member` add index `discord_member_guild_id_index` (`guild_id`);");
- this.addSql("alter table `discord_member` add index `discord_member_updated_at_index` (`updated_at`);");
- this.addSql("create table `core_user_data` (`auth_id` varchar(255) not null, `age` int not null, `gender` varchar(255) not null, `race` varchar(255) not null, `ethnicity` varchar(255) not null, `shirt_size` varchar(255) not null, `dietary_restrictions` json not null default ('[]'), `accommodation_note` text null, `phone_number` varchar(255) null, `country_of_residence` varchar(255) null, `has_accepted_mlhcode_of_conduct` tinyint(1) not null, `has_shared_data_with_mlh` tinyint(1) not null, `is_emailable` tinyint(1) not null, `completed_at` datetime not null, `updated_at` datetime not null, primary key (`auth_id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_user_data` add index `core_user_data_auth_id_index` (`auth_id`);");
- this.addSql("create table `core_user_ban` (`auth_id` varchar(255) not null, `reason` varchar(255) null, `banned_by_auth_id` varchar(255) not null, `created_at` datetime not null, primary key (`auth_id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_user_ban` add index `core_user_ban_auth_id_index` (`auth_id`);");
- this.addSql("alter table `core_user_ban` add index `core_user_ban_banned_by_auth_id_index` (`banned_by_auth_id`);");
- this.addSql("create table `core_setting` (`key` varchar(255) not null, `value` json not null, `created_at` datetime not null, `created_by_auth_id` varchar(255) null, `updated_at` datetime not null, `updated_by_auth_id` varchar(255) null, primary key (`key`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_setting` add index `core_setting_created_by_auth_id_index` (`created_by_auth_id`);");
- this.addSql("alter table `core_setting` add index `core_setting_updated_at_index` (`updated_at`);");
- this.addSql("alter table `core_setting` add index `core_setting_updated_by_auth_id_index` (`updated_by_auth_id`);");
- this.addSql("create table `core_rsvp` (`auth_id` varchar(255) not null, `status` enum('confirmed','waitlisted','cancelled') not null, `waitlist_position` int null, `created_at` datetime not null, `updated_at` datetime not null, `confirmed_at` datetime null, `waitlisted_at` datetime null, `cancelled_at` datetime null, `cancelled_by_auth_id` varchar(255) null, `promoted_at` datetime null, `promoted_by_auth_id` varchar(255) null, primary key (`auth_id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_rsvp` add index `core_rsvp_auth_id_index` (`auth_id`);");
- this.addSql("alter table `core_rsvp` add index `core_rsvp_cancelled_by_auth_id_index` (`cancelled_by_auth_id`);");
- this.addSql("alter table `core_rsvp` add index `core_rsvp_promoted_by_auth_id_index` (`promoted_by_auth_id`);");
- this.addSql("alter table `core_rsvp` add index `core_rsvp_status_index` (`status`);");
- this.addSql("alter table `core_rsvp` add index `core_rsvp_waitlist_position_index` (`waitlist_position`);");
- this.addSql("alter table `core_rsvp` add index `core_rsvp_created_at_index` (`created_at`);");
- this.addSql("alter table `core_rsvp` add index `core_rsvp_updated_at_index` (`updated_at`);");
- this.addSql("create table `core_notification_intent` (`id` varchar(255) not null, `kind` varchar(255) not null, `recipient_auth_id` varchar(255) null, `payload` json not null, `status` enum('pending','processing','delivered','failed','skipped') not null default 'pending', `idempotency_key` varchar(255) null, `created_at` datetime not null, `updated_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_notification_intent` add unique `core_notification_intent_idempotency_key_unique` (`idempotency_key`);");
- this.addSql("alter table `core_notification_intent` add index `core_notification_intent_kind_index` (`kind`);");
- this.addSql("alter table `core_notification_intent` add index `core_notification_intent_recipient_auth_id_index` (`recipient_auth_id`);");
- this.addSql("alter table `core_notification_intent` add index `core_notification_intent_status_index` (`status`);");
- this.addSql("alter table `core_notification_intent` add index `core_notification_intent_created_at_index` (`created_at`);");
- this.addSql("create table `core_notification_delivery_attempt` (`id` varchar(255) not null, `intent_id` varchar(255) not null, `channel` varchar(255) not null, `provider` varchar(255) null, `status` enum('delivered','failed','skipped') not null, `recipient` varchar(255) null, `external_id` varchar(255) null, `error` text null, `metadata` json not null, `attempted_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_notification_delivery_attempt` add index `core_notification_delivery_attempt_intent_id_index` (`intent_id`);");
- this.addSql("alter table `core_notification_delivery_attempt` add index `core_notification_delivery_attempt_channel_index` (`channel`);");
- this.addSql("alter table `core_notification_delivery_attempt` add index `core_notification_delivery_attempt_status_index` (`status`);");
- this.addSql("alter table `core_notification_delivery_attempt` add index `core_notification_delivery_attempt_attempted_at_index` (`attempted_at`);");
- this.addSql("create table `core_hacker` (`auth_id` varchar(255) not null, `university` varchar(255) not null, `major` varchar(255) not null, `school_id` varchar(255) null, `level_of_study` varchar(255) not null, `hackathons_attended` int not null, `software_experience` varchar(255) not null, `heard_from` varchar(255) null, `github_url` text null, `linked_in_url` text null, `personal_website_url` text null, `resume_url` text null, `group` varchar(255) null, `registered_at` datetime not null, `updated_at` datetime not null, primary key (`auth_id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_hacker` add index `core_hacker_auth_id_index` (`auth_id`);");
- this.addSql("alter table `core_hacker` add index `core_hacker_registered_at_index` (`registered_at`);");
- this.addSql("create table `core_event_scan` (`id` varchar(255) not null, `event_id` varchar(255) not null, `auth_id` varchar(255) not null, `scanned_by_auth_id` varchar(255) not null, `scanned_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `core_event_scan` add index `core_event_scan_scanned_by_auth_id_index` (`scanned_by_auth_id`);");
- this.addSql("alter table `core_event_scan` add index `core_event_scan_event_id_index` (`event_id`);");
- this.addSql("alter table `core_event_scan` add index `core_event_scan_auth_id_index` (`auth_id`);");
- this.addSql("alter table `core_event_scan` add index `core_event_scan_event_id_auth_id_index` (`event_id`, `auth_id`);");
- this.addSql("alter table `core_event_scan` add index `core_event_scan_scanned_at_index` (`scanned_at`);");
- this.addSql("create table `session` (`id` varchar(255) not null, `expires_at` datetime not null, `token` varchar(255) not null, `created_at` datetime not null, `updated_at` datetime not null, `ip_address` varchar(255) null, `user_agent` text null, `user_id` varchar(255) not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `session` add unique `session_token_unique` (`token`);");
- this.addSql("alter table `session` add index `session_user_id_index` (`user_id`);");
- this.addSql("create table `account` (`id` varchar(255) not null, `account_id` varchar(255) not null, `provider_id` varchar(255) not null, `user_id` varchar(255) not null, `access_token` text null, `refresh_token` text null, `id_token` text null, `access_token_expires_at` datetime null, `refresh_token_expires_at` datetime null, `scope` text null, `password` varchar(255) null, `created_at` datetime not null, `updated_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `account` add index `account_user_id_index` (`user_id`);");
- this.addSql("create table `teams_team` (`id` varchar(255) not null, `name` varchar(255) not null, `tag` varchar(255) not null, `owner_auth_id` varchar(255) not null, `created_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `teams_team` add unique `teams_team_tag_unique` (`tag`);");
- this.addSql("alter table `teams_team` add index `teams_team_tag_index` (`tag`);");
- this.addSql("alter table `teams_team` add index `teams_team_owner_auth_id_index` (`owner_auth_id`);");
- this.addSql("create table `teams_member` (`id` varchar(255) not null, `team_id` varchar(255) not null, `auth_id` varchar(255) not null, `joined_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `teams_member` add unique `teams_member_auth_id_unique` (`auth_id`);");
- this.addSql("alter table `teams_member` add index `teams_member_team_id_index` (`team_id`);");
- this.addSql("alter table `teams_member` add index `teams_member_auth_id_index` (`auth_id`);");
- this.addSql("create table `teams_invite` (`id` varchar(255) not null, `team_id` varchar(255) not null, `invitee_auth_id` varchar(255) not null, `status` enum('pending','accepted','declined') not null default 'pending', `created_at` datetime not null, primary key (`id`)) default character set utf8mb4 engine = InnoDB;");
- this.addSql("alter table `teams_invite` add index `teams_invite_team_id_index` (`team_id`);");
- this.addSql("alter table `teams_invite` add index `teams_invite_invitee_auth_id_index` (`invitee_auth_id`);");
- this.addSql("alter table `teams_invite` add index `teams_invite_team_id_invitee_auth_id_index` (`team_id`, `invitee_auth_id`);");
- this.addSql("alter table `core_user` add constraint `core_user_role_id_foreign` foreign key (`role_id`) references `core_role` (`id`) on delete set null;");
- this.addSql("alter table `discord_verification` add constraint `discord_verification_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete set null;");
- this.addSql("alter table `discord_role_sync_attempt` add constraint `discord_role_sync_attempt_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete cascade;");
- this.addSql("alter table `discord_member` add constraint `discord_member_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade;");
- this.addSql("alter table `core_user_data` add constraint `core_user_data_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade;");
- this.addSql("alter table `core_user_ban` add constraint `core_user_ban_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade;");
- this.addSql("alter table `core_user_ban` add constraint `core_user_ban_banned_by_auth_id_foreign` foreign key (`banned_by_auth_id`) references `core_user` (`id`);");
- this.addSql("alter table `core_setting` add constraint `core_setting_created_by_auth_id_foreign` foreign key (`created_by_auth_id`) references `core_user` (`id`) on delete set null;");
- this.addSql("alter table `core_setting` add constraint `core_setting_updated_by_auth_id_foreign` foreign key (`updated_by_auth_id`) references `core_user` (`id`) on delete set null;");
- this.addSql("alter table `core_rsvp` add constraint `core_rsvp_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade;");
- this.addSql("alter table `core_rsvp` add constraint `core_rsvp_cancelled_by_auth_id_foreign` foreign key (`cancelled_by_auth_id`) references `core_user` (`id`) on delete set null;");
- this.addSql("alter table `core_rsvp` add constraint `core_rsvp_promoted_by_auth_id_foreign` foreign key (`promoted_by_auth_id`) references `core_user` (`id`) on delete set null;");
- this.addSql("alter table `core_notification_intent` add constraint `core_notification_intent_recipient_auth_id_foreign` foreign key (`recipient_auth_id`) references `core_user` (`id`) on delete set null;");
- this.addSql("alter table `core_notification_delivery_attempt` add constraint `core_notification_delivery_attempt_intent_id_foreign` foreign key (`intent_id`) references `core_notification_intent` (`id`) on delete cascade;");
- this.addSql("alter table `core_hacker` add constraint `core_hacker_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade;");
- this.addSql("alter table `core_event_scan` add constraint `core_event_scan_event_id_foreign` foreign key (`event_id`) references `core_event` (`id`) on delete cascade;");
- this.addSql("alter table `core_event_scan` add constraint `core_event_scan_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete cascade;");
- this.addSql("alter table `core_event_scan` add constraint `core_event_scan_scanned_by_auth_id_foreign` foreign key (`scanned_by_auth_id`) references `core_user` (`id`);");
- this.addSql("alter table `session` add constraint `session_user_id_foreign` foreign key (`user_id`) references `core_user` (`id`) on delete cascade;");
- this.addSql("alter table `account` add constraint `account_user_id_foreign` foreign key (`user_id`) references `core_user` (`id`) on delete cascade;");
- this.addSql("alter table `teams_team` add constraint `teams_team_owner_auth_id_foreign` foreign key (`owner_auth_id`) references `core_user` (`id`) on delete cascade;");
- this.addSql("alter table `teams_member` add constraint `teams_member_team_id_foreign` foreign key (`team_id`) references `teams_team` (`id`) on delete cascade;");
- this.addSql("alter table `teams_member` add constraint `teams_member_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete cascade;");
- this.addSql("alter table `teams_invite` add constraint `teams_invite_team_id_foreign` foreign key (`team_id`) references `teams_team` (`id`) on delete cascade;");
- this.addSql("alter table `teams_invite` add constraint `teams_invite_invitee_auth_id_foreign` foreign key (`invitee_auth_id`) references `core_user` (`id`) on delete cascade;");
- }
-
- override down(): void | Promise {
- this.addSql(`alter table \`session\` drop foreign key \`session_user_id_foreign\`;`);
- this.addSql(`alter table \`account\` drop foreign key \`account_user_id_foreign\`;`);
- this.addSql(`alter table \`core_event_scan\` drop foreign key \`core_event_scan_event_id_foreign\`;`);
- this.addSql(`alter table \`core_user\` drop foreign key \`core_user_role_id_foreign\`;`);
- this.addSql(`alter table \`discord_verification\` drop foreign key \`discord_verification_auth_id_foreign\`;`);
- this.addSql(`alter table \`discord_role_sync_attempt\` drop foreign key \`discord_role_sync_attempt_auth_id_foreign\`;`);
- this.addSql(`alter table \`discord_member\` drop foreign key \`discord_member_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_user_data\` drop foreign key \`core_user_data_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_user_ban\` drop foreign key \`core_user_ban_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_user_ban\` drop foreign key \`core_user_ban_banned_by_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_setting\` drop foreign key \`core_setting_created_by_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_setting\` drop foreign key \`core_setting_updated_by_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_rsvp\` drop foreign key \`core_rsvp_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_rsvp\` drop foreign key \`core_rsvp_cancelled_by_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_rsvp\` drop foreign key \`core_rsvp_promoted_by_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_notification_intent\` drop foreign key \`core_notification_intent_recipient_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_hacker\` drop foreign key \`core_hacker_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_event_scan\` drop foreign key \`core_event_scan_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_event_scan\` drop foreign key \`core_event_scan_scanned_by_auth_id_foreign\`;`);
- this.addSql(`alter table \`teams_team\` drop foreign key \`teams_team_owner_auth_id_foreign\`;`);
- this.addSql(`alter table \`teams_member\` drop foreign key \`teams_member_auth_id_foreign\`;`);
- this.addSql(`alter table \`teams_invite\` drop foreign key \`teams_invite_invitee_auth_id_foreign\`;`);
- this.addSql(`alter table \`core_notification_delivery_attempt\` drop foreign key \`core_notification_delivery_attempt_intent_id_foreign\`;`);
- this.addSql(`alter table \`teams_member\` drop foreign key \`teams_member_team_id_foreign\`;`);
- this.addSql(`alter table \`teams_invite\` drop foreign key \`teams_invite_team_id_foreign\`;`);
-
- this.addSql(`drop table if exists \`session\`;`);
- this.addSql(`drop table if exists \`account\`;`);
- this.addSql(`drop table if exists \`verification\`;`);
- this.addSql(`drop table if exists \`core_event\`;`);
- this.addSql(`drop table if exists \`core_operation_lock\`;`);
- this.addSql(`drop table if exists \`core_role\`;`);
- this.addSql(`drop table if exists \`core_user\`;`);
- this.addSql(`drop table if exists \`discord_verification\`;`);
- this.addSql(`drop table if exists \`discord_role_sync_attempt\`;`);
- this.addSql(`drop table if exists \`discord_member\`;`);
- this.addSql(`drop table if exists \`core_user_data\`;`);
- this.addSql(`drop table if exists \`core_user_ban\`;`);
- this.addSql(`drop table if exists \`core_setting\`;`);
- this.addSql(`drop table if exists \`core_rsvp\`;`);
- this.addSql(`drop table if exists \`core_notification_intent\`;`);
- this.addSql(`drop table if exists \`core_notification_delivery_attempt\`;`);
- this.addSql(`drop table if exists \`core_hacker\`;`);
- this.addSql(`drop table if exists \`core_event_scan\`;`);
- this.addSql(`drop table if exists \`teams_team\`;`);
- this.addSql(`drop table if exists \`teams_member\`;`);
- this.addSql(`drop table if exists \`teams_invite\`;`);
- }
-
-}
diff --git a/apps/web/db/migrations/postgresql/.snapshot.json b/apps/web/db/migrations/postgresql/.snapshot.json
deleted file mode 100644
index e4b304873..000000000
--- a/apps/web/db/migrations/postgresql/.snapshot.json
+++ /dev/null
@@ -1,4449 +0,0 @@
-{
- "name": "public",
- "namespaces": [
- "public"
- ],
- "tables": [
- {
- "name": "account",
- "schema": "public",
- "columns": {
- "access_token": {
- "name": "access_token",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "access_token_expires_at": {
- "name": "access_token_expires_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "account_id": {
- "name": "account_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id_token": {
- "name": "id_token",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "password": {
- "name": "password",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "provider_id": {
- "name": "provider_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "refresh_token": {
- "name": "refresh_token",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "refresh_token_expires_at": {
- "name": "refresh_token_expires_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "scope": {
- "name": "scope",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "user_id": {
- "name": "user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "account_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "account_user_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "account_user_id_foreign": {
- "columnNames": [
- "user_id"
- ],
- "constraintName": "account_user_id_foreign",
- "localTableName": "public.account",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "core_event",
- "schema": "public",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "description": {
- "name": "description",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "end_time": {
- "name": "end_time",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "hidden": {
- "name": "hidden",
- "type": "boolean",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "false",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "host": {
- "name": "host",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "location": {
- "name": "location",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": "'TBD'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "start_time": {
- "name": "start_time",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "title": {
- "name": "title",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "type": {
- "name": "type",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "hidden"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_hidden_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_event_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "start_time"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_start_time_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "type"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_type_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- },
- {
- "name": "core_event_scan",
- "schema": "public",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "event_id": {
- "name": "event_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "scanned_at": {
- "name": "scanned_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "scanned_by_auth_id": {
- "name": "scanned_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_scan_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "event_id",
- "auth_id"
- ],
- "composite": true,
- "constraint": false,
- "keyName": "core_event_scan_event_id_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "event_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_scan_event_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_event_scan_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "scanned_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_event_scan_scanned_at_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_event_scan_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_event_scan_auth_id_foreign",
- "localTableName": "public.core_event_scan",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "cascade"
- },
- "core_event_scan_event_id_foreign": {
- "columnNames": [
- "event_id"
- ],
- "constraintName": "core_event_scan_event_id_foreign",
- "localTableName": "public.core_event_scan",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_event",
- "deleteRule": "cascade"
- },
- "core_event_scan_scanned_by_auth_id_foreign": {
- "columnNames": [
- "scanned_by_auth_id"
- ],
- "constraintName": "core_event_scan_scanned_by_auth_id_foreign",
- "localTableName": "public.core_event_scan",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user"
- }
- },
- "comment": null
- },
- {
- "name": "core_hacker",
- "schema": "public",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "github_url": {
- "name": "github_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "group": {
- "name": "group",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "hackathons_attended": {
- "name": "hackathons_attended",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "heard_from": {
- "name": "heard_from",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "level_of_study": {
- "name": "level_of_study",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "linked_in_url": {
- "name": "linked_in_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "major": {
- "name": "major",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "personal_website_url": {
- "name": "personal_website_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "registered_at": {
- "name": "registered_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "resume_url": {
- "name": "resume_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "school_id": {
- "name": "school_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "software_experience": {
- "name": "software_experience",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "university": {
- "name": "university",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_hacker_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "registered_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_hacker_registered_at_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_hacker_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_hacker_auth_id_foreign",
- "localTableName": "public.core_hacker",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "core_notification_delivery_attempt",
- "schema": "public",
- "columns": {
- "attempted_at": {
- "name": "attempted_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "channel": {
- "name": "channel",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "error": {
- "name": "error",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "external_id": {
- "name": "external_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "intent_id": {
- "name": "intent_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "provider": {
- "name": "provider",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "recipient": {
- "name": "recipient",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [
- "delivered",
- "failed",
- "skipped"
- ],
- "mappedType": "enum"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "attempted_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_attempted_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "channel"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_channel_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "intent_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_intent_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_notification_delivery_attempt_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_delivery_attempt_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [
- {
- "name": "core_notification_delivery_attempt_status_check",
- "expression": "\"status\" in ('delivered', 'failed', 'skipped')",
- "definition": "check (\"status\" in ('delivered', 'failed', 'skipped'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "core_notification_delivery_attempt_intent_id_foreign": {
- "columnNames": [
- "intent_id"
- ],
- "constraintName": "core_notification_delivery_attempt_intent_id_foreign",
- "localTableName": "public.core_notification_delivery_attempt",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_notification_intent",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "core_notification_intent",
- "schema": "public",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "idempotency_key": {
- "name": "idempotency_key",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "kind": {
- "name": "kind",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "payload": {
- "name": "payload",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "recipient_auth_id": {
- "name": "recipient_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'pending'",
- "comment": null,
- "collation": null,
- "enumItems": [
- "pending",
- "processing",
- "delivered",
- "failed",
- "skipped"
- ],
- "mappedType": "enum"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "idempotency_key"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_notification_intent_idempotency_key_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "kind"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_kind_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_notification_intent_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "recipient_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_recipient_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_notification_intent_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [
- {
- "name": "core_notification_intent_status_check",
- "expression": "\"status\" in ('pending', 'processing', 'delivered', 'failed', 'skipped')",
- "definition": "check (\"status\" in ('pending', 'processing', 'delivered', 'failed', 'skipped'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "core_notification_intent_recipient_auth_id_foreign": {
- "columnNames": [
- "recipient_auth_id"
- ],
- "constraintName": "core_notification_intent_recipient_auth_id_foreign",
- "localTableName": "public.core_notification_intent",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_operation_lock",
- "schema": "public",
- "columns": {
- "key": {
- "name": "key",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "token": {
- "name": "token",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "key"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_operation_lock_pkey",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- },
- {
- "name": "core_role",
- "schema": "public",
- "columns": {
- "color": {
- "name": "color",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "name": {
- "name": "name",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "permissions": {
- "name": "permissions",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "position": {
- "name": "position",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "name"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_role_name_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_role_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "position"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_role_position_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- },
- {
- "name": "core_rsvp",
- "schema": "public",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "cancelled_at": {
- "name": "cancelled_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "cancelled_by_auth_id": {
- "name": "cancelled_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "confirmed_at": {
- "name": "confirmed_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "promoted_at": {
- "name": "promoted_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "promoted_by_auth_id": {
- "name": "promoted_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [
- "confirmed",
- "waitlisted",
- "cancelled"
- ],
- "mappedType": "enum"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "waitlist_position": {
- "name": "waitlist_position",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "waitlisted_at": {
- "name": "waitlisted_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_rsvp_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_status_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "updated_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_updated_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "waitlist_position"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_rsvp_waitlist_position_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [
- {
- "name": "core_rsvp_status_check",
- "expression": "\"status\" in ('confirmed', 'waitlisted', 'cancelled')",
- "definition": "check (\"status\" in ('confirmed', 'waitlisted', 'cancelled'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "core_rsvp_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_rsvp_auth_id_foreign",
- "localTableName": "public.core_rsvp",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- },
- "core_rsvp_cancelled_by_auth_id_foreign": {
- "columnNames": [
- "cancelled_by_auth_id"
- ],
- "constraintName": "core_rsvp_cancelled_by_auth_id_foreign",
- "localTableName": "public.core_rsvp",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "set null"
- },
- "core_rsvp_promoted_by_auth_id_foreign": {
- "columnNames": [
- "promoted_by_auth_id"
- ],
- "constraintName": "core_rsvp_promoted_by_auth_id_foreign",
- "localTableName": "public.core_rsvp",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_setting",
- "schema": "public",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "created_by_auth_id": {
- "name": "created_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "key": {
- "name": "key",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "updated_by_auth_id": {
- "name": "updated_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "value": {
- "name": "value",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "key"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_setting_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "updated_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_setting_updated_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "updated_by_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_setting_updated_by_auth_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_setting_created_by_auth_id_foreign": {
- "columnNames": [
- "created_by_auth_id"
- ],
- "constraintName": "core_setting_created_by_auth_id_foreign",
- "localTableName": "public.core_setting",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "set null"
- },
- "core_setting_updated_by_auth_id_foreign": {
- "columnNames": [
- "updated_by_auth_id"
- ],
- "constraintName": "core_setting_updated_by_auth_id_foreign",
- "localTableName": "public.core_setting",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_user",
- "schema": "public",
- "columns": {
- "bio": {
- "name": "bio",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "checked_in_at": {
- "name": "checked_in_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_display_handle": {
- "name": "discord_display_handle",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "email": {
- "name": "email",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "false",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "hack_tag": {
- "name": "hack_tag",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "is_approved": {
- "name": "is_approved",
- "type": "boolean",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "false",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "is_profile_searchable": {
- "name": "is_profile_searchable",
- "type": "boolean",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "true",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "name": {
- "name": "name",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "profile_photo_url": {
- "name": "profile_photo_url",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "pronouns": {
- "name": "pronouns",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "role_id": {
- "name": "role_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "skills": {
- "name": "skills",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "email"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_user_email_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "hack_tag"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_hack_tag_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "hack_tag"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_user_hack_tag_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_user_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "role_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "core_user_role_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_user_role_id_foreign": {
- "columnNames": [
- "role_id"
- ],
- "constraintName": "core_user_role_id_foreign",
- "localTableName": "public.core_user",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_role",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "core_user_ban",
- "schema": "public",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "banned_by_auth_id": {
- "name": "banned_by_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "reason": {
- "name": "reason",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_user_ban_pkey",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_user_ban_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_user_ban_auth_id_foreign",
- "localTableName": "public.core_user_ban",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- },
- "core_user_ban_banned_by_auth_id_foreign": {
- "columnNames": [
- "banned_by_auth_id"
- ],
- "constraintName": "core_user_ban_banned_by_auth_id_foreign",
- "localTableName": "public.core_user_ban",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user"
- }
- },
- "comment": null
- },
- {
- "name": "core_user_data",
- "schema": "public",
- "columns": {
- "accommodation_note": {
- "name": "accommodation_note",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "age": {
- "name": "age",
- "type": "int",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "integer"
- },
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "completed_at": {
- "name": "completed_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "country_of_residence": {
- "name": "country_of_residence",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "dietary_restrictions": {
- "name": "dietary_restrictions",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "ethnicity": {
- "name": "ethnicity",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "gender": {
- "name": "gender",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "has_accepted_mlhcode_of_conduct": {
- "name": "has_accepted_mlhcode_of_conduct",
- "type": "boolean",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "has_shared_data_with_mlh": {
- "name": "has_shared_data_with_mlh",
- "type": "boolean",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "is_emailable": {
- "name": "is_emailable",
- "type": "boolean",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "boolean"
- },
- "phone_number": {
- "name": "phone_number",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "race": {
- "name": "race",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "shirt_size": {
- "name": "shirt_size",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "core_user_data_pkey",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "core_user_data_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "core_user_data_auth_id_foreign",
- "localTableName": "public.core_user_data",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_member",
- "schema": "public",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "avatar_hash": {
- "name": "avatar_hash",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "last_role_sync_at": {
- "name": "last_role_sync_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "username": {
- "name": "username",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "verified_at": {
- "name": "verified_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "discord_member_discord_user_id_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "guild_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_guild_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "discord_member_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "updated_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_member_updated_at_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "discord_member_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_member_auth_id_foreign",
- "localTableName": "public.discord_member",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "updateRule": "cascade",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_role_sync_attempt",
- "schema": "public",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "error": {
- "name": "error",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "role_ids": {
- "name": "role_ids",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "role_names": {
- "name": "role_names",
- "type": "jsonb",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'[]'",
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "json"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [
- "synced",
- "failed",
- "skipped"
- ],
- "mappedType": "enum"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "discord_role_sync_attempt_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_role_sync_attempt_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [
- {
- "name": "discord_role_sync_attempt_status_check",
- "expression": "\"status\" in ('synced', 'failed', 'skipped')",
- "definition": "check (\"status\" in ('synced', 'failed', 'skipped'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "discord_role_sync_attempt_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_role_sync_attempt_auth_id_foreign",
- "localTableName": "public.discord_role_sync_attempt",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "discord_verification",
- "schema": "public",
- "columns": {
- "accepted_at": {
- "name": "accepted_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "avatar_hash": {
- "name": "avatar_hash",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "code": {
- "name": "code",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "discord_user_id": {
- "name": "discord_user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "expires_at": {
- "name": "expires_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "guild_id": {
- "name": "guild_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'pending'",
- "comment": null,
- "collation": null,
- "enumItems": [
- "pending",
- "accepted",
- "rejected",
- "expired"
- ],
- "mappedType": "enum"
- },
- "username": {
- "name": "username",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "created_at"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_created_at_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "discord_user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_discord_user_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "guild_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_guild_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "code"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "discord_verification_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "status"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "discord_verification_status_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [
- {
- "name": "discord_verification_status_check",
- "expression": "\"status\" in ('pending', 'accepted', 'rejected', 'expired')",
- "definition": "check (\"status\" in ('pending', 'accepted', 'rejected', 'expired'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "discord_verification_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "discord_verification_auth_id_foreign",
- "localTableName": "public.discord_verification",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "set null"
- }
- },
- "comment": null
- },
- {
- "name": "session",
- "schema": "public",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "expires_at": {
- "name": "expires_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "ip_address": {
- "name": "ip_address",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "token": {
- "name": "token",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "user_agent": {
- "name": "user_agent",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- },
- "user_id": {
- "name": "user_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "session_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "token"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "session_token_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "user_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "session_user_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "session_user_id_foreign": {
- "columnNames": [
- "user_id"
- ],
- "constraintName": "session_user_id_foreign",
- "localTableName": "public.session",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "teams_invite",
- "schema": "public",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "invitee_auth_id": {
- "name": "invitee_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "status": {
- "name": "status",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": "'pending'",
- "comment": null,
- "collation": null,
- "enumItems": [
- "pending",
- "accepted",
- "declined"
- ],
- "mappedType": "enum"
- },
- "team_id": {
- "name": "team_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "invitee_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_invite_invitee_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "teams_invite_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "team_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_invite_team_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "team_id",
- "invitee_auth_id"
- ],
- "composite": true,
- "constraint": false,
- "keyName": "teams_invite_team_id_invitee_auth_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [
- {
- "name": "teams_invite_status_check",
- "expression": "\"status\" in ('pending', 'accepted', 'declined')",
- "definition": "check (\"status\" in ('pending', 'accepted', 'declined'))",
- "columnName": "status"
- }
- ],
- "triggers": [],
- "foreignKeys": {
- "teams_invite_invitee_auth_id_foreign": {
- "columnNames": [
- "invitee_auth_id"
- ],
- "constraintName": "teams_invite_invitee_auth_id_foreign",
- "localTableName": "public.teams_invite",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "cascade"
- },
- "teams_invite_team_id_foreign": {
- "columnNames": [
- "team_id"
- ],
- "constraintName": "teams_invite_team_id_foreign",
- "localTableName": "public.teams_invite",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.teams_team",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "teams_member",
- "schema": "public",
- "columns": {
- "auth_id": {
- "name": "auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "joined_at": {
- "name": "joined_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "team_id": {
- "name": "team_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_member_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "auth_id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "teams_member_auth_id_unique",
- "primary": false,
- "unique": true
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "teams_member_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "team_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_member_team_id_index",
- "primary": false,
- "unique": false
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "teams_member_auth_id_foreign": {
- "columnNames": [
- "auth_id"
- ],
- "constraintName": "teams_member_auth_id_foreign",
- "localTableName": "public.teams_member",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "cascade"
- },
- "teams_member_team_id_foreign": {
- "columnNames": [
- "team_id"
- ],
- "constraintName": "teams_member_team_id_foreign",
- "localTableName": "public.teams_member",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.teams_team",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "teams_team",
- "schema": "public",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "name": {
- "name": "name",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "owner_auth_id": {
- "name": "owner_auth_id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "tag": {
- "name": "tag",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": true,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "owner_auth_id"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_team_owner_auth_id_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "teams_team_pkey",
- "primary": true,
- "unique": true
- },
- {
- "columnNames": [
- "tag"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "teams_team_tag_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "tag"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "teams_team_tag_unique",
- "primary": false,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {
- "teams_team_owner_auth_id_foreign": {
- "columnNames": [
- "owner_auth_id"
- ],
- "constraintName": "teams_team_owner_auth_id_foreign",
- "localTableName": "public.teams_team",
- "referencedColumnNames": [
- "id"
- ],
- "referencedTableName": "public.core_user",
- "deleteRule": "cascade"
- }
- },
- "comment": null
- },
- {
- "name": "verification",
- "schema": "public",
- "columns": {
- "created_at": {
- "name": "created_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "expires_at": {
- "name": "expires_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "id": {
- "name": "id",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": true,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "identifier": {
- "name": "identifier",
- "type": "varchar(255)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": 255,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "string"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamptz(6)",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": true,
- "unique": false,
- "length": 6,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "datetime"
- },
- "value": {
- "name": "value",
- "type": "text",
- "unsigned": false,
- "autoincrement": false,
- "primary": false,
- "nullable": false,
- "unique": false,
- "length": null,
- "precision": null,
- "scale": null,
- "default": null,
- "comment": null,
- "collation": null,
- "enumItems": [],
- "mappedType": "text"
- }
- },
- "indexes": [
- {
- "columnNames": [
- "identifier"
- ],
- "composite": false,
- "constraint": false,
- "keyName": "verification_identifier_index",
- "primary": false,
- "unique": false
- },
- {
- "columnNames": [
- "id"
- ],
- "composite": false,
- "constraint": true,
- "keyName": "verification_pkey",
- "primary": true,
- "unique": true
- }
- ],
- "checks": [],
- "triggers": [],
- "foreignKeys": {},
- "comment": null
- }
- ],
- "views": [],
- "nativeEnums": {}
-}
\ No newline at end of file
diff --git a/apps/web/db/migrations/postgresql/Migration20260927180400_initial.ts b/apps/web/db/migrations/postgresql/Migration20260927180400_initial.ts
deleted file mode 100644
index 02ac9c298..000000000
--- a/apps/web/db/migrations/postgresql/Migration20260927180400_initial.ts
+++ /dev/null
@@ -1,167 +0,0 @@
-import { Migration } from "@mikro-orm/migrations";
-
-export class Migration20260927180400_initial extends Migration {
- override name = "Migration20260927180400_initial";
-
- override up(): void {
- this.addSql("create table \"verification\" (\"id\" varchar(255) not null, \"identifier\" varchar(255) not null, \"value\" text not null, \"expires_at\" timestamptz not null, \"created_at\" timestamptz null, \"updated_at\" timestamptz null, primary key (\"id\"));");
- this.addSql("create index \"verification_identifier_index\" on \"verification\" (\"identifier\");");
- this.addSql("create table \"core_event\" (\"id\" varchar(255) not null, \"title\" varchar(255) not null, \"start_time\" timestamptz not null, \"end_time\" timestamptz not null, \"location\" varchar(255) not null default 'TBD', \"description\" text not null, \"type\" varchar(255) not null, \"host\" varchar(255) null, \"hidden\" boolean not null default false, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("create index \"core_event_start_time_index\" on \"core_event\" (\"start_time\");");
- this.addSql("create index \"core_event_type_index\" on \"core_event\" (\"type\");");
- this.addSql("create index \"core_event_hidden_index\" on \"core_event\" (\"hidden\");");
- this.addSql("create table \"core_operation_lock\" (\"key\" varchar(255) not null, \"token\" varchar(255) not null, primary key (\"key\"));");
- this.addSql("create table \"core_role\" (\"id\" varchar(255) not null, \"name\" varchar(255) not null, \"position\" int not null, \"permissions\" jsonb not null default '[]', \"color\" varchar(255) null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("alter table \"core_role\" add constraint \"core_role_name_unique\" unique (\"name\");");
- this.addSql("create index \"core_role_position_index\" on \"core_role\" (\"position\");");
- this.addSql("create table \"core_user\" (\"id\" varchar(255) not null, \"name\" varchar(255) not null, \"email\" varchar(255) not null, \"email_verified\" boolean not null default false, \"profile_photo_url\" text null, \"hack_tag\" varchar(255) null, \"bio\" text null, \"pronouns\" varchar(255) null, \"skills\" jsonb not null default '[]', \"is_profile_searchable\" boolean not null default true, \"discord_display_handle\" varchar(255) null, \"role_id\" varchar(255) null, \"is_approved\" boolean not null default false, \"checked_in_at\" timestamptz null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("alter table \"core_user\" add constraint \"core_user_email_unique\" unique (\"email\");");
- this.addSql("alter table \"core_user\" add constraint \"core_user_hack_tag_unique\" unique (\"hack_tag\");");
- this.addSql("create index \"core_user_hack_tag_index\" on \"core_user\" (\"hack_tag\");");
- this.addSql("create index \"core_user_role_id_index\" on \"core_user\" (\"role_id\");");
- this.addSql("create index \"core_user_created_at_index\" on \"core_user\" (\"created_at\");");
- this.addSql("create table \"discord_verification\" (\"code\" varchar(255) not null, \"discord_user_id\" varchar(255) not null, \"guild_id\" varchar(255) not null, \"username\" varchar(255) not null, \"avatar_hash\" varchar(255) null, \"auth_id\" varchar(255) null, \"status\" text not null default 'pending', \"expires_at\" timestamptz not null, \"created_at\" timestamptz not null, \"accepted_at\" timestamptz null, primary key (\"code\"));");
- this.addSql("create index \"discord_verification_discord_user_id_index\" on \"discord_verification\" (\"discord_user_id\");");
- this.addSql("create index \"discord_verification_guild_id_index\" on \"discord_verification\" (\"guild_id\");");
- this.addSql("create index \"discord_verification_auth_id_index\" on \"discord_verification\" (\"auth_id\");");
- this.addSql("create index \"discord_verification_status_index\" on \"discord_verification\" (\"status\");");
- this.addSql("create index \"discord_verification_created_at_index\" on \"discord_verification\" (\"created_at\");");
- this.addSql("alter table \"discord_verification\" add constraint \"discord_verification_status_check\" check (\"status\" in ('pending', 'accepted', 'rejected', 'expired'));");
- this.addSql("create table \"discord_role_sync_attempt\" (\"id\" varchar(255) not null, \"auth_id\" varchar(255) not null, \"discord_user_id\" varchar(255) not null, \"guild_id\" varchar(255) not null, \"status\" text not null, \"role_ids\" jsonb not null default '[]', \"role_names\" jsonb not null default '[]', \"error\" text null, \"created_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("create index \"discord_role_sync_attempt_auth_id_index\" on \"discord_role_sync_attempt\" (\"auth_id\");");
- this.addSql("create index \"discord_role_sync_attempt_discord_user_id_index\" on \"discord_role_sync_attempt\" (\"discord_user_id\");");
- this.addSql("create index \"discord_role_sync_attempt_status_index\" on \"discord_role_sync_attempt\" (\"status\");");
- this.addSql("create index \"discord_role_sync_attempt_created_at_index\" on \"discord_role_sync_attempt\" (\"created_at\");");
- this.addSql("alter table \"discord_role_sync_attempt\" add constraint \"discord_role_sync_attempt_status_check\" check (\"status\" in ('synced', 'failed', 'skipped'));");
- this.addSql("create table \"discord_member\" (\"auth_id\" varchar(255) not null, \"discord_user_id\" varchar(255) not null, \"guild_id\" varchar(255) not null, \"username\" varchar(255) not null, \"avatar_hash\" varchar(255) null, \"verified_at\" timestamptz not null, \"updated_at\" timestamptz not null, \"last_role_sync_at\" timestamptz null, primary key (\"auth_id\"));");
- this.addSql("alter table \"discord_member\" add constraint \"discord_member_discord_user_id_unique\" unique (\"discord_user_id\");");
- this.addSql("create index \"discord_member_discord_user_id_index\" on \"discord_member\" (\"discord_user_id\");");
- this.addSql("create index \"discord_member_guild_id_index\" on \"discord_member\" (\"guild_id\");");
- this.addSql("create index \"discord_member_updated_at_index\" on \"discord_member\" (\"updated_at\");");
- this.addSql("create table \"core_user_data\" (\"auth_id\" varchar(255) not null, \"age\" int not null, \"gender\" varchar(255) not null, \"race\" varchar(255) not null, \"ethnicity\" varchar(255) not null, \"shirt_size\" varchar(255) not null, \"dietary_restrictions\" jsonb not null default '[]', \"accommodation_note\" text null, \"phone_number\" varchar(255) null, \"country_of_residence\" varchar(255) null, \"has_accepted_mlhcode_of_conduct\" boolean not null, \"has_shared_data_with_mlh\" boolean not null, \"is_emailable\" boolean not null, \"completed_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"auth_id\"));");
- this.addSql("create table \"core_user_ban\" (\"auth_id\" varchar(255) not null, \"reason\" varchar(255) null, \"banned_by_auth_id\" varchar(255) not null, \"created_at\" timestamptz not null, primary key (\"auth_id\"));");
- this.addSql("create table \"core_setting\" (\"key\" varchar(255) not null, \"value\" jsonb not null, \"created_at\" timestamptz not null, \"created_by_auth_id\" varchar(255) null, \"updated_at\" timestamptz not null, \"updated_by_auth_id\" varchar(255) null, primary key (\"key\"));");
- this.addSql("create index \"core_setting_updated_at_index\" on \"core_setting\" (\"updated_at\");");
- this.addSql("create index \"core_setting_updated_by_auth_id_index\" on \"core_setting\" (\"updated_by_auth_id\");");
- this.addSql("create table \"core_rsvp\" (\"auth_id\" varchar(255) not null, \"status\" text not null, \"waitlist_position\" int null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, \"confirmed_at\" timestamptz null, \"waitlisted_at\" timestamptz null, \"cancelled_at\" timestamptz null, \"cancelled_by_auth_id\" varchar(255) null, \"promoted_at\" timestamptz null, \"promoted_by_auth_id\" varchar(255) null, primary key (\"auth_id\"));");
- this.addSql("create index \"core_rsvp_status_index\" on \"core_rsvp\" (\"status\");");
- this.addSql("create index \"core_rsvp_waitlist_position_index\" on \"core_rsvp\" (\"waitlist_position\");");
- this.addSql("create index \"core_rsvp_created_at_index\" on \"core_rsvp\" (\"created_at\");");
- this.addSql("create index \"core_rsvp_updated_at_index\" on \"core_rsvp\" (\"updated_at\");");
- this.addSql("alter table \"core_rsvp\" add constraint \"core_rsvp_status_check\" check (\"status\" in ('confirmed', 'waitlisted', 'cancelled'));");
- this.addSql("create table \"core_notification_intent\" (\"id\" varchar(255) not null, \"kind\" varchar(255) not null, \"recipient_auth_id\" varchar(255) null, \"payload\" jsonb not null, \"status\" text not null default 'pending', \"idempotency_key\" varchar(255) null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("alter table \"core_notification_intent\" add constraint \"core_notification_intent_idempotency_key_unique\" unique (\"idempotency_key\");");
- this.addSql("create index \"core_notification_intent_kind_index\" on \"core_notification_intent\" (\"kind\");");
- this.addSql("create index \"core_notification_intent_recipient_auth_id_index\" on \"core_notification_intent\" (\"recipient_auth_id\");");
- this.addSql("create index \"core_notification_intent_status_index\" on \"core_notification_intent\" (\"status\");");
- this.addSql("create index \"core_notification_intent_created_at_index\" on \"core_notification_intent\" (\"created_at\");");
- this.addSql("alter table \"core_notification_intent\" add constraint \"core_notification_intent_status_check\" check (\"status\" in ('pending', 'processing', 'delivered', 'failed', 'skipped'));");
- this.addSql("create table \"core_notification_delivery_attempt\" (\"id\" varchar(255) not null, \"intent_id\" varchar(255) not null, \"channel\" varchar(255) not null, \"provider\" varchar(255) null, \"status\" text not null, \"recipient\" varchar(255) null, \"external_id\" varchar(255) null, \"error\" text null, \"metadata\" jsonb not null, \"attempted_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("create index \"core_notification_delivery_attempt_intent_id_index\" on \"core_notification_delivery_attempt\" (\"intent_id\");");
- this.addSql("create index \"core_notification_delivery_attempt_channel_index\" on \"core_notification_delivery_attempt\" (\"channel\");");
- this.addSql("create index \"core_notification_delivery_attempt_status_index\" on \"core_notification_delivery_attempt\" (\"status\");");
- this.addSql("create index \"core_notification_delivery_attempt_attempted_at_index\" on \"core_notification_delivery_attempt\" (\"attempted_at\");");
- this.addSql("alter table \"core_notification_delivery_attempt\" add constraint \"core_notification_delivery_attempt_status_check\" check (\"status\" in ('delivered', 'failed', 'skipped'));");
- this.addSql("create table \"core_hacker\" (\"auth_id\" varchar(255) not null, \"university\" varchar(255) not null, \"major\" varchar(255) not null, \"school_id\" varchar(255) null, \"level_of_study\" varchar(255) not null, \"hackathons_attended\" int not null, \"software_experience\" varchar(255) not null, \"heard_from\" varchar(255) null, \"github_url\" text null, \"linked_in_url\" text null, \"personal_website_url\" text null, \"resume_url\" text null, \"group\" varchar(255) null, \"registered_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"auth_id\"));");
- this.addSql("create index \"core_hacker_registered_at_index\" on \"core_hacker\" (\"registered_at\");");
- this.addSql("create table \"core_event_scan\" (\"id\" varchar(255) not null, \"event_id\" varchar(255) not null, \"auth_id\" varchar(255) not null, \"scanned_by_auth_id\" varchar(255) not null, \"scanned_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("create index \"core_event_scan_event_id_index\" on \"core_event_scan\" (\"event_id\");");
- this.addSql("create index \"core_event_scan_auth_id_index\" on \"core_event_scan\" (\"auth_id\");");
- this.addSql("create index \"core_event_scan_event_id_auth_id_index\" on \"core_event_scan\" (\"event_id\", \"auth_id\");");
- this.addSql("create index \"core_event_scan_scanned_at_index\" on \"core_event_scan\" (\"scanned_at\");");
- this.addSql("create table \"session\" (\"id\" varchar(255) not null, \"expires_at\" timestamptz not null, \"token\" varchar(255) not null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, \"ip_address\" varchar(255) null, \"user_agent\" text null, \"user_id\" varchar(255) not null, primary key (\"id\"));");
- this.addSql("alter table \"session\" add constraint \"session_token_unique\" unique (\"token\");");
- this.addSql("create index \"session_user_id_index\" on \"session\" (\"user_id\");");
- this.addSql("create table \"account\" (\"id\" varchar(255) not null, \"account_id\" varchar(255) not null, \"provider_id\" varchar(255) not null, \"user_id\" varchar(255) not null, \"access_token\" text null, \"refresh_token\" text null, \"id_token\" text null, \"access_token_expires_at\" timestamptz null, \"refresh_token_expires_at\" timestamptz null, \"scope\" text null, \"password\" varchar(255) null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("create index \"account_user_id_index\" on \"account\" (\"user_id\");");
- this.addSql("create table \"teams_team\" (\"id\" varchar(255) not null, \"name\" varchar(255) not null, \"tag\" varchar(255) not null, \"owner_auth_id\" varchar(255) not null, \"created_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("alter table \"teams_team\" add constraint \"teams_team_tag_unique\" unique (\"tag\");");
- this.addSql("create index \"teams_team_tag_index\" on \"teams_team\" (\"tag\");");
- this.addSql("create index \"teams_team_owner_auth_id_index\" on \"teams_team\" (\"owner_auth_id\");");
- this.addSql("create table \"teams_member\" (\"id\" varchar(255) not null, \"team_id\" varchar(255) not null, \"auth_id\" varchar(255) not null, \"joined_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("alter table \"teams_member\" add constraint \"teams_member_auth_id_unique\" unique (\"auth_id\");");
- this.addSql("create index \"teams_member_team_id_index\" on \"teams_member\" (\"team_id\");");
- this.addSql("create index \"teams_member_auth_id_index\" on \"teams_member\" (\"auth_id\");");
- this.addSql("create table \"teams_invite\" (\"id\" varchar(255) not null, \"team_id\" varchar(255) not null, \"invitee_auth_id\" varchar(255) not null, \"status\" text not null default 'pending', \"created_at\" timestamptz not null, primary key (\"id\"));");
- this.addSql("create index \"teams_invite_team_id_index\" on \"teams_invite\" (\"team_id\");");
- this.addSql("create index \"teams_invite_invitee_auth_id_index\" on \"teams_invite\" (\"invitee_auth_id\");");
- this.addSql("create index \"teams_invite_team_id_invitee_auth_id_index\" on \"teams_invite\" (\"team_id\", \"invitee_auth_id\");");
- this.addSql("alter table \"teams_invite\" add constraint \"teams_invite_status_check\" check (\"status\" in ('pending', 'accepted', 'declined'));");
- this.addSql("alter table \"core_user\" add constraint \"core_user_role_id_foreign\" foreign key (\"role_id\") references \"core_role\" (\"id\") on delete set null;");
- this.addSql("alter table \"discord_verification\" add constraint \"discord_verification_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on delete set null;");
- this.addSql("alter table \"discord_role_sync_attempt\" add constraint \"discord_role_sync_attempt_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on delete cascade;");
- this.addSql("alter table \"discord_member\" add constraint \"discord_member_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on update cascade on delete cascade;");
- this.addSql("alter table \"core_user_data\" add constraint \"core_user_data_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on update cascade on delete cascade;");
- this.addSql("alter table \"core_user_ban\" add constraint \"core_user_ban_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on update cascade on delete cascade;");
- this.addSql("alter table \"core_user_ban\" add constraint \"core_user_ban_banned_by_auth_id_foreign\" foreign key (\"banned_by_auth_id\") references \"core_user\" (\"id\");");
- this.addSql("alter table \"core_setting\" add constraint \"core_setting_created_by_auth_id_foreign\" foreign key (\"created_by_auth_id\") references \"core_user\" (\"id\") on delete set null;");
- this.addSql("alter table \"core_setting\" add constraint \"core_setting_updated_by_auth_id_foreign\" foreign key (\"updated_by_auth_id\") references \"core_user\" (\"id\") on delete set null;");
- this.addSql("alter table \"core_rsvp\" add constraint \"core_rsvp_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on update cascade on delete cascade;");
- this.addSql("alter table \"core_rsvp\" add constraint \"core_rsvp_cancelled_by_auth_id_foreign\" foreign key (\"cancelled_by_auth_id\") references \"core_user\" (\"id\") on delete set null;");
- this.addSql("alter table \"core_rsvp\" add constraint \"core_rsvp_promoted_by_auth_id_foreign\" foreign key (\"promoted_by_auth_id\") references \"core_user\" (\"id\") on delete set null;");
- this.addSql("alter table \"core_notification_intent\" add constraint \"core_notification_intent_recipient_auth_id_foreign\" foreign key (\"recipient_auth_id\") references \"core_user\" (\"id\") on delete set null;");
- this.addSql("alter table \"core_notification_delivery_attempt\" add constraint \"core_notification_delivery_attempt_intent_id_foreign\" foreign key (\"intent_id\") references \"core_notification_intent\" (\"id\") on delete cascade;");
- this.addSql("alter table \"core_hacker\" add constraint \"core_hacker_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on update cascade on delete cascade;");
- this.addSql("alter table \"core_event_scan\" add constraint \"core_event_scan_event_id_foreign\" foreign key (\"event_id\") references \"core_event\" (\"id\") on delete cascade;");
- this.addSql("alter table \"core_event_scan\" add constraint \"core_event_scan_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on delete cascade;");
- this.addSql("alter table \"core_event_scan\" add constraint \"core_event_scan_scanned_by_auth_id_foreign\" foreign key (\"scanned_by_auth_id\") references \"core_user\" (\"id\");");
- this.addSql("alter table \"session\" add constraint \"session_user_id_foreign\" foreign key (\"user_id\") references \"core_user\" (\"id\") on delete cascade;");
- this.addSql("alter table \"account\" add constraint \"account_user_id_foreign\" foreign key (\"user_id\") references \"core_user\" (\"id\") on delete cascade;");
- this.addSql("alter table \"teams_team\" add constraint \"teams_team_owner_auth_id_foreign\" foreign key (\"owner_auth_id\") references \"core_user\" (\"id\") on delete cascade;");
- this.addSql("alter table \"teams_member\" add constraint \"teams_member_team_id_foreign\" foreign key (\"team_id\") references \"teams_team\" (\"id\") on delete cascade;");
- this.addSql("alter table \"teams_member\" add constraint \"teams_member_auth_id_foreign\" foreign key (\"auth_id\") references \"core_user\" (\"id\") on delete cascade;");
- this.addSql("alter table \"teams_invite\" add constraint \"teams_invite_team_id_foreign\" foreign key (\"team_id\") references \"teams_team\" (\"id\") on delete cascade;");
- this.addSql("alter table \"teams_invite\" add constraint \"teams_invite_invitee_auth_id_foreign\" foreign key (\"invitee_auth_id\") references \"core_user\" (\"id\") on delete cascade;");
- }
-
- override down(): void | Promise {
- this.addSql(`alter table "session" drop constraint "session_user_id_foreign";`);
- this.addSql(`alter table "account" drop constraint "account_user_id_foreign";`);
- this.addSql(`alter table "core_event_scan" drop constraint "core_event_scan_event_id_foreign";`);
- this.addSql(`alter table "core_user" drop constraint "core_user_role_id_foreign";`);
- this.addSql(`alter table "discord_verification" drop constraint "discord_verification_auth_id_foreign";`);
- this.addSql(`alter table "discord_role_sync_attempt" drop constraint "discord_role_sync_attempt_auth_id_foreign";`);
- this.addSql(`alter table "discord_member" drop constraint "discord_member_auth_id_foreign";`);
- this.addSql(`alter table "core_user_data" drop constraint "core_user_data_auth_id_foreign";`);
- this.addSql(`alter table "core_user_ban" drop constraint "core_user_ban_auth_id_foreign";`);
- this.addSql(`alter table "core_user_ban" drop constraint "core_user_ban_banned_by_auth_id_foreign";`);
- this.addSql(`alter table "core_setting" drop constraint "core_setting_created_by_auth_id_foreign";`);
- this.addSql(`alter table "core_setting" drop constraint "core_setting_updated_by_auth_id_foreign";`);
- this.addSql(`alter table "core_rsvp" drop constraint "core_rsvp_auth_id_foreign";`);
- this.addSql(`alter table "core_rsvp" drop constraint "core_rsvp_cancelled_by_auth_id_foreign";`);
- this.addSql(`alter table "core_rsvp" drop constraint "core_rsvp_promoted_by_auth_id_foreign";`);
- this.addSql(`alter table "core_notification_intent" drop constraint "core_notification_intent_recipient_auth_id_foreign";`);
- this.addSql(`alter table "core_hacker" drop constraint "core_hacker_auth_id_foreign";`);
- this.addSql(`alter table "core_event_scan" drop constraint "core_event_scan_auth_id_foreign";`);
- this.addSql(`alter table "core_event_scan" drop constraint "core_event_scan_scanned_by_auth_id_foreign";`);
- this.addSql(`alter table "teams_team" drop constraint "teams_team_owner_auth_id_foreign";`);
- this.addSql(`alter table "teams_member" drop constraint "teams_member_auth_id_foreign";`);
- this.addSql(`alter table "teams_invite" drop constraint "teams_invite_invitee_auth_id_foreign";`);
- this.addSql(`alter table "core_notification_delivery_attempt" drop constraint "core_notification_delivery_attempt_intent_id_foreign";`);
- this.addSql(`alter table "teams_member" drop constraint "teams_member_team_id_foreign";`);
- this.addSql(`alter table "teams_invite" drop constraint "teams_invite_team_id_foreign";`);
-
- this.addSql(`drop table if exists "session" cascade;`);
- this.addSql(`drop table if exists "account" cascade;`);
- this.addSql(`drop table if exists "verification" cascade;`);
- this.addSql(`drop table if exists "core_event" cascade;`);
- this.addSql(`drop table if exists "core_operation_lock" cascade;`);
- this.addSql(`drop table if exists "core_role" cascade;`);
- this.addSql(`drop table if exists "core_user" cascade;`);
- this.addSql(`drop table if exists "discord_verification" cascade;`);
- this.addSql(`drop table if exists "discord_role_sync_attempt" cascade;`);
- this.addSql(`drop table if exists "discord_member" cascade;`);
- this.addSql(`drop table if exists "core_user_data" cascade;`);
- this.addSql(`drop table if exists "core_user_ban" cascade;`);
- this.addSql(`drop table if exists "core_setting" cascade;`);
- this.addSql(`drop table if exists "core_rsvp" cascade;`);
- this.addSql(`drop table if exists "core_notification_intent" cascade;`);
- this.addSql(`drop table if exists "core_notification_delivery_attempt" cascade;`);
- this.addSql(`drop table if exists "core_hacker" cascade;`);
- this.addSql(`drop table if exists "core_event_scan" cascade;`);
- this.addSql(`drop table if exists "teams_team" cascade;`);
- this.addSql(`drop table if exists "teams_member" cascade;`);
- this.addSql(`drop table if exists "teams_invite" cascade;`);
- }
-
-}
diff --git a/apps/web/db/migrations/sqlite/Migration20260927180400_initial.ts b/apps/web/db/migrations/sqlite/Migration20260927180400_initial.ts
deleted file mode 100644
index 7adbaced8..000000000
--- a/apps/web/db/migrations/sqlite/Migration20260927180400_initial.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { Migration } from "@mikro-orm/migrations";
-
-export class Migration20260927180400_initial extends Migration {
- override name = "Migration20260927180400_initial";
-
- override up(): void {
- this.addSql("create table `verification` (`id` text not null primary key, `identifier` text not null, `value` text not null, `expires_at` datetime not null, `created_at` datetime null, `updated_at` datetime null);");
- this.addSql("create index `verification_identifier_index` on `verification` (`identifier`);");
- this.addSql("create table `core_event` (`id` text not null primary key, `title` text not null, `start_time` datetime not null, `end_time` datetime not null, `location` text not null default 'TBD', `description` text not null, `type` text not null, `host` text null, `hidden` integer not null default false, `created_at` datetime not null, `updated_at` datetime not null);");
- this.addSql("create index `core_event_start_time_index` on `core_event` (`start_time`);");
- this.addSql("create index `core_event_type_index` on `core_event` (`type`);");
- this.addSql("create index `core_event_hidden_index` on `core_event` (`hidden`);");
- this.addSql("create table `core_operation_lock` (`key` text not null primary key, `token` text not null);");
- this.addSql("create table `core_role` (`id` text not null primary key, `name` text not null, `position` integer not null, `permissions` json not null default '[]', `color` text null, `created_at` datetime not null, `updated_at` datetime not null);");
- this.addSql("create unique index `core_role_name_unique` on `core_role` (`name`);");
- this.addSql("create index `core_role_position_index` on `core_role` (`position`);");
- this.addSql("create table `core_user` (`id` text not null primary key, `name` text not null, `email` text not null, `email_verified` integer not null default false, `profile_photo_url` text null, `hack_tag` text null, `bio` text null, `pronouns` text null, `skills` json not null default '[]', `is_profile_searchable` integer not null default true, `discord_display_handle` text null, `role_id` text null, `is_approved` integer not null default false, `checked_in_at` datetime null, `created_at` datetime not null, `updated_at` datetime not null, constraint `core_user_role_id_foreign` foreign key (`role_id`) references `core_role` (`id`) on delete set null);");
- this.addSql("create unique index `core_user_email_unique` on `core_user` (`email`);");
- this.addSql("create unique index `core_user_hack_tag_unique` on `core_user` (`hack_tag`);");
- this.addSql("create index `core_user_hack_tag_index` on `core_user` (`hack_tag`);");
- this.addSql("create index `core_user_role_id_index` on `core_user` (`role_id`);");
- this.addSql("create index `core_user_created_at_index` on `core_user` (`created_at`);");
- this.addSql("create table `discord_verification` (`code` text not null primary key, `discord_user_id` text not null, `guild_id` text not null, `username` text not null, `avatar_hash` text null, `auth_id` text null, `status` text check (`status` in ('pending', 'accepted', 'rejected', 'expired')) not null default 'pending', `expires_at` datetime not null, `created_at` datetime not null, `accepted_at` datetime null, constraint `discord_verification_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete set null);");
- this.addSql("create index `discord_verification_discord_user_id_index` on `discord_verification` (`discord_user_id`);");
- this.addSql("create index `discord_verification_guild_id_index` on `discord_verification` (`guild_id`);");
- this.addSql("create index `discord_verification_auth_id_index` on `discord_verification` (`auth_id`);");
- this.addSql("create index `discord_verification_status_index` on `discord_verification` (`status`);");
- this.addSql("create index `discord_verification_created_at_index` on `discord_verification` (`created_at`);");
- this.addSql("create table `discord_role_sync_attempt` (`id` text not null primary key, `auth_id` text not null, `discord_user_id` text not null, `guild_id` text not null, `status` text check (`status` in ('synced', 'failed', 'skipped')) not null, `role_ids` json not null default '[]', `role_names` json not null default '[]', `error` text null, `created_at` datetime not null, constraint `discord_role_sync_attempt_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete cascade);");
- this.addSql("create index `discord_role_sync_attempt_auth_id_index` on `discord_role_sync_attempt` (`auth_id`);");
- this.addSql("create index `discord_role_sync_attempt_discord_user_id_index` on `discord_role_sync_attempt` (`discord_user_id`);");
- this.addSql("create index `discord_role_sync_attempt_status_index` on `discord_role_sync_attempt` (`status`);");
- this.addSql("create index `discord_role_sync_attempt_created_at_index` on `discord_role_sync_attempt` (`created_at`);");
- this.addSql("create table `discord_member` (`auth_id` text not null primary key, `discord_user_id` text not null, `guild_id` text not null, `username` text not null, `avatar_hash` text null, `verified_at` datetime not null, `updated_at` datetime not null, `last_role_sync_at` datetime null, constraint `discord_member_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade);");
- this.addSql("create index `discord_member_auth_id_index` on `discord_member` (`auth_id`);");
- this.addSql("create unique index `discord_member_discord_user_id_unique` on `discord_member` (`discord_user_id`);");
- this.addSql("create index `discord_member_discord_user_id_index` on `discord_member` (`discord_user_id`);");
- this.addSql("create index `discord_member_guild_id_index` on `discord_member` (`guild_id`);");
- this.addSql("create index `discord_member_updated_at_index` on `discord_member` (`updated_at`);");
- this.addSql("create table `core_user_data` (`auth_id` text not null primary key, `age` integer not null, `gender` text not null, `race` text not null, `ethnicity` text not null, `shirt_size` text not null, `dietary_restrictions` json not null default '[]', `accommodation_note` text null, `phone_number` text null, `country_of_residence` text null, `has_accepted_mlhcode_of_conduct` integer not null, `has_shared_data_with_mlh` integer not null, `is_emailable` integer not null, `completed_at` datetime not null, `updated_at` datetime not null, constraint `core_user_data_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade);");
- this.addSql("create index `core_user_data_auth_id_index` on `core_user_data` (`auth_id`);");
- this.addSql("create table `core_user_ban` (`auth_id` text not null primary key, `reason` text null, `banned_by_auth_id` text not null, `created_at` datetime not null, constraint `core_user_ban_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade, constraint `core_user_ban_banned_by_auth_id_foreign` foreign key (`banned_by_auth_id`) references `core_user` (`id`));");
- this.addSql("create index `core_user_ban_auth_id_index` on `core_user_ban` (`auth_id`);");
- this.addSql("create index `core_user_ban_banned_by_auth_id_index` on `core_user_ban` (`banned_by_auth_id`);");
- this.addSql("create table `core_setting` (`key` text not null primary key, `value` json not null, `created_at` datetime not null, `created_by_auth_id` text null, `updated_at` datetime not null, `updated_by_auth_id` text null, constraint `core_setting_created_by_auth_id_foreign` foreign key (`created_by_auth_id`) references `core_user` (`id`) on delete set null, constraint `core_setting_updated_by_auth_id_foreign` foreign key (`updated_by_auth_id`) references `core_user` (`id`) on delete set null);");
- this.addSql("create index `core_setting_created_by_auth_id_index` on `core_setting` (`created_by_auth_id`);");
- this.addSql("create index `core_setting_updated_at_index` on `core_setting` (`updated_at`);");
- this.addSql("create index `core_setting_updated_by_auth_id_index` on `core_setting` (`updated_by_auth_id`);");
- this.addSql("create table `core_rsvp` (`auth_id` text not null primary key, `status` text check (`status` in ('confirmed', 'waitlisted', 'cancelled')) not null, `waitlist_position` integer null, `created_at` datetime not null, `updated_at` datetime not null, `confirmed_at` datetime null, `waitlisted_at` datetime null, `cancelled_at` datetime null, `cancelled_by_auth_id` text null, `promoted_at` datetime null, `promoted_by_auth_id` text null, constraint `core_rsvp_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade, constraint `core_rsvp_cancelled_by_auth_id_foreign` foreign key (`cancelled_by_auth_id`) references `core_user` (`id`) on delete set null, constraint `core_rsvp_promoted_by_auth_id_foreign` foreign key (`promoted_by_auth_id`) references `core_user` (`id`) on delete set null);");
- this.addSql("create index `core_rsvp_auth_id_index` on `core_rsvp` (`auth_id`);");
- this.addSql("create index `core_rsvp_cancelled_by_auth_id_index` on `core_rsvp` (`cancelled_by_auth_id`);");
- this.addSql("create index `core_rsvp_promoted_by_auth_id_index` on `core_rsvp` (`promoted_by_auth_id`);");
- this.addSql("create index `core_rsvp_status_index` on `core_rsvp` (`status`);");
- this.addSql("create index `core_rsvp_waitlist_position_index` on `core_rsvp` (`waitlist_position`);");
- this.addSql("create index `core_rsvp_created_at_index` on `core_rsvp` (`created_at`);");
- this.addSql("create index `core_rsvp_updated_at_index` on `core_rsvp` (`updated_at`);");
- this.addSql("create table `core_notification_intent` (`id` text not null primary key, `kind` text not null, `recipient_auth_id` text null, `payload` json not null, `status` text check (`status` in ('pending', 'processing', 'delivered', 'failed', 'skipped')) not null default 'pending', `idempotency_key` text null, `created_at` datetime not null, `updated_at` datetime not null, constraint `core_notification_intent_recipient_auth_id_foreign` foreign key (`recipient_auth_id`) references `core_user` (`id`) on delete set null);");
- this.addSql("create unique index `core_notification_intent_idempotency_key_unique` on `core_notification_intent` (`idempotency_key`);");
- this.addSql("create index `core_notification_intent_kind_index` on `core_notification_intent` (`kind`);");
- this.addSql("create index `core_notification_intent_recipient_auth_id_index` on `core_notification_intent` (`recipient_auth_id`);");
- this.addSql("create index `core_notification_intent_status_index` on `core_notification_intent` (`status`);");
- this.addSql("create index `core_notification_intent_created_at_index` on `core_notification_intent` (`created_at`);");
- this.addSql("create table `core_notification_delivery_attempt` (`id` text not null primary key, `intent_id` text not null, `channel` text not null, `provider` text null, `status` text check (`status` in ('delivered', 'failed', 'skipped')) not null, `recipient` text null, `external_id` text null, `error` text null, `metadata` json not null, `attempted_at` datetime not null, constraint `core_notification_delivery_attempt_intent_id_foreign` foreign key (`intent_id`) references `core_notification_intent` (`id`) on delete cascade);");
- this.addSql("create index `core_notification_delivery_attempt_intent_id_index` on `core_notification_delivery_attempt` (`intent_id`);");
- this.addSql("create index `core_notification_delivery_attempt_channel_index` on `core_notification_delivery_attempt` (`channel`);");
- this.addSql("create index `core_notification_delivery_attempt_status_index` on `core_notification_delivery_attempt` (`status`);");
- this.addSql("create index `core_notification_delivery_attempt_attempted_at_index` on `core_notification_delivery_attempt` (`attempted_at`);");
- this.addSql("create table `core_hacker` (`auth_id` text not null primary key, `university` text not null, `major` text not null, `school_id` text null, `level_of_study` text not null, `hackathons_attended` integer not null, `software_experience` text not null, `heard_from` text null, `github_url` text null, `linked_in_url` text null, `personal_website_url` text null, `resume_url` text null, `group` text null, `registered_at` datetime not null, `updated_at` datetime not null, constraint `core_hacker_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on update cascade on delete cascade);");
- this.addSql("create index `core_hacker_auth_id_index` on `core_hacker` (`auth_id`);");
- this.addSql("create index `core_hacker_registered_at_index` on `core_hacker` (`registered_at`);");
- this.addSql("create table `core_event_scan` (`id` text not null primary key, `event_id` text not null, `auth_id` text not null, `scanned_by_auth_id` text not null, `scanned_at` datetime not null, constraint `core_event_scan_event_id_foreign` foreign key (`event_id`) references `core_event` (`id`) on delete cascade, constraint `core_event_scan_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete cascade, constraint `core_event_scan_scanned_by_auth_id_foreign` foreign key (`scanned_by_auth_id`) references `core_user` (`id`));");
- this.addSql("create index `core_event_scan_scanned_by_auth_id_index` on `core_event_scan` (`scanned_by_auth_id`);");
- this.addSql("create index `core_event_scan_event_id_index` on `core_event_scan` (`event_id`);");
- this.addSql("create index `core_event_scan_auth_id_index` on `core_event_scan` (`auth_id`);");
- this.addSql("create index `core_event_scan_event_id_auth_id_index` on `core_event_scan` (`event_id`, `auth_id`);");
- this.addSql("create index `core_event_scan_scanned_at_index` on `core_event_scan` (`scanned_at`);");
- this.addSql("create table `session` (`id` text not null primary key, `expires_at` datetime not null, `token` text not null, `created_at` datetime not null, `updated_at` datetime not null, `ip_address` text null, `user_agent` text null, `user_id` text not null, constraint `session_user_id_foreign` foreign key (`user_id`) references `core_user` (`id`) on delete cascade);");
- this.addSql("create unique index `session_token_unique` on `session` (`token`);");
- this.addSql("create index `session_user_id_index` on `session` (`user_id`);");
- this.addSql("create table `account` (`id` text not null primary key, `account_id` text not null, `provider_id` text not null, `user_id` text not null, `access_token` text null, `refresh_token` text null, `id_token` text null, `access_token_expires_at` datetime null, `refresh_token_expires_at` datetime null, `scope` text null, `password` text null, `created_at` datetime not null, `updated_at` datetime not null, constraint `account_user_id_foreign` foreign key (`user_id`) references `core_user` (`id`) on delete cascade);");
- this.addSql("create index `account_user_id_index` on `account` (`user_id`);");
- this.addSql("create table `teams_team` (`id` text not null primary key, `name` text not null, `tag` text not null, `owner_auth_id` text not null, `created_at` datetime not null, constraint `teams_team_owner_auth_id_foreign` foreign key (`owner_auth_id`) references `core_user` (`id`) on delete cascade);");
- this.addSql("create unique index `teams_team_tag_unique` on `teams_team` (`tag`);");
- this.addSql("create index `teams_team_tag_index` on `teams_team` (`tag`);");
- this.addSql("create index `teams_team_owner_auth_id_index` on `teams_team` (`owner_auth_id`);");
- this.addSql("create table `teams_member` (`id` text not null primary key, `team_id` text not null, `auth_id` text not null, `joined_at` datetime not null, constraint `teams_member_team_id_foreign` foreign key (`team_id`) references `teams_team` (`id`) on delete cascade, constraint `teams_member_auth_id_foreign` foreign key (`auth_id`) references `core_user` (`id`) on delete cascade);");
- this.addSql("create unique index `teams_member_auth_id_unique` on `teams_member` (`auth_id`);");
- this.addSql("create index `teams_member_team_id_index` on `teams_member` (`team_id`);");
- this.addSql("create index `teams_member_auth_id_index` on `teams_member` (`auth_id`);");
- this.addSql("create table `teams_invite` (`id` text not null primary key, `team_id` text not null, `invitee_auth_id` text not null, `status` text check (`status` in ('pending', 'accepted', 'declined')) not null default 'pending', `created_at` datetime not null, constraint `teams_invite_team_id_foreign` foreign key (`team_id`) references `teams_team` (`id`) on delete cascade, constraint `teams_invite_invitee_auth_id_foreign` foreign key (`invitee_auth_id`) references `core_user` (`id`) on delete cascade);");
- this.addSql("create index `teams_invite_team_id_index` on `teams_invite` (`team_id`);");
- this.addSql("create index `teams_invite_invitee_auth_id_index` on `teams_invite` (`invitee_auth_id`);");
- this.addSql("create index `teams_invite_team_id_invitee_auth_id_index` on `teams_invite` (`team_id`, `invitee_auth_id`);");
- }
-
- override down(): void {
- this.addSql("drop table if exists `teams_invite`;");
- this.addSql("drop table if exists `teams_member`;");
- this.addSql("drop table if exists `teams_team`;");
- this.addSql("drop table if exists `account`;");
- this.addSql("drop table if exists `session`;");
- this.addSql("drop table if exists `core_event_scan`;");
- this.addSql("drop table if exists `core_hacker`;");
- this.addSql("drop table if exists `core_notification_delivery_attempt`;");
- this.addSql("drop table if exists `core_notification_intent`;");
- this.addSql("drop table if exists `core_rsvp`;");
- this.addSql("drop table if exists `core_setting`;");
- this.addSql("drop table if exists `core_user_ban`;");
- this.addSql("drop table if exists `core_user_data`;");
- this.addSql("drop table if exists `discord_member`;");
- this.addSql("drop table if exists `discord_role_sync_attempt`;");
- this.addSql("drop table if exists `discord_verification`;");
- this.addSql("drop table if exists `core_user`;");
- this.addSql("drop table if exists `core_role`;");
- this.addSql("drop table if exists `core_operation_lock`;");
- this.addSql("drop table if exists `core_event`;");
- this.addSql("drop table if exists `verification`;");
- }
-}
diff --git a/apps/web/scripts/test-db-workflow.sh b/apps/web/scripts/test-db-workflow.sh
deleted file mode 100644
index e464fc62d..000000000
--- a/apps/web/scripts/test-db-workflow.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
-TEST_DIR="$(mktemp -d "${TMPDIR:-/tmp}/hackkit-db-workflow.XXXXXX")"
-export HACKKIT_DATABASE_DIALECT=sqlite
-trap 'rm -rf "$TEST_DIR"' EXIT
-
-cd "$ROOT"
-
-DATABASE_URL="file:$TEST_DIR/sync-must-not-connect.db" pnpm sync
-test ! -e "$TEST_DIR/sync-must-not-connect.db"
-
-# Exercise the actual Node entry point, including check's nonzero exit code.
-DATABASE_URL="file:$TEST_DIR/selected.db" node scripts/db.mjs status >"$TEST_DIR/status.json"
-if DATABASE_URL="file:$TEST_DIR/selected.db" node scripts/db.mjs check >"$TEST_DIR/check.json"; then
- echo "db:check accepted an unmigrated database" >&2
- exit 1
-fi
-node --input-type=module -e '
- import assert from "node:assert/strict";
- import { readFileSync } from "node:fs";
- const status = JSON.parse(readFileSync(process.argv[1], "utf8"));
- const check = JSON.parse(readFileSync(process.argv[2], "utf8"));
- assert.equal(status.executed.length, 0);
- assert.equal(status.pending.length, 1);
- assert.equal(check.ok, false);
- assert.equal(check.needsMigration, false);
- assert.ok(check.schemaSql.includes("core_user"));
-' "$TEST_DIR/status.json" "$TEST_DIR/check.json"
-
-if DATABASE_URL="libsql://remote.example.com" pnpm db:reset >/dev/null 2>&1; then
- echo "db:reset accepted a remote URL" >&2
- exit 1
-fi
-
-printf 'leave me alone\n' >"$TEST_DIR/untouched.db"
-DATABASE_URL="file:$TEST_DIR/selected.db" pnpm db:reset
-DATABASE_URL="file:$TEST_DIR/selected.db" node scripts/db.mjs check >"$TEST_DIR/checked.json"
-
-test -f "$TEST_DIR/selected.db"
-test "$(cat "$TEST_DIR/untouched.db")" = "leave me alone"
-
-node --input-type=module -e '
- import { MikroORM, SqliteDriver } from "@mikro-orm/sqlite";
- import { coreModels, authEntities } from "@hackkit/core";
- const orm = await MikroORM.init({driver: SqliteDriver, dbName: process.argv[1], entities: [...Object.values(coreModels), ...authEntities]});
- try {
- const roles = await orm.em.fork().find(coreModels.role, {}, {orderBy: {id: "asc"}});
- if (JSON.stringify(roles.map(role => role.id)) !== JSON.stringify(["core.owner", "core.participant"])) process.exitCode = 1;
- } finally { await orm.close(); }
-' "$TEST_DIR/selected.db"
-
-echo "Database workflow isolation checks passed."
diff --git a/apps/web/scripts/test-runtime.mjs b/apps/web/scripts/test-runtime.mjs
deleted file mode 100644
index 75f49f799..000000000
--- a/apps/web/scripts/test-runtime.mjs
+++ /dev/null
@@ -1,236 +0,0 @@
-import assert from "node:assert/strict";
-import { createHackkitClient } from "@hackkit/core/http/client";
-import { spawn } from "node:child_process";
-import { once } from "node:events";
-import { mkdtemp, rm } from "node:fs/promises";
-import { tmpdir } from "node:os";
-import { join } from "node:path";
-import { fileURLToPath } from "node:url";
-import { setTimeout } from "node:timers/promises";
-
-// Exercise the production build against a new disposable database on every run.
-const directory = await mkdtemp(join(tmpdir(), "hackkit-http-"));
-const port = 33017;
-const baseURL = `http://127.0.0.1:${port}`;
-const env = {
- PATH: process.env.PATH,
- NODE_ENV: "production",
- NEXT_TELEMETRY_DISABLED: "1",
- DATABASE_URL: `file:${join(directory, "web.db")}`,
- HACKKIT_DATABASE_DIALECT: "sqlite",
- NEXT_PUBLIC_APP_URL: baseURL,
- BETTER_AUTH_URL: baseURL,
- BETTER_AUTH_SECRET: "isolated-http-test-secret-with-at-least-32-characters",
- HACKKIT_EMAIL_PROVIDER: "none",
- HACKKIT_BLOB_ADAPTER: "s3",
- HACKKIT_S3_BUCKET: "test",
- HACKKIT_S3_REGION: "auto",
- HACKKIT_S3_ENDPOINT: "https://example.invalid",
- HACKKIT_S3_ACCESS_KEY_ID: "test",
- HACKKIT_S3_SECRET_ACCESS_KEY: "test",
- DISCORD_GUILD_ID: "test",
- DISCORD_BOT_API_URL: "https://example.invalid",
- DISCORD_INTERNAL_AUTH_KEY: "test",
- DISCORD_PARTICIPANT_ROLE_ID: "test",
-};
-
-async function run(...args) {
- const command = spawn(process.execPath, args, { env, stdio: "inherit" });
- const [code] = await once(command, "exit");
- assert.equal(code, 0, `Command failed: ${args.join(" ")}`);
-}
-
-let server;
-try {
- const cli = join(
- process.cwd(),
- "node_modules/@hackkit/cli/bin/hackkit.mjs",
- );
- await run(cli, "db", "migrate");
- await run(cli, "db", "seed");
- server = spawn(
- process.execPath,
- [
- fileURLToPath(import.meta.resolve("next/dist/bin/next")),
- "start",
- "-p",
- String(port),
- "-H",
- "127.0.0.1",
- ],
- { env, stdio: "inherit" },
- );
- let ready = false;
- for (let attempt = 0; attempt < 40; attempt++) {
- if (server.exitCode !== null)
- throw new Error("Next exited before becoming ready.");
- try {
- const response = await fetch(`${baseURL}/api/auth/get-session`);
- ready = response.ok;
- } catch {
- /* Server may still be starting. */
- }
- if (ready) break;
- await setTimeout(250);
- }
- assert.ok(ready, "Next did not become ready.");
-
- const accounts = [];
- for (const name of ["First", "Second"]) {
- const response = await fetch(`${baseURL}/api/auth/sign-up/email`, {
- method: "POST",
- headers: { "content-type": "application/json", origin: baseURL },
- body: JSON.stringify({
- name: `HTTP ${name}`,
- email: `${name.toLowerCase()}@example.com`,
- password: "a sufficiently long password",
- }),
- });
- assert.equal(response.status, 200);
- const body = await response.json();
- const cookie = response.headers
- .getSetCookie()
- .map((value) => value.split(";")[0])
- .join("; ");
- assert.ok(cookie.includes("better-auth.session_token="));
- accounts.push({ id: body.user.id, cookie });
- }
-
- for (const account of accounts) {
- const headers = { cookie: account.cookie };
- const session = await fetch(`${baseURL}/api/auth/get-session`, {
- headers,
- }).then((response) => response.json());
- assert.equal(session.user.id, account.id);
- const page = await fetch(`${baseURL}/onboarding/hacktag`, {
- headers,
- redirect: "manual",
- });
- assert.equal(page.status, 200);
- assert.ok(!(await page.text()).includes("data-next-error-message"));
- const forbidden = await fetch(`${baseURL}/api/admin/export`, {
- headers,
- });
- assert.equal(forbidden.status, 403);
- }
- assert.equal(
- await fetch(`${baseURL}/api/auth/get-session`).then((response) =>
- response.json(),
- ),
- null,
- );
- assert.equal(
- (await fetch(`${baseURL}/dashboard`, { redirect: "manual" })).status,
- 307,
- );
- assert.equal((await fetch(`${baseURL}/api/admin/export`)).status, 401);
- const client = createHackkitClient({
- baseURL: baseURL + "/api/hackkit",
- });
- const callOptions = accounts.map((account) => ({
- headers: { cookie: account.cookie, origin: baseURL },
- }));
- const tags = ["http-first", "http-second"];
- const claimed = await Promise.all(
- accounts.map((_, index) =>
- client("@post/users/claim-hack-tag", {
- body: { hackTag: tags[index] },
- ...callOptions[index],
- }),
- ),
- );
- assert.deepEqual(
- claimed.map((result) => result.data?.id),
- accounts.map((account) => account.id),
- );
- assert.equal(typeof claimed[0].data.createdAt, "string");
- const unauthenticated = await client("@post/users/claim-hack-tag", {
- body: { hackTag: "anon" },
- headers: { origin: baseURL },
- });
- assert.equal(unauthenticated.error.code, "UNAUTHORIZED");
- assert.equal(unauthenticated.error.status, 401);
- const forbidden = await client("@post/roles/create", {
- body: { name: "Forbidden", position: 0, permissions: [] },
- ...callOptions[0],
- });
- assert.equal(forbidden.error.status, 403);
- const spoof = await fetch(baseURL + "/api/hackkit/users/claim-hack-tag", {
- method: "POST",
- headers: {
- ...callOptions[0].headers,
- "content-type": "application/json",
- },
- body: JSON.stringify({ hackTag: "spoof", authId: accounts[1].id }),
- });
- assert.equal(spoof.status, 400);
- for (let index = 0; index < accounts.length; index++) {
- const data = await client("@post/user-data/complete", {
- body: {
- age: 20,
- gender: "prefer_not_to_answer",
- race: "prefer_not_to_answer",
- ethnicity: "prefer_not_to_answer",
- shirtSize: "m",
- dietaryRestrictions: ["none"],
- hasAcceptedMLHCodeOfConduct: true,
- hasSharedDataWithMLH: true,
- isEmailable: true,
- },
- ...callOptions[index],
- });
- assert.equal(data.error, null, JSON.stringify(data.error));
- const registration = await client("@post/hackers/register", {
- body: {
- university: "Test University",
- major: "CS",
- levelOfStudy: "undergraduate",
- hackathonsAttended: 0,
- softwareExperience: "beginner",
- },
- ...callOptions[index],
- });
- assert.equal(
- registration.error,
- null,
- JSON.stringify(registration.error),
- );
- assert.equal(registration.data.userId, accounts[index].id);
- }
- const team = await client("@post/teams/create", {
- body: { name: "HTTP team", tag: "http-team" },
- ...callOptions[0],
- });
- assert.equal(team.error, null, JSON.stringify(team.error));
- assert.equal(team.data.ownerAuthId, accounts[0].id);
- const invite = await client("@post/teams/invite", {
- body: { teamId: team.data.id, hackTag: tags[1] },
- ...callOptions[0],
- });
- assert.equal(invite.error, null, JSON.stringify(invite.error));
- const accepted = await client("@post/teams/respond-to-invite", {
- body: { inviteId: invite.data.id, accept: true },
- ...callOptions[1],
- });
- assert.equal(accepted.error, null, JSON.stringify(accepted.error));
- const left = await client("@post/teams/leave", callOptions[1]);
- assert.deepEqual(left, { data: null, error: null });
- const ownerCannotLeave = await client("@post/teams/leave", callOptions[0]);
- assert.equal(ownerCannotLeave.error.status, 422);
- const discord = await client("@post/discord/confirm-verification", {
- body: { code: "missing-code" },
- ...callOptions[0],
- });
- assert.equal(discord.error.status, 404);
-
- console.log(
- "Passed: HTTP signup, isolated sessions, onboarding rendering, Core and Teams path mutations, actor rejection, permissions, and Discord routing.",
- );
-} finally {
- if (server && server.exitCode === null) {
- const exited = once(server, "exit");
- server.kill("SIGTERM");
- await exited;
- }
- await rm(directory, { recursive: true, force: true });
-}
diff --git a/contributions.md b/contributions.md
index 06db94926..6b914a4e5 100644
--- a/contributions.md
+++ b/contributions.md
@@ -2,8 +2,8 @@
**Thanks to the following awesome people for supporting the development of the project in various ways! Without y'all it would not have been possible!**
-- RowdyHacks Tech Team
-- RowdyHacks Design Team
-- UTSA Hackkit Team
-- [Google Fonts](https://fonts.google.com/)
-- [Shadcn](https://ui.shadcn.com/)
+- RowdyHacks Tech Team
+- RowdyHacks Design Team
+- UTSA Hackkit Team
+- [Google Fonts](https://fonts.google.com/)
+- [Shadcn](https://ui.shadcn.com/)
diff --git a/docs/adr/0007-event-pass-qr-in-hackkit-ui.md b/docs/adr/0007-event-pass-qr-in-hackkit-ui.md
index 0d1d2eb21..c37e92c2c 100644
--- a/docs/adr/0007-event-pass-qr-in-hackkit-ui.md
+++ b/docs/adr/0007-event-pass-qr-in-hackkit-ui.md
@@ -10,13 +10,13 @@ Early Core implementations coupled QR validation to `users.checkIn` and `events.
## Decision
-- Remove QR-specific fields and validation from Core User/Event APIs.
-- Implement Event Pass QR helpers in `@hackkit/ui`.
-- Parse and validate raw QR in `@hackkit/next` mutations (`previewEventPassQr`, `checkInUser`, `recordEventScan`).
-- Keep scanner UX in HackKit UI with client-only scan state; confirm sends `rawQr` to server actions.
+- Remove QR-specific fields and validation from Core User/Event APIs.
+- Implement Event Pass QR helpers in `@hackkit/ui`.
+- Parse and validate raw QR in `@hackkit/next` mutations (`previewEventPassQr`, `checkInUser`, `recordEventScan`).
+- Keep scanner UX in HackKit UI with client-only scan state; confirm sends `rawQr` to server actions.
## Consequences
-- Core stays framework- and presentation-free; alternate check-in UIs can call the same Core APIs.
-- Apps configure Event Pass QR TTL when wiring `HackKitUIProvider` and mutations, not via `createHackkit`.
-- Security depends on server-side QR validation in mutations, not URL query parameters.
+- Core stays framework- and presentation-free; alternate check-in UIs can call the same Core APIs.
+- Apps configure Event Pass QR TTL when wiring `HackKitUIProvider` and mutations, not via `createHackkit`.
+- Security depends on server-side QR validation in mutations, not URL query parameters.
diff --git a/docs/adr/0010-hackkit-logger.md b/docs/adr/0010-hackkit-logger.md
index f5f8350f9..985097c3b 100644
--- a/docs/adr/0010-hackkit-logger.md
+++ b/docs/adr/0010-hackkit-logger.md
@@ -4,29 +4,29 @@ HackKit exposes a replaceable **HackKit Logger** at `initializeHackkit` and in `
## Context
-- Legacy **apps/web** persisted errors in an `error_log` table via `logError`, separate from framework diagnostics.
-- **HackKit Core** had no logging contract; Better Auth already supports its own `logger` on `betterAuth({ ... })`.
-- Operators need visibility into domain actions (registration, approval, check-in) without storing PII in the database or coupling Core to a specific vendor (Datadog, Sentry, stdout).
+- Legacy **apps/web** persisted errors in an `error_log` table via `logError`, separate from framework diagnostics.
+- **HackKit Core** had no logging contract; Better Auth already supports its own `logger` on `betterAuth({ ... })`.
+- Operators need visibility into domain actions (registration, approval, check-in) without storing PII in the database or coupling Core to a specific vendor (Datadog, Sentry, stdout).
## Decision
-- Define a **HackKit Logger** type in **HackKit Core** with levels `debug` | `info` | `warn` | `error`, `disabled`, and optional custom `log`.
-- Ship a default console implementation when the app omits `logger`.
-- Default minimum **Log Level**: `info` when `NODE_ENV` is development, `warn` in production, overridable in config.
-- **HackKit Core** logs significant domain API calls (e.g. **Hacker Registration**, **Organiser Approval**, **Hackathon Check-in**) with **Log Context**: action name, outcome, **Auth ID**s, stable record ids, and **HackKit** error code/message on failure — never emails, names, or form payloads.
-- **HackKit CLI** commands run from a **HackKit Web App** directory read the same `logger` from `hackkit.config.ts`, falling back to the environment-based default when omitted.
-- **HackKit Core** bridges the app’s **HackKit Logger** into Better Auth’s `logger.log` so one custom implementation in config can cover auth and Core output.
+- Define a **HackKit Logger** type in **HackKit Core** with levels `debug` | `info` | `warn` | `error`, `disabled`, and optional custom `log`.
+- Ship a default console implementation when the app omits `logger`.
+- Default minimum **Log Level**: `info` when `NODE_ENV` is development, `warn` in production, overridable in config.
+- **HackKit Core** logs significant domain API calls (e.g. **Hacker Registration**, **Organiser Approval**, **Hackathon Check-in**) with **Log Context**: action name, outcome, **Auth ID**s, stable record ids, and **HackKit** error code/message on failure — never emails, names, or form payloads.
+- **HackKit CLI** commands run from a **HackKit Web App** directory read the same `logger` from `hackkit.config.ts`, falling back to the environment-based default when omitted.
+- **HackKit Core** bridges the app’s **HackKit Logger** into Better Auth’s `logger.log` so one custom implementation in config can cover auth and Core output.
## Alternatives considered
-- **Persisted error/audit tables** — Rejected for this milestone; different retention, query, and compliance model than framework logging.
-- **Stdout-only, no contract** — Rejected; apps could not forward to hosted logging without forking Core.
-- **Independent Better Auth logger only** — Rejected; duplicate config and divergent formats in typical apps.
-- **Verbose `debug` payloads (form fields)** — Rejected; PII risk and weak redaction story across custom loggers.
+- **Persisted error/audit tables** — Rejected for this milestone; different retention, query, and compliance model than framework logging.
+- **Stdout-only, no contract** — Rejected; apps could not forward to hosted logging without forking Core.
+- **Independent Better Auth logger only** — Rejected; duplicate config and divergent formats in typical apps.
+- **Verbose `debug` payloads (form fields)** — Rejected; PII risk and weak redaction story across custom loggers.
## Consequences
-- No SQL `error_log` parity in v1; organisers who need searchable error history may add a custom logger that writes to their store.
-- Core gains a small amount of logging overhead on hot paths; keep messages cheap and level-gated.
-- Custom loggers must treat **Log Context** as potentially sensitive even without full payloads (Auth IDs are still identifiers).
-- Better Auth internal messages and HackKit domain messages share one pipeline when the bridge is used; apps that need separation can pass different implementations to Core vs `config.auth.logger`.
+- No SQL `error_log` parity in v1; organisers who need searchable error history may add a custom logger that writes to their store.
+- Core gains a small amount of logging overhead on hot paths; keep messages cheap and level-gated.
+- Custom loggers must treat **Log Context** as potentially sensitive even without full payloads (Auth IDs are still identifiers).
+- Better Auth internal messages and HackKit domain messages share one pipeline when the bridge is used; apps that need separation can pass different implementations to Core vs `config.auth.logger`.
diff --git a/docs/adr/0011-blob-storage-and-stored-file-references.md b/docs/adr/0011-blob-storage-and-stored-file-references.md
index ab1d8dc3b..82e2a86e5 100644
--- a/docs/adr/0011-blob-storage-and-stored-file-references.md
+++ b/docs/adr/0011-blob-storage-and-stored-file-references.md
@@ -4,29 +4,29 @@ Files (e.g. resumes on **Hacker Registration**) are stored outside **HackKit Cor
## Context
-- Legacy **apps/web** used R2 presigned uploads and app routes (`/api/upload/resume/...`) that return app-relative view URLs stored on hacker rows.
-- **HackKit Core** already has optional `resumeUrl` on **Hacker**; there was no adapter boundary, and resume “missing” used a legacy sentinel URL constant.
-- **Competitor Onboarding** this milestone includes resume upload in **HackKit UI** with web defaulting to local storage for contributors without cloud credentials.
+- Legacy **apps/web** used R2 presigned uploads and app routes (`/api/upload/resume/...`) that return app-relative view URLs stored on hacker rows.
+- **HackKit Core** already has optional `resumeUrl` on **Hacker**; there was no adapter boundary, and resume “missing” used a legacy sentinel URL constant.
+- **Competitor Onboarding** this milestone includes resume upload in **HackKit UI** with web defaulting to local storage for contributors without cloud credentials.
## Decision
-- Define **Blob Storage Adapter** in **HackKit Core**; implement `@hackkit/blob-local` and `@hackkit/blob-s3` (or equivalent names) as separate packages.
-- **HackKit Web Apps** select an implementation in `hackkit.config.ts`; web defaults to local.
-- After upload, the app passes a **Stored File Reference** (app-relative URL) into Core APIs; Core does not talk to blob backends directly.
-- Resume is optional: omit `resumeUrl` when the user skips upload; no sentinel “no resume provided” string in Core records.
-- **HackKit UI** **Hacker Registration** form accepts upload via app-provided handlers; resulting URL is submitted with `registerHacker`.
+- Define **Blob Storage Adapter** in **HackKit Core**; implement `@hackkit/blob-local` and `@hackkit/blob-s3` (or equivalent names) as separate packages.
+- **HackKit Web Apps** select an implementation in `hackkit.config.ts`; web defaults to local.
+- After upload, the app passes a **Stored File Reference** (app-relative URL) into Core APIs; Core does not talk to blob backends directly.
+- Resume is optional: omit `resumeUrl` when the user skips upload; no sentinel “no resume provided” string in Core records.
+- **HackKit UI** **Hacker Registration** form accepts upload via app-provided handlers; resulting URL is submitted with `registerHacker`.
## Alternatives considered
-- **Direct public CDN URLs in Core** — Rejected; host/bucket changes invalidate rows and leak infrastructure into the domain.
-- **Opaque storage keys only in Core** — Rejected for v1; every read path would need adapter resolution in UI and exports; more wiring before onboarding ships.
-- **Core-owned file model / attachment entity** — Rejected; glossary keeps blobs at the adapter boundary.
-- **Single backend hard-coded in Core** — Rejected; prevents local dev without cloud keys.
-- **Legacy sentinel URL for “no resume”** — Rejected; optional field is sufficient for v1 reporting (`resumeUrl` present vs absent).
+- **Direct public CDN URLs in Core** — Rejected; host/bucket changes invalidate rows and leak infrastructure into the domain.
+- **Opaque storage keys only in Core** — Rejected for v1; every read path would need adapter resolution in UI and exports; more wiring before onboarding ships.
+- **Core-owned file model / attachment entity** — Rejected; glossary keeps blobs at the adapter boundary.
+- **Single backend hard-coded in Core** — Rejected; prevents local dev without cloud keys.
+- **Legacy sentinel URL for “no resume”** — Rejected; optional field is sufficient for v1 reporting (`resumeUrl` present vs absent).
## Consequences
-- Each **HackKit Web App** must implement routes that serve or proxy files for **Stored File References** (local read path vs S3 redirect/proxy).
-- Switching from local to S3 does not require migrating Core rows if URL shape stays app-relative and keys remain stable in the query/path convention.
-- Upload security (auth, content type, size limits) stays in the Web App and adapter packages, not in Core validation of `registerHackerSchema` alone.
-- Plugins or future file types reuse the same adapter contract; avoid ad hoc upload routes per feature without extending the adapter interface deliberately.
+- Each **HackKit Web App** must implement routes that serve or proxy files for **Stored File References** (local read path vs S3 redirect/proxy).
+- Switching from local to S3 does not require migrating Core rows if URL shape stays app-relative and keys remain stable in the query/path convention.
+- Upload security (auth, content type, size limits) stays in the Web App and adapter packages, not in Core validation of `registerHackerSchema` alone.
+- Plugins or future file types reuse the same adapter contract; avoid ad hoc upload routes per feature without extending the adapter interface deliberately.
diff --git a/docs/adr/0013-mikroorm-and-core-auth.md b/docs/adr/0013-mikroorm-and-core-auth.md
index 5b6f33112..be91e6972 100644
--- a/docs/adr/0013-mikroorm-and-core-auth.md
+++ b/docs/adr/0013-mikroorm-and-core-auth.md
@@ -10,13 +10,13 @@ Core and server plugins use native MikroORM `defineEntity` definitions and `Enti
Core's `src/runtime.ts` owns HackKit initialization, shared authentication, logging, and execution scopes. `src/mikro/options.ts` owns native ORM options and driver types. Both remain available through the `@hackkit/core` package entrypoint.
-One ORM owns shared connections. Each request, action, job, or CLI operation gets a fresh EntityManager. `runtime.createScope(actorAuthId)` binds domain and plugin APIs; `runtime.run(callback, actorAuthId)` also provides MikroORM RequestContext. Transactions use a fresh identity map and clear the parent map on completion. Domain responses are plain DTOs; managed entities and authentication secrets stay on the server. Browser code imports `@hackkit/core/client`.
+One ORM owns shared connections. Runtime initialization prepares domain configuration, validation schemas, and the logger once. Scoped APIs reuse that preparation while binding an execution-specific EntityManager and actor ID. Each request, action, job, or CLI operation gets a fresh EntityManager. `runtime.createScope(actorAuthId)` binds domain and plugin APIs; `runtime.run(callback, actorAuthId)` also provides MikroORM RequestContext and binds APIs directly to its single fork. Transactions use a fresh identity map and clear the parent map on completion. Domain responses are plain DTOs; managed entities and authentication secrets stay on the server. Browser code imports `@hackkit/core/client`.
## Authentication
Core constructs Better Auth with `@a77ay/better-auth-mikro-orm`. Better Auth still declares its own unused Drizzle adapter as an upstream dependency; HackKit does not import it, and `drizzle-orm` is absent from the resolved dependency graph. This community MikroORM adapter is pinned alongside Better Auth and MikroORM and covered by real database tests. Apps provide secrets, providers, trusted origins, email behavior, and optional auth plugins. Next owns request headers, cookies, redirects, and auth route handlers.
-`HackKitUser` is the canonical native entity in `core_user`. It stores the Better Auth identity fields and HackKit profile, role, approval, and check-in fields in one row. Better Auth maps its user model to `core_user` and its `image` field to `profilePhotoUrl`. The primary key is `id`; Core's inferred user DTO, public profiles, and admin exports expose this same property through native serialization. Sessions, accounts, and all domain/plugin user foreign keys reference this row.
+`HackKitUser` is the canonical native entity in `core_user`. It stores the Better Auth identity fields and HackKit profile, role, approval, and check-in fields in one row. Better Auth maps its user model to `core_user`. Its `image` field uses the same name in the native entity and Core APIs. The primary key is `id`; Core's inferred user DTO, public profiles, and admin exports expose this same property through native serialization. Sessions, accounts, and all domain/plugin user foreign keys reference this row.
Consumers of the former user DTO must replace `user.authId` with `user.id`. The admin CSV identifier column is now `id`. Hacker records and the `registerHacker` input use `userId`, which references the same user primary key. The hacker entity retains its mapping to the committed `auth_id` database column. Other operation inputs such as `authId`, `actorAuthId`, and `targetAuthId` still accept the user ID. These contract changes require no database migration.
@@ -44,7 +44,7 @@ The [migration guide](../guides/database-migrations.md) specifies staged upgrade
## Validation
-The app database matrix applies committed migrations and tests real SQLite, local libSQL, PostgreSQL, MySQL, and HTTP libSQL. It checks schema agreement, signup/session/profile behavior, native JSON/date/boolean/null values, rollback, concurrent registration capacity, teams, uniqueness, and foreign-key cleanup. Package tests cover domain authorization, request isolation, notification claims, and membership conflicts. CI requires external service URLs so those cases cannot silently skip.
+The app database matrix generates a baseline from the configured entity registry, applies it, and tests real SQLite, local libSQL, PostgreSQL, MySQL, and HTTP libSQL. It checks schema agreement, signup/session/profile behavior, native JSON/date/boolean/null values, rollback, concurrent registration capacity, teams, uniqueness, and foreign-key cleanup. Package tests cover domain authorization, request isolation, notification claims, and membership conflicts. CI requires external service URLs so those cases cannot silently skip.
Use Node.js 22.17 or newer and TypeScript 5.9.3. Production validation must also cover the deployment's credentials, TLS, OAuth providers, and external email/Discord services.
diff --git a/docs/guides/database-migrations.md b/docs/guides/database-migrations.md
index d5cabaa52..d79499cdc 100644
--- a/docs/guides/database-migrations.md
+++ b/docs/guides/database-migrations.md
@@ -2,28 +2,36 @@
The application owns one ordered migration history for Core, Better Auth, installed plugins, and application entities. Core supplies native entity definitions and a shared registry. The reference app supplies runnable scripts and database-specific configuration. Package authors supply reviewed transformation SQL and upgrade instructions when their schema changes require them.
-The scripts live in `apps/web/scripts/database.ts`, with `scripts/db.mjs` as the Node entry point. They use MikroORM's native migrator and its `mikro_orm_migrations` history table. They do not call the HackKit CLI. Plugin route/action synchronization continues to use the existing CLI.
+The scripts live in `templates/nextjs-full/scripts/database.ts`, with `scripts/db.mjs` as the Node entry point. They use MikroORM's native migrator and its `mikro_orm_migrations` history table. They do not call the HackKit CLI. Plugin route/action synchronization continues to use the existing CLI.
+
+## Initialize a new application
+
+Templates ship without migration files or schema snapshots. After configuring the database, plugins, and application entities, select an empty development database and run the selected template's `db:generate --name initial`. Review the generated TypeScript migration and snapshot, apply it with `db:migrate`, and insert roles with `db:seed`. Commit the migration and snapshot to the consuming application's repository.
+
+Generation proposes SQL; it does not apply the application tables. Without a snapshot it needs a reachable database to inspect the starting schema. Use an empty database for the initial baseline. Do not use this new-project procedure to replace an existing application's migration history or adopt an already-populated database.
+
+After the first setup, other developers and deployment jobs apply the committed history with `db:migrate`. Generate again only when registered entities change. The deployed demo is an existing application and retains its committed history.
## Commands
Run from the repository root after installing dependencies and building workspace packages:
-| Command | Behavior |
-| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
-| `pnpm --filter web db:generate --name describe_change` | Generates a migration and updates the target snapshot. Outputs the SQL proposal and potentially destructive statements. |
-| `pnpm --filter web db:generate --name backfill --blank` | Creates a migration for authored SQL. |
-| `pnpm --filter web db:status` | Lists applied and pending migrations. |
-| `pnpm --filter web db:check` | Checks metadata against the snapshot, pending history, and the live schema. Exits with status 1 when any check differs. |
-| `pnpm --filter web db:migrate` | Applies all pending migrations. |
-| `pnpm --filter web db:migrate --to Migration20261006120000_expand` | Applies up to and including the named migration. |
-| `pnpm --filter web db:rollback` | Runs the latest applied migration's `down()` method. |
-| `pnpm --filter web db:rollback --to Migration20261006120000_expand` | Reverts later migrations, leaving the named migration applied. `--to 0` reverts all. |
-| `pnpm --filter web db:seed` | Inserts missing configured role IDs. Existing roles and assignments remain unchanged. |
-| `pnpm --filter web db:reset` | In development/tests, drops registered tables and migration history in the selected local SQLite database, then migrates and seeds. |
+| Command | Behavior |
+| --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
+| `pnpm --filter @hackkit/template-nextjs-full db:generate --name describe_change` | Generates a migration and updates the target snapshot. Outputs the SQL proposal and potentially destructive statements. |
+| `pnpm --filter @hackkit/template-nextjs-full db:generate --name backfill --blank` | Creates a migration for authored SQL. |
+| `pnpm --filter @hackkit/template-nextjs-full db:status` | Lists applied and pending migrations. |
+| `pnpm --filter @hackkit/template-nextjs-full db:check` | Checks metadata against the snapshot, pending history, and the live schema. Exits with status 1 when any check differs. |
+| `pnpm --filter @hackkit/template-nextjs-full db:migrate` | Applies all pending migrations. |
+| `pnpm --filter @hackkit/template-nextjs-full db:migrate --to Migration20261006120000_expand` | Applies up to and including the named migration. |
+| `pnpm --filter @hackkit/template-nextjs-full db:rollback` | Runs the latest applied migration's `down()` method. |
+| `pnpm --filter @hackkit/template-nextjs-full db:rollback --to Migration20261006120000_expand` | Reverts later migrations, leaving the named migration applied. `--to 0` reverts all. |
+| `pnpm --filter @hackkit/template-nextjs-full db:seed` | Inserts missing configured role IDs. Existing roles and assignments remain unchanged. |
+| `pnpm --filter @hackkit/template-nextjs-full db:reset` | In development/tests, drops registered tables and migration history in the selected local SQLite database, then migrates and seeds. |
Every command accepts `--config path/to/hackkit.config.ts` and optional `--output path/to/result.json`. The output file contains the command result separately from driver diagnostics; a failed `check` still writes its result and exits with status 1. The entry point loads `.env` files with Next's environment precedence before loading the config. Explicit shell environment variables take precedence. Configuration paths and relative database paths are resolved from the application directory.
-The selected dialect determines the migration directory. PostgreSQL, MySQL, and SQLite have separate histories in `apps/web/db/migrations`; libSQL uses the SQLite history. Generate and test each supported history when changing a shared entity. A generated migration for one dialect is not a replacement for the other dialects' histories.
+The selected dialect determines the default migration directory under `db/migrations`: `postgresql`, `mysql`, or `sqlite`; libSQL uses the SQLite dialect directory. These directories and snapshots are created during generation. `HACKKIT_MIGRATIONS_PATH` overrides the path, relative to the application or absolute. E2E uses this override for temporary histories. An application maintains only the dialects it supports. If it supports several, generate and test each history; SQL generated for one dialect does not replace another dialect's history.
`status` and `check` use native migration history APIs. These APIs may create the tracking table if it does not exist. They do not apply application migrations or seed data. A database connection failure is an error, not a successful status check. Generation can use a committed snapshot without connecting; without a snapshot, MikroORM needs a database for its starting schema.
@@ -90,8 +98,8 @@ Reset rejects production and all non-SQLite drivers, including local libSQL. It
## Validation
-`pnpm --filter web test` exercises the app scripts against SQLite/local libSQL. It checks existing-data expansion/backfill/contraction, staged migration, plugin upgrade, rollback/reapply, live drift, disabled-schema retention, destructive uninstall proposals, fresh replay, and reset/seed behavior.
+`corepack pnpm test:e2e:db` generates a fresh baseline from each selected configuration and exercises the app scripts against SQLite/local libSQL. Generated histories and snapshots stay in temporary directories. It verifies generation without applying tables, schema agreement after migration, unchanged generation as a no-op, and fresh replay of the application history. It checks existing-data expansion/backfill/contraction, staged migration, plugin upgrade, rollback/reapply, live drift, disabled-schema retention, destructive uninstall proposals, fresh replay, and reset/seed behavior.
-`pnpm --filter web test:db-matrix` runs the same upgrade flow after auth/domain validation on each configured target. CI requires PostgreSQL, MySQL, and HTTP libSQL URLs; missing local targets are reported as skipped. Test URLs must name empty, disposable databases. The native libSQL client can hang when repeatedly creating and destroying ORM instances in one Node process. The HTTP upgrade test uses one Node process per command, matching the utility scripts’ release-job lifecycle. Do not run a sequence of these commands inside a long-lived application process. Hosted Turso authentication/TLS and deployment-specific runtime behavior need separate validation.
+`corepack pnpm test:e2e:db` runs the same upgrade flow after auth/domain validation on each configured target. CI requires PostgreSQL, MySQL, and HTTP libSQL URLs; missing local targets are reported as skipped. Test URLs must name empty, disposable databases. The native libSQL client can hang when repeatedly creating and destroying ORM instances in one Node process. The HTTP upgrade test uses one Node process per command, matching the utility scripts’ release-job lifecycle. Do not run a sequence of these commands inside a long-lived application process. Hosted Turso authentication/TLS and deployment-specific runtime behavior need separate validation.
Primary reference: [MikroORM 7.2 migrations](https://mikro-orm.io/docs/migrations).
diff --git a/docs/guides/next-integration.md b/docs/guides/next-integration.md
index 2a2c82501..8ba60e280 100644
--- a/docs/guides/next-integration.md
+++ b/docs/guides/next-integration.md
@@ -1,6 +1,6 @@
# Next.js integration
-HackKit uses package-owned better-call endpoints and its typed path client. `@hackkit/next` supplies Next request setup and page guards. See [its README](../../packages/next/README.md) for the interface and [the reference app](../../apps/web/README.md) for database commands.
+HackKit uses package-owned better-call endpoints and its typed path client. `@hackkit/next` supplies Next request setup and page guards. See [its README](../../packages/next/README.md) for the interface and [the reference app](../../templates/nextjs-full/README.md) for database commands.
| Concern | Owner | App integration |
| --------------------------------------- | ------------------- | ---------------------------------------------------------- |
@@ -41,4 +41,4 @@ Core endpoint definitions are grouped by domain in `packages/core/src/http/endpo
## Verification
-Use the repository-pinned pnpm through `corepack pnpm`. Run package builds, typechecks, and tests, then the web production build and `corepack pnpm --filter web test:runtime`. HTTP checks use a fresh disposable SQLite database. `node tooling/check-client-bundle.mjs` bundles the provider entry and checks its inputs for recognized server implementations.
+Use the repository-pinned pnpm through `corepack pnpm`. Run package builds, typechecks, and tests, then the web production build and `corepack pnpm test:e2e:http`. HTTP checks use a fresh disposable SQLite database. `node tooling/check-client-bundle.mjs` bundles the provider entry and checks its inputs for recognized server implementations.
diff --git a/docs/guides/package-schema-upgrades.md b/docs/guides/package-schema-upgrades.md
index 5d63ca257..5bf652b51 100644
--- a/docs/guides/package-schema-upgrades.md
+++ b/docs/guides/package-schema-upgrades.md
@@ -8,15 +8,15 @@ Store that guidance beside the package's release documentation. Keep the SQL rev
Use this checklist for each schema-changing release:
-- **Versions:** exact supported source versions and target version. State whether intermediate versions must be installed first.
-- **Entities:** added/removed/changed tables, fields, constraints, and foreign-key relationships.
-- **Expansion:** schema changes needed before the transformation, including temporary nullable fields or defaults.
-- **Transformation:** static SQL with expected input/output values, handling of nulls, empty values, and invalid legacy data. State whether rerunning is safe.
-- **Contraction:** final constraints and removals. State when old code must stop running.
-- **Application integration:** tell developers where to insert each step in their own history. Describe dependencies on other Core/plugin/app tables. Include the `db:migrate --to` boundaries where applicable.
-- **Verification:** expected schema and data assertions. Record passed versions for PostgreSQL, MySQL, SQLite, and libSQL separately; explicitly list skipped or unvalidated targets.
-- **Recovery:** supported `down()` behavior, irreversible data loss, and partial-DDL handling. MySQL must have an explicit recovery plan for failed DDL.
-- **Disabled plugins:** state whether the release changes retained schema. `enabled: false` retains entities and still participates in package schema upgrades.
+- **Versions:** exact supported source versions and target version. State whether intermediate versions must be installed first.
+- **Entities:** added/removed/changed tables, fields, constraints, and foreign-key relationships.
+- **Expansion:** schema changes needed before the transformation, including temporary nullable fields or defaults.
+- **Transformation:** static SQL with expected input/output values, handling of nulls, empty values, and invalid legacy data. State whether rerunning is safe.
+- **Contraction:** final constraints and removals. State when old code must stop running.
+- **Application integration:** tell developers where to insert each step in their own history. Describe dependencies on other Core/plugin/app tables. Include the `db:migrate --to` boundaries where applicable.
+- **Verification:** expected schema and data assertions. Record passed versions for PostgreSQL, MySQL, SQLite, and libSQL separately; explicitly list skipped or unvalidated targets.
+- **Recovery:** supported `down()` behavior, irreversible data loss, and partial-DDL handling. MySQL must have an explicit recovery plan for failed DDL.
+- **Disabled plugins:** state whether the release changes retained schema. `enabled: false` retains entities and still participates in package schema upgrades.
Use the package's frozen historical SQL in test fixtures. Apply the upgrade to the previous schema with existing Core users, plugin foreign keys, and application-owned references. Also replay the complete consuming application's history into an empty database using only current metadata.
diff --git a/docs/plans/template-distribution.md b/docs/plans/template-distribution.md
new file mode 100644
index 000000000..08b847f18
--- /dev/null
+++ b/docs/plans/template-distribution.md
@@ -0,0 +1,16 @@
+# Standalone templates and CLI initialization
+
+Status: deferred. Current templates are runnable workspace examples. Packages remain private. This change does not publish packages or add an init command.
+
+The next distribution milestone will add `hackkit init --template minimal|full`, defaulting to minimal. The command must create a complete project without overwriting an existing destination. It must not copy repository credentials, databases, uploads, build output, or test infrastructure.
+
+Required work:
+
+- Establish public package metadata, dependency versions, release versioning, and npm scope access before publication.
+- Include distributable template assets with the CLI and substitute released package versions for workspace references.
+- Make application scripts and Tailwind content discovery work without monorepo source paths.
+- Include each template's configuration, database commands, and setup documentation. After database/plugin selection, generate the new application's initial migration and snapshot against an empty development database. Do not distribute a pre-generated template migration history. The application commits its generated history and maintains future migrations.
+- Validate packed packages and both generated projects outside the monorepo. Verify initialization, dependency installation, plugin synchronization, migrations, seeding, typechecking, and production builds without workspace symlinks.
+- Review the release artifacts before publishing. Define the first release version, registry ownership, authentication, and publishing workflow as part of that milestone.
+
+Acceptance requires a working fresh project from the distributed CLI for each template. An in-workspace build alone does not establish standalone readiness.
diff --git a/e2e/README.md b/e2e/README.md
new file mode 100644
index 000000000..82a02c523
--- /dev/null
+++ b/e2e/README.md
@@ -0,0 +1,37 @@
+# HackKit end-to-end validation
+
+Tests run the actual [full](../templates/nextjs-full/README.md) and [minimal](../templates/nextjs-minimal/README.md) templates. There is no separate test application. Package tests remain beside the libraries.
+
+## Commands
+
+From the repository root, use Node.js 22.17+ and pinned pnpm 12.15.0 available on `PATH`. CI installs pnpm through `pnpm/action-setup`; the E2E runner invokes pnpm directly.
+
+1. Run `pnpm install`.
+2. Install Chromium with `pnpm --filter @hackkit/e2e exec playwright install chromium`. On Linux CI, add `--with-deps`.
+3. Run `pnpm test:e2e`.
+
+Choose `test:e2e:db`, `test:e2e:http`, or `test:e2e:browser` to run a focused suite. The runner builds library dependencies, checks plugin sync for changes, typechecks templates and E2E, and checks both browser bundles. HTTP/browser suites also generate initial migrations, migrate and check the schema, seed temporary build databases and build both production apps once. Runtime databases are separate from build databases.
+
+Stop template development servers before testing, and run one E2E invocation at a time. The fixtures use loopback ports 33017 for full and 33018 for minimal, refuse occupied ports, and never reuse an existing server. Each worker gets a new temporary database, migration history, snapshot, and upload directory. Generated migrations resolve dependencies through a temporary node_modules link. No test writes migration files into the templates. Application commands run from the selected template's directory using explicit test configuration. No developer database or uploads are selected. One Chromium worker runs without retries; browser sessions and accounts are independent. Each test supplies a distinct simulated proxy client IP so production authentication rate limits remain enabled without sharing one test-client bucket.
+
+## Coverage
+
+- `database`: initial generation, snapshot creation, migration replay, auth/domain integration, schema upgrades, drift, rollback/reapply, plugin retention, concurrency, and real application command isolation.
+- `http`: production cookies/sessions, access control, Core and plugin mutations, actor rejection, and JSON serialization. Playwright API tests do not launch a browser.
+- `browser`: signup and complete onboarding, persisted registration, signout/signin, participant/admin guards, approval state, owner access, and full-template team invitations across sessions.
+
+E2E-only database helpers promote known test user IDs and configure approval. Applications expose no testing or bootstrap endpoints. Tests that change approval settings restore them in teardown. External OAuth, hosted Turso authentication/TLS, email delivery, Discord role synchronization, and S3 operations require separate deployment validation.
+
+## Database matrix
+
+SQLite and local libSQL run locally. Supply URLs for empty, disposable external databases to add:
+
+- `HACKKIT_TEST_POSTGRESQL_URL`
+- `HACKKIT_TEST_MYSQL_URL`
+- `HACKKIT_TEST_LIBSQL_URL`
+
+Set `HACKKIT_REQUIRE_DATABASE_MATRIX=1` to fail if any URL is missing. CI requires all five targets. The full template runs the multi-driver migration/upgrade suite; the minimal template generates its own Core/auth SQLite baseline. HTTP libSQL migration commands retain one Node process per operation to avoid native-client lifecycle hangs.
+
+## Diagnostics
+
+Playwright writes HTML reports to `playwright-report` and JUnit results, worker server logs, traces, and failure screenshots to `test-results`. CI uploads these artifacts on failure. Startup failures include captured server output. Child processes have timeouts and bounded shutdown; temporary runtime storage is removed after teardown.
diff --git a/e2e/browser/participant.spec.ts b/e2e/browser/participant.spec.ts
new file mode 100644
index 000000000..d4633c70e
--- /dev/null
+++ b/e2e/browser/participant.spec.ts
@@ -0,0 +1,95 @@
+import { test, expect } from "../support/fixtures";
+import {
+ accountDetails,
+ signup,
+ completeRegistration,
+} from "../support/accounts";
+import { registerThroughUI, signIn, databaseAction } from "../support/browser";
+
+test("signup, onboarding, persisted registration, signout and signin", async ({
+ page,
+}) => {
+ const account = accountDetails();
+ await registerThroughUI(page, account);
+ await expect(
+ page.getByRole("heading", { name: `Welcome, ${account.name}` }),
+ ).toBeVisible();
+ await page.getByRole("button", { name: "Open account menu" }).click();
+ await page.getByRole("menuitem", { name: "Log out" }).click();
+ await expect(page).toHaveURL(/\/sign-in$/);
+ await signIn(page, account);
+ await page.goto("/dashboard");
+ await expect(page).toHaveURL(/\/dashboard$/);
+ await expect(page.getByText(account.tag, { exact: true })).toBeVisible();
+ await page.goto("/settings/registration");
+ await expect(
+ page.getByRole("combobox", { name: "University", exact: true }),
+ ).toContainText("University of Texas at San Antonio");
+});
+
+test("anonymous and incomplete accounts are redirected; participants cannot open admin pages", async ({
+ app,
+ page,
+ request,
+}) => {
+ await page.goto("/dashboard");
+ await expect(page).toHaveURL(/\/sign-in(?:\?.*)?$/);
+ const account = await signup(request, app.baseURL);
+ await signIn(page, account);
+ await page.goto("/dashboard");
+ await expect(page).toHaveURL(/\/onboarding\/hacktag$/);
+ await completeRegistration(app.baseURL, account);
+ await page.goto("/dashboard");
+ await expect(page).toHaveURL(/\/dashboard$/);
+ const denied = await page.goto("/admin");
+ expect(denied?.status()).toBe(404);
+ await expect(
+ page.getByRole("heading", { name: "Admin Overview" }),
+ ).not.toBeVisible();
+});
+
+test("a registered participant waits for approval when approval is required", async ({
+ app,
+ page,
+ request,
+}) => {
+ const owner = await signup(request, app.baseURL);
+ await databaseAction(app, "promote", owner.id);
+ await databaseAction(app, "approval", owner.id, true);
+ try {
+ const account = await signup(request, app.baseURL);
+ await completeRegistration(app.baseURL, account);
+ await signIn(page, account);
+ await page.goto("/dashboard");
+ await expect(page).toHaveURL(/\/i\/approval$/);
+ await expect(
+ page.getByRole("heading", {
+ name: "Your account is awaiting approval.",
+ }),
+ ).toBeVisible();
+ } finally {
+ await databaseAction(app, "approval", owner.id, false);
+ }
+});
+
+test("a seeded owner can open basic administration", async ({
+ app,
+ page,
+ request,
+}) => {
+ const owner = await signup(request, app.baseURL);
+ await databaseAction(app, "promote", owner.id);
+ await signIn(page, owner);
+ for (const [path, heading] of [
+ ["/admin", "Admin Overview"],
+ ["/admin/users", "Users"],
+ ["/admin/roles", "Roles"],
+ ["/admin/settings", "Hackathon Settings"],
+ ]) {
+ const response = await page.goto(path);
+ expect(response?.status()).toBe(200);
+ await expect(
+ page.getByRole("heading", { name: heading, exact: true }),
+ ).toBeVisible();
+ }
+});
diff --git a/e2e/browser/teams.spec.ts b/e2e/browser/teams.spec.ts
new file mode 100644
index 000000000..db5ee713a
--- /dev/null
+++ b/e2e/browser/teams.spec.ts
@@ -0,0 +1,56 @@
+import { test, expect } from "../support/fixtures";
+import { signup, completeRegistration } from "../support/accounts";
+import { signIn } from "../support/browser";
+
+test("team creation, invitation and acceptance across separate sessions", async ({
+ app,
+ browser,
+ request,
+ page,
+ extraHTTPHeaders,
+}) => {
+ test.skip(
+ app.template.id !== "full",
+ "Teams is included only in the full template.",
+ );
+ const owner = await signup(request, app.baseURL);
+ const teammate = await signup(request, app.baseURL);
+ await completeRegistration(app.baseURL, owner);
+ await completeRegistration(app.baseURL, teammate);
+ await signIn(page, owner);
+ await page.goto("/teams");
+ const teamName = `Team ${owner.tag}`;
+ await page.getByLabel("Team name").fill(teamName);
+ await page.getByLabel("Team tag").fill(`t-${owner.tag}`);
+ await page
+ .getByRole("button", { name: "Create team", exact: true })
+ .click();
+ await expect(page.getByRole("heading", { name: teamName })).toBeVisible();
+ await page.getByLabel("HackTag", { exact: true }).fill(teammate.tag);
+ await page.getByRole("button", { name: "Send invite" }).click();
+ await expect(page.getByText("Invite sent.", { exact: true })).toBeVisible();
+ const context = await browser.newContext({
+ baseURL: app.baseURL,
+ extraHTTPHeaders,
+ });
+ try {
+ const memberPage = await context.newPage();
+ await signIn(memberPage, teammate);
+ await memberPage.goto("/invites");
+ await memberPage
+ .getByRole("button", { name: "Accept", exact: true })
+ .click();
+ await memberPage.goto("/teams");
+ await expect(
+ memberPage.getByRole("heading", { name: teamName }),
+ ).toBeVisible();
+ await page.reload();
+ await expect(
+ page
+ .getByRole("list", { name: "Team members" })
+ .getByText(teammate.name, { exact: true }),
+ ).toBeVisible();
+ } finally {
+ await context.close();
+ }
+});
diff --git a/apps/web/db/__tests__/database-workflow.test.ts b/e2e/database/database-workflow.test.ts
similarity index 79%
rename from apps/web/db/__tests__/database-workflow.test.ts
rename to e2e/database/database-workflow.test.ts
index 3fe8d8f61..8325a3e0c 100644
--- a/apps/web/db/__tests__/database-workflow.test.ts
+++ b/e2e/database/database-workflow.test.ts
@@ -1,13 +1,14 @@
+import { prepareMigrationDirectory } from "../support/migrations.mjs";
import { mkdtemp, rm } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
-import { runDatabaseCommand } from "../../scripts/database";
+import { runDatabaseCommand } from "../../templates/nextjs-full/scripts/database";
import { initializeHackkit } from "@hackkit/core";
import { SqliteDriver } from "@mikro-orm/sqlite";
import { expect, it } from "vitest";
-import appConfig from "../../hackkit.config";
+import appConfig from "../../templates/nextjs-full/hackkit.config";
-it("runs Core, plugins, and Better Auth against committed app migrations", async () => {
+it("generates an application baseline and runs Core, plugins, and Better Auth", async () => {
const directory = await mkdtemp(join(tmpdir(), "hackkit-web-db-"));
const config = {
...appConfig,
@@ -17,7 +18,9 @@ it("runs Core, plugins, and Better Auth against committed app migrations", async
dbName: join(directory, "web.db"),
clientUrl: undefined,
migrations: {
- path: join(process.cwd(), "db/migrations/sqlite"),
+ path: await prepareMigrationDirectory(directory),
+ emit: "ts" as const,
+ snapshotName: ".snapshot",
snapshotOnMigrate: false,
},
},
@@ -29,6 +32,10 @@ it("runs Core, plugins, and Better Auth against committed app migrations", async
logger: { disabled: true },
};
try {
+ await runDatabaseCommand(config, {
+ command: "generate",
+ name: "initial",
+ });
await runDatabaseCommand(config, { command: "migrate" });
await runDatabaseCommand(config, { command: "seed" });
const core = await initializeHackkit(config);
diff --git a/apps/web/db/__tests__/dialects.test.ts b/e2e/database/dialects.test.ts
similarity index 95%
rename from apps/web/db/__tests__/dialects.test.ts
rename to e2e/database/dialects.test.ts
index 1097834fa..da015c0a8 100644
--- a/apps/web/db/__tests__/dialects.test.ts
+++ b/e2e/database/dialects.test.ts
@@ -1,3 +1,4 @@
+import { prepareMigrationDirectory } from "../support/migrations.mjs";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
@@ -6,7 +7,7 @@ import { SqliteDriver } from "@mikro-orm/sqlite";
import { LibSqlDriver } from "@mikro-orm/libsql";
import { MySqlDriver } from "@mikro-orm/mysql";
import { PostgreSqlDriver } from "@mikro-orm/postgresql";
-import { runDatabaseCommand } from "../../scripts/database";
+import { runDatabaseCommand } from "../../templates/nextjs-full/scripts/database";
import {
HackKitUser,
AuthSession,
@@ -19,7 +20,7 @@ import {
} from "@hackkit/core";
import { teamsModels } from "@hackkit/plugin-teams";
import { discordModels } from "@hackkit/plugin-discord";
-import appConfig from "../../hackkit.config";
+import appConfig from "../../templates/nextjs-full/hackkit.config";
import { verifyMigrationUpgrade } from "./migration-workflow";
import { verifyProfileConcurrency } from "./profile-concurrency";
@@ -80,11 +81,9 @@ for (const target of targets) {
? { dbName: target.url! }
: { clientUrl: target.url! }),
migrations: {
- path: join(
- process.cwd(),
- "db/migrations",
- target.dialect,
- ),
+ path: await prepareMigrationDirectory(directory),
+ emit: "ts" as const,
+ snapshotName: ".snapshot",
snapshotOnMigrate: false,
...(target.driver === MySqlDriver
? { transactional: false, allOrNothing: false }
@@ -103,6 +102,10 @@ for (const target of targets) {
logger: { disabled: true },
};
try {
+ await runDatabaseCommand(config, {
+ command: "generate",
+ name: "initial",
+ });
await runDatabaseCommand(config, { command: "migrate" });
await runDatabaseCommand(config, { command: "seed" });
const core = await initializeHackkit(config);
@@ -262,7 +265,7 @@ for (const target of targets) {
await participant.hackkit.users.updateProfile({
authId: hacker.userId,
name: "Edited Name",
- profilePhotoUrl: "/api/files/view/photo.png",
+ image: "/api/files/view/photo.png",
});
expect(
(await core.auth.api.getSession({ headers }))?.user,
@@ -284,7 +287,7 @@ for (const target of targets) {
.hackkit.users.getUser(hacker.userId),
).toMatchObject({
name: "Auth Edit",
- profilePhotoUrl: "https://example.com/photo.png",
+ image: "https://example.com/photo.png",
roleId: "core.participant",
isApproved: true,
});
diff --git a/apps/web/db/__tests__/migration-fixture-schema.ts b/e2e/database/migration-fixture-schema.ts
similarity index 100%
rename from apps/web/db/__tests__/migration-fixture-schema.ts
rename to e2e/database/migration-fixture-schema.ts
diff --git a/apps/web/db/__tests__/migration-workflow.test.ts b/e2e/database/migration-workflow.test.ts
similarity index 83%
rename from apps/web/db/__tests__/migration-workflow.test.ts
rename to e2e/database/migration-workflow.test.ts
index 87c6492a7..23b4aff3e 100644
--- a/apps/web/db/__tests__/migration-workflow.test.ts
+++ b/e2e/database/migration-workflow.test.ts
@@ -1,3 +1,4 @@
+import { prepareMigrationDirectory } from "../support/migrations.mjs";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
@@ -6,8 +7,8 @@ import { SqliteDriver } from "@mikro-orm/sqlite";
import { LibSqlDriver } from "@mikro-orm/libsql";
import { createOrmOptions } from "@hackkit/core";
import { expect, it, vi } from "vitest";
-import appConfig from "../../hackkit.config";
-import { runDatabaseCommand } from "../../scripts/database";
+import appConfig from "../../templates/nextjs-full/hackkit.config";
+import { runDatabaseCommand } from "../../templates/nextjs-full/scripts/database";
import { verifyMigrationUpgrade } from "./migration-workflow";
for (const driver of [SqliteDriver, LibSqlDriver]) {
@@ -21,11 +22,17 @@ for (const driver of [SqliteDriver, LibSqlDriver]) {
driver,
dbName: join(directory, "upgrade.db"),
migrations: {
- path: join(process.cwd(), "db/migrations/sqlite"),
+ path: await prepareMigrationDirectory(directory),
+ emit: "ts" as const,
+ snapshotName: ".snapshot",
snapshotOnMigrate: false,
},
},
};
+ await runDatabaseCommand(config, {
+ command: "generate",
+ name: "initial",
+ });
await runDatabaseCommand(config, { command: "migrate" });
await runDatabaseCommand(config, { command: "seed" });
const upgrade = await verifyMigrationUpgrade(config, directory);
@@ -67,7 +74,9 @@ it("limits reset to development SQLite and seeds missing roles without changing
driver: SqliteDriver,
dbName: join(directory, "reset.db"),
migrations: {
- path: join(process.cwd(), "db/migrations/sqlite"),
+ path: await prepareMigrationDirectory(directory),
+ emit: "ts" as const,
+ snapshotName: ".snapshot",
snapshotOnMigrate: false,
},
},
@@ -91,6 +100,10 @@ it("limits reset to development SQLite and seeds missing roles without changing
{ command: "reset" },
),
).rejects.toThrow("local SQLite");
+ await runDatabaseCommand(config, {
+ command: "generate",
+ name: "initial",
+ });
await runDatabaseCommand(config, { command: "reset" });
expect(
await runDatabaseCommand(config, { command: "check" }),
diff --git a/apps/web/db/__tests__/migration-workflow.ts b/e2e/database/migration-workflow.ts
similarity index 95%
rename from apps/web/db/__tests__/migration-workflow.ts
rename to e2e/database/migration-workflow.ts
index 350032f59..78a1cf1bf 100644
--- a/apps/web/db/__tests__/migration-workflow.ts
+++ b/e2e/database/migration-workflow.ts
@@ -1,3 +1,4 @@
+import { templates, e2eDirectory } from "../support/templates.mjs";
import {
access,
cp,
@@ -19,7 +20,7 @@ import { expect } from "vitest";
import {
runDatabaseCommand,
type DatabaseCommand,
-} from "../../scripts/database";
+} from "../../templates/nextjs-full/scripts/database";
import {
LegacyNote,
ExpandedNote,
@@ -35,7 +36,7 @@ import { promisify } from "node:util";
const runProcess = promisify(execFile);
-/** Runs on the caller's disposable database after its committed initial migration. */
+/** Runs on the caller's disposable database after generating and applying its baseline. */
export async function verifyMigrationUpgrade(
input: HackkitConfig,
directory: string,
@@ -69,27 +70,25 @@ export async function verifyMigrationUpgrade(
: undefined;
const configPath = join(directory, "command.config.ts");
const schemaPath = join(
- process.cwd(),
- "db/__tests__/migration-fixture-schema.ts",
+ e2eDirectory,
+ "database/migration-fixture-schema.ts",
);
await symlink(
- join(process.cwd(), "node_modules"),
+ join(e2eDirectory, "node_modules"),
join(directory, "node_modules"),
"dir",
).catch((error: unknown) => {
- if (
- !(
- error instanceof Error &&
- "code" in error &&
- error.code === "EEXIST"
- )
- )
+ if (!(
+ error instanceof Error &&
+ "code" in error &&
+ error.code === "EEXIST"
+ ))
throw error;
});
await writeFile(
configPath,
`
-import appConfig from ${JSON.stringify(join(process.cwd(), "hackkit.config.ts"))};
+import appConfig from ${JSON.stringify(join(templates.full.directory, "hackkit.config.ts"))};
import { LibSqlDriver } from '@mikro-orm/libsql';
import { ${noteName}, probePlugin, PriorityPluginEntry } from ${JSON.stringify(schemaPath)};
export default {
@@ -129,7 +128,7 @@ export default {
try {
await runProcess(process.execPath, args, {
- cwd: process.cwd(),
+ cwd: templates.full.directory,
timeout: 15000,
});
} catch (error) {
diff --git a/apps/web/db/__tests__/profile-concurrency.ts b/e2e/database/profile-concurrency.ts
similarity index 98%
rename from apps/web/db/__tests__/profile-concurrency.ts
rename to e2e/database/profile-concurrency.ts
index bf726ba24..8fa4e529a 100644
--- a/apps/web/db/__tests__/profile-concurrency.ts
+++ b/e2e/database/profile-concurrency.ts
@@ -27,7 +27,7 @@ export async function verifyProfileConcurrency(
runtime: HackKitRuntime,
rowLocking: boolean,
) {
- const ids = [crypto.randomUUID(), crypto.randomUUID()];
+ const ids: string[] = [crypto.randomUUID(), crypto.randomUUID()];
const seed = runtime.createScope().em;
for (const id of ids) {
seed.create(HackKitUser, {
diff --git a/e2e/database/templates.test.ts b/e2e/database/templates.test.ts
new file mode 100644
index 000000000..d2e755a47
--- /dev/null
+++ b/e2e/database/templates.test.ts
@@ -0,0 +1,176 @@
+import { execFile } from "node:child_process";
+import { promisify } from "node:util";
+import { mkdtemp, readFile, writeFile, access, rm } from "node:fs/promises";
+import { join } from "node:path";
+import { tmpdir } from "node:os";
+import { expect, it } from "vitest";
+import { templates, testEnvironment } from "../support/templates.mjs";
+import { prepareMigrationDirectory } from "../support/migrations.mjs";
+import { loadHackkitConfig } from "@hackkit/config";
+import { initializeHackkit } from "@hackkit/core";
+import { SqliteDriver } from "@mikro-orm/sqlite";
+import { runDatabaseCommand } from "../../templates/nextjs-minimal/scripts/database";
+
+const execute = promisify(execFile);
+for (const template of Object.values(templates)) {
+ it(`${template.id}: app commands isolate storage, sync without connecting, and enforce reset restrictions`, async () => {
+ const directory = await mkdtemp(
+ join(tmpdir(), `hackkit-commands-${template.id}-`),
+ );
+ const env = {
+ ...testEnvironment(template, directory),
+ NODE_ENV: "test",
+ };
+ const run = (args: string[], overrides: NodeJS.ProcessEnv = {}) =>
+ execute(process.execPath, args, {
+ cwd: template.directory,
+ env: { ...env, ...overrides },
+ timeout: 30000,
+ });
+ const command = (name: string, overrides: NodeJS.ProcessEnv = {}) =>
+ run(["scripts/db.mjs", name], overrides);
+ try {
+ await prepareMigrationDirectory(directory);
+ const syncDatabase = join(directory, "sync-must-not-connect.db");
+ await run(
+ ["node_modules/@hackkit/cli/bin/hackkit.mjs", "plugin", "sync"],
+ { DATABASE_URL: `file:${syncDatabase}` },
+ );
+ await expect(access(syncDatabase)).rejects.toMatchObject({
+ code: "ENOENT",
+ });
+ const generated: unknown = JSON.parse(
+ (await command("generate")).stdout,
+ );
+ expect(generated).toMatchObject({
+ command: "generate",
+ migration: { code: expect.stringContaining("core_user") },
+ });
+ expect(generated).toMatchObject({
+ migration: {
+ code:
+ template.id === "full"
+ ? expect.stringContaining("teams_team")
+ : expect.not.stringContaining("teams_team"),
+ },
+ });
+ await access(join(directory, "migrations/.snapshot.json"));
+ const status = await command("status");
+ expect(JSON.parse(status.stdout)).toMatchObject({
+ executed: [],
+ pending: [expect.anything()],
+ });
+ const resultPath = join(directory, "unmigrated.json");
+ await expect(
+ run(["scripts/db.mjs", "check", "--output", resultPath]),
+ ).rejects.toMatchObject({ code: 1 });
+ expect(
+ JSON.parse(await readFile(resultPath, "utf8")),
+ ).toMatchObject({
+ ok: false,
+ needsMigration: false,
+ schemaSql: expect.stringContaining("core_user"),
+ });
+ await expect(
+ command("reset", { NODE_ENV: "production" }),
+ ).rejects.toMatchObject({ code: 1 });
+ await expect(
+ command("reset", {
+ DATABASE_URL: "libsql://remote.example.com",
+ }),
+ ).rejects.toMatchObject({ code: 1 });
+ const untouched = join(directory, "untouched.db");
+ await writeFile(untouched, "leave me alone\n");
+ await command("reset");
+ expect(
+ JSON.parse((await command("generate")).stdout),
+ ).toMatchObject({
+ migration: { fileName: "", diff: { up: [] } },
+ });
+ expect(JSON.parse((await command("check")).stdout)).toMatchObject({
+ ok: true,
+ });
+ expect(JSON.parse((await command("seed")).stdout)).toMatchObject({
+ seed: {
+ insertedRoleIds: [],
+ skippedRoleIds: ["core.participant", "core.owner"],
+ },
+ });
+ expect(await readFile(untouched, "utf8")).toBe("leave me alone\n");
+ } finally {
+ await rm(directory, { recursive: true, force: true });
+ }
+ });
+}
+
+it("minimal: generates and replays a Core/auth baseline without plugins", async () => {
+ const directory = await mkdtemp(join(tmpdir(), "hackkit-minimal-db-"));
+ try {
+ const input = await loadHackkitConfig("hackkit.config.ts", {
+ cwd: templates.minimal.directory,
+ });
+ expect(input.plugins).toEqual([]);
+ expect(input.seedRoles.map((role) => role.id)).toEqual([
+ "core.participant",
+ "core.owner",
+ ]);
+ const config = {
+ ...input,
+ database: {
+ driver: SqliteDriver,
+ dbName: join(directory, "web.db"),
+ migrations: {
+ path: await prepareMigrationDirectory(directory),
+ emit: "ts" as const,
+ snapshotName: ".snapshot",
+ snapshotOnMigrate: false,
+ },
+ },
+ auth: {
+ baseURL: templates.minimal.origin,
+ secret: "minimal-db-secret-at-least-32-characters",
+ emailAndPassword: { enabled: true },
+ },
+ logger: { disabled: true },
+ };
+ await runDatabaseCommand(config, {
+ command: "generate",
+ name: "initial",
+ });
+ await runDatabaseCommand(config, { command: "migrate" });
+ await runDatabaseCommand(config, { command: "seed" });
+ expect(
+ await runDatabaseCommand(config, { command: "check" }),
+ ).toMatchObject({ ok: true });
+ const core = await initializeHackkit(config);
+ try {
+ const signup = await core.auth.api.signUpEmail({
+ body: {
+ name: "Minimal",
+ email: "minimal@example.com",
+ password: "correct-horse-battery-staple",
+ },
+ });
+ expect(
+ await core.createScope().hackkit.users.getUser(signup.user.id),
+ ).toMatchObject({ email: "minimal@example.com" });
+ expect(await core.orm.schema.getUpdateSchemaSQL()).toBe("");
+ } finally {
+ await core.orm.close();
+ }
+ // Replaying the application's history initializes another clone without regenerating it.
+ const fresh = {
+ ...config,
+ database: {
+ ...config.database,
+ dbName: join(directory, "fresh.db"),
+ },
+ };
+ await runDatabaseCommand(fresh, { command: "migrate" });
+ expect(
+ await runDatabaseCommand(fresh, { command: "check" }),
+ ).toMatchObject({ ok: true });
+ } finally {
+ await rm(directory, { recursive: true, force: true });
+ }
+});
diff --git a/e2e/http/runtime.spec.ts b/e2e/http/runtime.spec.ts
new file mode 100644
index 000000000..0c348838d
--- /dev/null
+++ b/e2e/http/runtime.spec.ts
@@ -0,0 +1,215 @@
+import { test, expect } from "../support/fixtures";
+import { signup, clientFor, completeRegistration } from "../support/accounts";
+
+test("production HTTP auth, request isolation, permissions, Core and plugin transport", async ({
+ app,
+ request,
+}) => {
+ const accounts = await Promise.all([
+ signup(request, app.baseURL),
+ signup(request, app.baseURL),
+ ]);
+ for (const account of accounts) {
+ const headers = { cookie: account.cookie };
+ const session = await request.get("/api/auth/get-session", { headers });
+ expect(await session.json()).toMatchObject({
+ user: { id: account.id },
+ });
+ const page = await request.get("/onboarding/hacktag", { headers });
+ expect(page.status()).toBe(200);
+ expect(await page.text()).not.toContain("data-next-error-message");
+ expect(
+ (await request.get("/api/admin/export", { headers })).status(),
+ ).toBe(403);
+ }
+ // Explicit empty cookies avoid the request fixture's signup cookie jar.
+ expect(
+ await (
+ await request.get("/api/auth/get-session", {
+ headers: { cookie: "" },
+ })
+ ).json(),
+ ).toBeNull();
+ expect(
+ (
+ await request.get("/dashboard", {
+ headers: { cookie: "" },
+ maxRedirects: 0,
+ })
+ ).status(),
+ ).toBe(307);
+ expect(
+ (
+ await request.get("/api/admin/export", { headers: { cookie: "" } })
+ ).status(),
+ ).toBe(401);
+ const claimed = await Promise.all(
+ accounts.map((account) =>
+ clientFor(app.baseURL, account.cookie)(
+ "@post/users/claim-hack-tag",
+ { body: { hackTag: account.tag } },
+ ),
+ ),
+ );
+ expect(claimed.map((result) => result.data?.id)).toEqual(
+ accounts.map((account) => account.id),
+ );
+ expect(typeof claimed[0]?.data?.createdAt).toBe("string");
+ expect(
+ (
+ await clientFor(app.baseURL)("@post/users/claim-hack-tag", {
+ body: { hackTag: "anonymous" },
+ })
+ ).error,
+ ).toMatchObject({ code: "UNAUTHORIZED", status: 401 });
+ expect(
+ (
+ await clientFor(app.baseURL, accounts[0].cookie)(
+ "@post/roles/create",
+ { body: { name: "Forbidden", position: 0, permissions: [] } },
+ )
+ ).error,
+ ).toMatchObject({ status: 403 });
+ const spoof = await request.post("/api/hackkit/users/claim-hack-tag", {
+ headers: { cookie: accounts[0].cookie, origin: app.baseURL },
+ data: { hackTag: "spoof", authId: accounts[1].id },
+ });
+ expect(spoof.status()).toBe(400);
+ for (const account of accounts)
+ await completeRegistration(app.baseURL, account);
+ if (app.template.id === "minimal") {
+ for (const path of ["teams/create", "discord/confirm-verification"])
+ expect(
+ (
+ await request.post(`/api/hackkit/${path}`, {
+ headers: {
+ cookie: accounts[0].cookie,
+ origin: app.baseURL,
+ },
+ data: {},
+ })
+ ).status(),
+ ).toBe(404);
+ return;
+ }
+ const owner = clientFor(app.baseURL, accounts[0].cookie);
+ const member = clientFor(app.baseURL, accounts[1].cookie);
+ const created = await owner("@post/teams/create", {
+ body: { name: "HTTP team", tag: `t-${accounts[0].tag}` },
+ });
+ expect(created.error).toBeNull();
+ if (!created.data) throw new Error("Team creation returned no team.");
+ expect(created.data.ownerAuthId).toBe(accounts[0].id);
+ const invited = await owner("@post/teams/invite", {
+ body: { teamId: created.data.id, hackTag: accounts[1].tag },
+ });
+ expect(invited.error).toBeNull();
+ if (!invited.data) throw new Error("Invitation returned no invite.");
+ expect(
+ (
+ await member("@post/teams/respond-to-invite", {
+ body: { inviteId: invited.data.id, accept: true },
+ })
+ ).error,
+ ).toBeNull();
+ expect(await member("@post/teams/leave")).toEqual({
+ data: null,
+ error: null,
+ });
+ expect((await owner("@post/teams/leave")).error).toMatchObject({
+ status: 422,
+ });
+ expect(
+ (
+ await owner("@post/discord/confirm-verification", {
+ body: { code: "missing-code" },
+ })
+ ).error,
+ ).toMatchObject({ status: 404 });
+});
+
+test("minimal local uploads roundtrip and preserve resume access checks", async ({
+ app,
+ request,
+}) => {
+ test.skip(
+ app.template.id !== "minimal",
+ "The full template uses S3 in production.",
+ );
+ const account = await signup(request, app.baseURL);
+ const other = await signup(request, app.baseURL);
+ expect(
+ (
+ await request.post("/api/files/register", {
+ headers: { cookie: "" },
+ data: { location: "resumes", fileName: "resume.pdf" },
+ })
+ ).status(),
+ ).toBe(401);
+ for (const location of ["resumes", "profile-photos"]) {
+ const registration = await request.post("/api/files/register", {
+ headers: { cookie: account.cookie },
+ data: {
+ location,
+ fileName: location === "resumes" ? "resume.pdf" : "photo.png",
+ },
+ });
+ expect(registration.status()).toBe(200);
+ const target: unknown = await registration.json();
+ if (
+ !target ||
+ typeof target !== "object" ||
+ !("uploadUrl" in target) ||
+ typeof target.uploadUrl !== "string" ||
+ !("storedFileReference" in target) ||
+ typeof target.storedFileReference !== "string"
+ )
+ throw new Error("Invalid local upload target.");
+ expect(new URL(target.uploadUrl).origin).toBe(app.baseURL);
+ const bytes = Buffer.from("E2E file upload");
+ expect(
+ (
+ await request.put(target.uploadUrl, {
+ headers: { cookie: "" },
+ data: bytes,
+ })
+ ).status(),
+ ).toBe(401);
+ expect(
+ (
+ await request.put(target.uploadUrl, {
+ headers: { cookie: account.cookie },
+ data: bytes,
+ })
+ ).status(),
+ ).toBe(204);
+ if (location === "resumes") {
+ await completeRegistration(
+ app.baseURL,
+ account,
+ target.storedFileReference,
+ );
+ for (const cookie of ["", other.cookie])
+ expect(
+ (
+ await request.get(target.storedFileReference, {
+ headers: { cookie },
+ })
+ ).status(),
+ ).toBe(401);
+ } else {
+ expect(
+ (
+ await request.get(target.storedFileReference, {
+ headers: { cookie: "" },
+ })
+ ).status(),
+ ).toBe(200);
+ }
+ const viewed = await request.get(target.storedFileReference, {
+ headers: { cookie: account.cookie },
+ });
+ expect(viewed.status()).toBe(200);
+ expect(await viewed.body()).toEqual(bytes);
+ }
+});
diff --git a/e2e/package.json b/e2e/package.json
new file mode 100644
index 000000000..3e25307e4
--- /dev/null
+++ b/e2e/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "@hackkit/e2e",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "test": "node support/run.mjs all",
+ "test:db": "node support/run.mjs db",
+ "test:http": "node support/run.mjs http",
+ "test:browser": "node support/run.mjs browser",
+ "typecheck": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@hackkit/core": "workspace:*",
+ "@hackkit/config": "workspace:*",
+ "@hackkit/cli": "workspace:*",
+ "@hackkit/plugin-teams": "workspace:*",
+ "@hackkit/plugin-discord": "workspace:*",
+ "@hackkit/plugin-notifications-email": "workspace:*",
+ "@mikro-orm/core": "7.2.1",
+ "@mikro-orm/sqlite": "7.2.1",
+ "@mikro-orm/libsql": "7.2.1",
+ "@mikro-orm/mysql": "7.2.1",
+ "@mikro-orm/postgresql": "7.2.1",
+ "@playwright/test": "1.64.1",
+ "@types/node": "22.18.6",
+ "esbuild": "0.25.12",
+ "jiti": "2.4.2",
+ "typescript": "5.9.3",
+ "vitest": "^3.2.4",
+ "@mikro-orm/migrations": "7.2.1"
+ }
+}
diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts
new file mode 100644
index 000000000..c9377cb80
--- /dev/null
+++ b/e2e/playwright.config.ts
@@ -0,0 +1,30 @@
+import { defineConfig, devices } from "@playwright/test";
+import { e2eDirectory } from "./support/templates.mjs";
+
+export default defineConfig({
+ testDir: e2eDirectory,
+ testMatch: ["http/**/*.spec.ts", "browser/**/*.spec.ts"],
+ outputDir: "test-results",
+ workers: 1,
+ fullyParallel: false,
+ forbidOnly: Boolean(process.env.CI),
+ retries: 0,
+ timeout: 60000,
+ expect: { timeout: 10000 },
+ reporter: [
+ ["list"],
+ ["html", { open: "never" }],
+ ["junit", { outputFile: "test-results/results.xml" }],
+ ],
+ use: {
+ ...devices["Desktop Chrome"],
+ trace: "retain-on-failure",
+ screenshot: "only-on-failure",
+ },
+ projects: ["full", "minimal"].flatMap((template) =>
+ ["http", "browser"].map((kind) => ({
+ name: `${template}-${kind}`,
+ testMatch: `${kind}/**/*.spec.ts`,
+ })),
+ ),
+});
diff --git a/e2e/support/accounts.ts b/e2e/support/accounts.ts
new file mode 100644
index 000000000..bf8bae285
--- /dev/null
+++ b/e2e/support/accounts.ts
@@ -0,0 +1,96 @@
+import { randomUUID } from "node:crypto";
+import type { APIRequestContext } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { createHackkitClient } from "@hackkit/core/http/client";
+import type { TeamsEndpoints } from "@hackkit/plugin-teams/client";
+import type { DiscordEndpoints } from "@hackkit/plugin-discord/client";
+
+export function accountDetails() {
+ const tag = `h-${randomUUID().slice(0, 8)}`;
+ return {
+ name: `Hacker ${tag}`,
+ email: `${tag}@example.com`,
+ password: "correct-horse-battery-staple",
+ tag,
+ };
+}
+
+export async function signup(request: APIRequestContext, baseURL: string) {
+ const account = accountDetails();
+ const response = await request.post(`${baseURL}/api/auth/sign-up/email`, {
+ headers: { origin: baseURL },
+ data: account,
+ });
+ expect(response.status(), await response.text()).toBe(200);
+ const body: unknown = await response.json();
+ if (
+ !body ||
+ typeof body !== "object" ||
+ !("user" in body) ||
+ !body.user ||
+ typeof body.user !== "object" ||
+ !("id" in body.user) ||
+ typeof body.user.id !== "string"
+ )
+ throw new Error("Signup did not return a canonical user ID.");
+ const cookie = response
+ .headersArray()
+ .filter((header) => header.name.toLowerCase() === "set-cookie")
+ .map((header) => header.value.split(";")[0])
+ .join("; ");
+ expect(cookie).toContain("better-auth.session_token=");
+ return { ...account, id: body.user.id, cookie };
+}
+
+export function clientFor(baseURL: string, cookie?: string) {
+ return createHackkitClient({
+ baseURL: `${baseURL}/api/hackkit`,
+ headers: { origin: baseURL, ...(cookie ? { cookie } : {}) },
+ });
+}
+
+export async function completeRegistration(
+ baseURL: string,
+ account: Awaited>,
+ resumeUrl?: string,
+) {
+ const client = clientFor(baseURL, account.cookie);
+ expect(
+ (
+ await client("@post/users/claim-hack-tag", {
+ body: { hackTag: account.tag },
+ })
+ ).error,
+ ).toBeNull();
+ expect(
+ (
+ await client("@post/user-data/complete", {
+ body: {
+ age: 20,
+ gender: "prefer_not_to_answer",
+ race: "prefer_not_to_answer",
+ ethnicity: "prefer_not_to_answer",
+ shirtSize: "m",
+ dietaryRestrictions: ["none"],
+ hasAcceptedMLHCodeOfConduct: true,
+ hasSharedDataWithMLH: true,
+ isEmailable: true,
+ },
+ })
+ ).error,
+ ).toBeNull();
+ expect(
+ (
+ await client("@post/hackers/register", {
+ body: {
+ university: "Test University",
+ major: "CS",
+ levelOfStudy: "undergraduate",
+ hackathonsAttended: 0,
+ softwareExperience: "beginner",
+ resumeUrl,
+ },
+ })
+ ).error,
+ ).toBeNull();
+}
diff --git a/e2e/support/browser.ts b/e2e/support/browser.ts
new file mode 100644
index 000000000..9eeef169c
--- /dev/null
+++ b/e2e/support/browser.ts
@@ -0,0 +1,85 @@
+import { expect, type Page } from "@playwright/test";
+import { promisify } from "node:util";
+import { execFile } from "node:child_process";
+import { join } from "node:path";
+import { e2eDirectory } from "./templates.mjs";
+import type { startTemplate } from "./server.mjs";
+import { accountDetails } from "./accounts";
+
+const execute = promisify(execFile);
+export async function databaseAction(
+ app: Awaited>,
+ action: "promote" | "approval",
+ userId: string,
+ value?: boolean,
+) {
+ await execute(
+ process.execPath,
+ [
+ join(e2eDirectory, "support/database-task.mjs"),
+ action,
+ userId,
+ ...(value === undefined ? [] : [String(value)]),
+ ],
+ { cwd: app.template.directory, env: app.env, timeout: 30000 },
+ );
+}
+
+export async function signIn(
+ page: Page,
+ account: ReturnType,
+) {
+ await page.goto("/sign-in");
+ await page.getByLabel("Email", { exact: true }).fill(account.email);
+ await page.getByLabel("Password", { exact: true }).fill(account.password);
+ await page.getByRole("button", { name: "Sign in", exact: true }).click();
+ await expect(page).toHaveURL(/\/$/);
+}
+
+async function select(page: Page, label: string, option: string) {
+ await page.getByRole("combobox", { name: label, exact: true }).click();
+ await page.getByRole("option", { name: option, exact: true }).click();
+}
+
+/** Exercise every form through the browser instead of bypassing registration. */
+export async function registerThroughUI(
+ page: Page,
+ account: ReturnType,
+) {
+ await page.goto("/sign-up");
+ await page.getByLabel("Name", { exact: true }).fill(account.name);
+ await page.getByLabel("Email", { exact: true }).fill(account.email);
+ await page.getByLabel("Password", { exact: true }).fill(account.password);
+ await page.getByRole("button", { name: "Create account" }).click();
+ await expect(page).toHaveURL(/\/onboarding\/hacktag$/);
+ await page.getByLabel("HackTag", { exact: true }).fill(account.tag);
+ await page.getByRole("button", { name: "Claim HackTag" }).click();
+ await expect(page).toHaveURL(/\/onboarding\/user-data$/);
+ await page.getByLabel("Age", { exact: true }).fill("22");
+ await select(page, "Gender", "Prefer not to answer");
+ await select(page, "Race", "Prefer not to answer");
+ await select(page, "Ethnicity", "Prefer not to answer");
+ await select(page, "Shirt size", "Medium");
+ await select(page, "Country of residence", "United States");
+ await page
+ .getByRole("checkbox", { name: "No dietary restrictions", exact: true })
+ .check();
+ await page
+ .getByRole("checkbox", {
+ name: "I have read and agree to the MLH Code of Conduct.",
+ })
+ .check();
+ await page.getByRole("checkbox", { name: /I authorize sharing/ }).check();
+ await page
+ .getByRole("checkbox", { name: /I agree to receive email/ })
+ .check();
+ await page.getByRole("button", { name: "Save user data" }).click();
+ await expect(page).toHaveURL(/\/onboarding\/hacker$/);
+ await select(page, "University", "University of Texas at San Antonio");
+ await select(page, "Major", "Computer Science");
+ await select(page, "Level of study", "Freshman");
+ await page.getByLabel("Hackathons attended", { exact: true }).fill("0");
+ await select(page, "Software experience", "Beginner");
+ await page.getByRole("button", { name: "Complete registration" }).click();
+ await expect(page).toHaveURL(/\/dashboard$/);
+}
diff --git a/e2e/support/database-env.ts b/e2e/support/database-env.ts
new file mode 100644
index 000000000..e21088041
--- /dev/null
+++ b/e2e/support/database-env.ts
@@ -0,0 +1,10 @@
+// Config imports are intentionally inert: each database test supplies an explicit
+// disposable connection before initializing an ORM or invoking an app command.
+import { testEnvironment, templates } from "./templates.mjs";
+import { join } from "node:path";
+import { tmpdir } from "node:os";
+Object.assign(
+ process.env,
+ testEnvironment(templates.full, join(tmpdir(), "hackkit-unused-config")),
+ { NODE_ENV: "test" },
+);
diff --git a/e2e/support/database-task.mjs b/e2e/support/database-task.mjs
new file mode 100644
index 000000000..448b9cd62
--- /dev/null
+++ b/e2e/support/database-task.mjs
@@ -0,0 +1,34 @@
+import { createJiti } from "jiti";
+import { initializeHackkit, HackKitUser, CoreSetting } from "@hackkit/core";
+import { resolve } from "node:path";
+
+// This executable belongs only to E2E. Applications expose no bootstrap endpoint.
+const [action, userId, value] = process.argv.slice(2);
+if (!userId || !["promote", "approval"].includes(action))
+ throw new Error(
+ "Choose promote or approval and provide a canonical test user ID.",
+ );
+const jiti = createJiti(import.meta.url);
+const { default: config } = await jiti.import(resolve("hackkit.config.ts"));
+const core = await initializeHackkit(config);
+try {
+ const scope = core.createScope();
+ if (action === "promote") {
+ const updated = await scope.em.nativeUpdate(
+ HackKitUser,
+ { id: userId },
+ { roleId: "core.owner" },
+ );
+ if (updated !== 1) throw new Error("Expected one existing test user.");
+ } else {
+ if (value !== "true" && value !== "false")
+ throw new Error("Approval requires true or false.");
+ await scope.hackkit.settings.set({
+ actorAuthId: userId,
+ key: CoreSetting.RequireApproval,
+ value: value === "true",
+ });
+ }
+} finally {
+ await core.orm.close();
+}
diff --git a/e2e/support/fixtures.ts b/e2e/support/fixtures.ts
new file mode 100644
index 000000000..5b3cbcccb
--- /dev/null
+++ b/e2e/support/fixtures.ts
@@ -0,0 +1,57 @@
+import { test as base, expect } from "@playwright/test";
+import { templates } from "./templates.mjs";
+import { startTemplate } from "./server.mjs";
+import { mkdir, writeFile } from "node:fs/promises";
+import { join } from "node:path";
+import { createHash } from "node:crypto";
+
+type Server = Awaited>;
+export const test = base.extend<{ serverLogs: void }, { app: Server }>({
+ extraHTTPHeaders: async ({}, use, testInfo) => {
+ // Separate simulated clients retain real production auth rate limiting.
+ const digest = createHash("sha256").update(testInfo.testId).digest();
+ await use({ "x-forwarded-for": `198.18.${digest[0]}.${digest[1]}` });
+ },
+ app: [
+ async ({}, use, workerInfo) => {
+ const template = workerInfo.project.name.startsWith("full-")
+ ? templates.full
+ : templates.minimal;
+ const app = await startTemplate(template);
+ try {
+ await use(app);
+ } finally {
+ try {
+ await mkdir(workerInfo.project.outputDir, {
+ recursive: true,
+ });
+ await writeFile(
+ join(
+ workerInfo.project.outputDir,
+ `server-${workerInfo.workerIndex}.log`,
+ ),
+ app.logs(),
+ );
+ } finally {
+ await app.close();
+ }
+ }
+ },
+ { scope: "worker", timeout: 90000 },
+ ],
+ baseURL: async ({ app }, use) => {
+ await use(app.baseURL);
+ },
+ serverLogs: [
+ async ({ app }, use, testInfo) => {
+ await use();
+ if (testInfo.status !== testInfo.expectedStatus)
+ await testInfo.attach("server.log", {
+ body: app.logs(),
+ contentType: "text/plain",
+ });
+ },
+ { auto: true },
+ ],
+});
+export { expect };
diff --git a/e2e/support/migrations.mjs b/e2e/support/migrations.mjs
new file mode 100644
index 000000000..7efbd0294
--- /dev/null
+++ b/e2e/support/migrations.mjs
@@ -0,0 +1,17 @@
+import { mkdir, symlink } from "node:fs/promises";
+import { join } from "node:path";
+import { e2eDirectory } from "./templates.mjs";
+
+/** Give generated TypeScript migrations an isolated history and resolvable imports.
+ * @param {string} directory
+ */
+export async function prepareMigrationDirectory(directory) {
+ const path = join(directory, "migrations");
+ await mkdir(directory, { recursive: true });
+ await symlink(
+ join(e2eDirectory, "node_modules"),
+ join(directory, "node_modules"),
+ "dir",
+ );
+ return path;
+}
diff --git a/e2e/support/processes.mjs b/e2e/support/processes.mjs
new file mode 100644
index 000000000..56076a521
--- /dev/null
+++ b/e2e/support/processes.mjs
@@ -0,0 +1,50 @@
+import { spawn } from "node:child_process";
+
+/** Execute commands without a shell, with bounded lifetime and visible diagnostics. */
+export async function runCommand(command, args, options = {}) {
+ const child = spawn(command, args, {
+ cwd: options.cwd,
+ env: options.env ?? process.env,
+ stdio: "inherit",
+ detached: process.platform !== "win32",
+ });
+ const timer = setTimeout(() => {
+ if (process.platform === "win32" || !child.pid) child.kill("SIGKILL");
+ else {
+ try {
+ process.kill(-child.pid, "SIGKILL");
+ } catch (error) {
+ if (error.code !== "ESRCH") throw error;
+ }
+ }
+ }, options.timeout ?? 300000);
+ try {
+ await new Promise((resolve, reject) => {
+ child.once("error", reject);
+ child.once("exit", (code, signal) =>
+ code === 0
+ ? resolve()
+ : reject(
+ new Error(
+ `${command} ${args.join(" ")} failed (${code ?? signal}).`,
+ ),
+ ),
+ );
+ });
+ } finally {
+ clearTimeout(timer);
+ }
+}
+
+export async function stopServer(child) {
+ if (!child.pid || child.exitCode !== null || child.signalCode !== null)
+ return;
+ await new Promise((resolve) => {
+ const timer = setTimeout(() => child.kill("SIGKILL"), 5000);
+ child.once("exit", () => {
+ clearTimeout(timer);
+ resolve();
+ });
+ child.kill("SIGTERM");
+ });
+}
diff --git a/e2e/support/run.mjs b/e2e/support/run.mjs
new file mode 100644
index 000000000..c401c7016
--- /dev/null
+++ b/e2e/support/run.mjs
@@ -0,0 +1,104 @@
+import assert from "node:assert/strict";
+import { mkdtemp, rm, readdir, readFile } from "node:fs/promises";
+import { createHash } from "node:crypto";
+import { tmpdir } from "node:os";
+import { join, relative } from "node:path";
+import {
+ templates,
+ e2eDirectory,
+ repositoryRoot,
+ testEnvironment,
+} from "./templates.mjs";
+import { runCommand } from "./processes.mjs";
+import { prepareMigrationDirectory } from "./migrations.mjs";
+
+const suite = process.argv[2] ?? "all";
+assert.ok(
+ ["all", "db", "http", "browser"].includes(suite),
+ "Choose all, db, http, or browser.",
+);
+const pnpm = (args, options = {}) =>
+ runCommand("pnpm", args, {
+ cwd: repositoryRoot,
+ ...options,
+ });
+
+async function generatedFiles(template) {
+ const entries = [];
+ async function collect(directory) {
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
+ const path = join(directory, entry.name);
+ if (entry.isDirectory()) await collect(path);
+ else
+ entries.push([
+ relative(template.directory, path),
+ createHash("sha256")
+ .update(await readFile(path))
+ .digest("hex"),
+ ]);
+ }
+ }
+ await collect(join(template.directory, "app"));
+ entries.push([
+ "hackkit.lock",
+ (await readFile(join(template.directory, "hackkit.lock"))).toString(),
+ ]);
+ return entries.sort(([a], [b]) => a.localeCompare(b));
+}
+
+await pnpm([
+ "exec",
+ "turbo",
+ "run",
+ "build",
+ "--filter=@hackkit/template-nextjs-full^...",
+ "--filter=@hackkit/template-nextjs-minimal^...",
+]);
+const buildDirectory = await mkdtemp(join(tmpdir(), "hackkit-build-"));
+try {
+ const targets = Object.values(templates).map((template) => ({
+ template,
+ options: {
+ cwd: template.directory,
+ env: testEnvironment(template, join(buildDirectory, template.id)),
+ },
+ }));
+ for (const { template, options } of targets) {
+ const before = await generatedFiles(template);
+ await pnpm(["sync"], options);
+ assert.deepEqual(
+ await generatedFiles(template),
+ before,
+ `Plugin sync changed ${template.id} generated files. Run its sync command and commit the result.`,
+ );
+ }
+ for (const { options } of targets) await pnpm(["typecheck"], options);
+ await pnpm(["typecheck"], { cwd: e2eDirectory });
+ await runCommand(process.execPath, ["tooling/check-client-bundle.mjs"], {
+ cwd: repositoryRoot,
+ });
+ if (suite !== "db") {
+ for (const { template, options } of targets) {
+ await prepareMigrationDirectory(join(buildDirectory, template.id));
+ await pnpm(["db:generate", "--name", "initial"], options);
+ await pnpm(["db:migrate"], options);
+ await pnpm(["db:check"], options);
+ await pnpm(["db:seed"], options);
+ await pnpm(["build"], options);
+ }
+ }
+} finally {
+ await rm(buildDirectory, { recursive: true, force: true });
+}
+if (suite === "all" || suite === "db")
+ await pnpm(["exec", "vitest", "run"], { cwd: e2eDirectory });
+if (suite !== "db") {
+ const projects = ["full", "minimal"].flatMap((id) =>
+ (suite === "all" ? ["http", "browser"] : [suite]).map(
+ (kind) => `--project=${id}-${kind}`,
+ ),
+ );
+ await pnpm(["exec", "playwright", "test", ...projects], {
+ cwd: e2eDirectory,
+ });
+}
diff --git a/e2e/support/server.mjs b/e2e/support/server.mjs
new file mode 100644
index 000000000..03bd321f4
--- /dev/null
+++ b/e2e/support/server.mjs
@@ -0,0 +1,110 @@
+import { createRequire } from "node:module";
+import { spawn } from "node:child_process";
+import { mkdtemp, rm } from "node:fs/promises";
+import { createServer } from "node:net";
+import { join } from "node:path";
+import { tmpdir } from "node:os";
+import { setTimeout as delay } from "node:timers/promises";
+import { runCommand, stopServer } from "./processes.mjs";
+import { testEnvironment } from "./templates.mjs";
+import { prepareMigrationDirectory } from "./migrations.mjs";
+
+async function assertPortAvailable(port) {
+ const probe = createServer();
+ await new Promise((resolve, reject) => {
+ probe.once("error", () =>
+ reject(
+ new Error(
+ `E2E port ${port} is occupied. Stop that process; tests never reuse running apps.`,
+ ),
+ ),
+ );
+ probe.listen(port, "127.0.0.1", () => probe.close(resolve));
+ });
+}
+
+/** Start the real template build with fresh storage; never inherit developer config. */
+export async function startTemplate(template) {
+ await assertPortAvailable(template.port);
+ const directory = await mkdtemp(
+ join(tmpdir(), `hackkit-runtime-${template.id}-`),
+ );
+ const env = testEnvironment(template, directory);
+ let server;
+ let output = "";
+ try {
+ await prepareMigrationDirectory(directory);
+ for (const command of ["generate", "migrate", "check", "seed"])
+ await runCommand(process.execPath, ["scripts/db.mjs", command], {
+ cwd: template.directory,
+ env,
+ timeout: 15000,
+ });
+ const require = createRequire(join(template.directory, "package.json"));
+ server = spawn(
+ process.execPath,
+ [
+ require.resolve("next/dist/bin/next"),
+ "start",
+ "-H",
+ "127.0.0.1",
+ "-p",
+ String(template.port),
+ ],
+ { cwd: template.directory, env, stdio: ["ignore", "pipe", "pipe"] },
+ );
+ server.stdout.on("data", (chunk) => {
+ output += chunk.toString();
+ });
+ server.stderr.on("data", (chunk) => {
+ output += chunk.toString();
+ });
+ server.once("error", (error) => {
+ output += error.message;
+ });
+ let ready = false;
+ const deadline = Date.now() + 30000;
+ while (Date.now() < deadline) {
+ if (
+ server.exitCode !== null ||
+ server.signalCode !== null ||
+ !server.pid
+ )
+ throw new Error("Next exited before becoming ready.");
+ try {
+ const response = await fetch(
+ `${template.origin}/api/auth/get-session`,
+ { signal: AbortSignal.timeout(1000) },
+ );
+ ready = response.status === 200;
+ } catch {
+ /* Retry only while the process is starting. */
+ }
+ if (ready) break;
+ await delay(250);
+ }
+ if (!ready)
+ throw new Error(
+ "Next did not become ready within the startup timeout.",
+ );
+ const child = server;
+ return {
+ template,
+ directory,
+ env,
+ baseURL: template.origin,
+ logs: () => output,
+ async close() {
+ await stopServer(child);
+ await rm(directory, { recursive: true, force: true });
+ },
+ };
+ } catch (error) {
+ if (server) await stopServer(server);
+ await rm(directory, { recursive: true, force: true });
+ throw new Error(
+ `Failed starting ${template.id}: ${error instanceof Error ? error.message : String(error)}\n${output}`,
+ { cause: error },
+ );
+ }
+}
diff --git a/e2e/support/templates.mjs b/e2e/support/templates.mjs
new file mode 100644
index 000000000..8cb7c6992
--- /dev/null
+++ b/e2e/support/templates.mjs
@@ -0,0 +1,76 @@
+import { fileURLToPath } from "node:url";
+import { join } from "node:path";
+import { tmpdir } from "node:os";
+
+export const repositoryRoot = fileURLToPath(new URL("../../", import.meta.url));
+export const e2eDirectory = join(repositoryRoot, "e2e");
+export const templates = {
+ full: {
+ id: "full",
+ directory: join(repositoryRoot, "templates/nextjs-full"),
+ packageName: "@hackkit/template-nextjs-full",
+ dialects: ["sqlite", "libsql", "postgresql", "mysql"],
+ port: 33017,
+ origin: "http://127.0.0.1:33017",
+ },
+ minimal: {
+ id: "minimal",
+ directory: join(repositoryRoot, "templates/nextjs-minimal"),
+ packageName: "@hackkit/template-nextjs-minimal",
+ dialects: ["sqlite"],
+ port: 33018,
+ origin: "http://127.0.0.1:33018",
+ },
+};
+
+/** Use explicit values so Next's dotenv loader cannot select developer services. */
+export function testEnvironment(template, directory) {
+ const common = {
+ PATH: process.env.PATH,
+ HOME: process.env.HOME,
+ TMPDIR: tmpdir(),
+ ...(process.env.SystemRoot === undefined
+ ? {}
+ : { SystemRoot: process.env.SystemRoot }),
+ NODE_ENV: "production",
+ NEXT_TELEMETRY_DISABLED: "1",
+ DATABASE_URL: `file:${join(directory, "web.db")}`,
+ HACKKIT_DATABASE_DIALECT: "sqlite",
+ HACKKIT_MIGRATIONS_PATH: join(directory, "migrations"),
+ HACKKIT_LOCAL_BLOB_BASE_DIR: join(directory, "uploads"),
+ NEXT_PUBLIC_APP_URL: template.origin,
+ BETTER_AUTH_URL: template.origin,
+ BETTER_AUTH_SECRET: "isolated-e2e-secret-with-at-least-32-characters",
+ BETTER_AUTH_TRUSTED_ORIGINS: template.origin,
+ };
+ if (template.id === "minimal") return common;
+ return {
+ ...common,
+ HACKKIT_EMAIL_PROVIDER: "none",
+ GITHUB_CLIENT_ID: "",
+ GITHUB_CLIENT_SECRET: "",
+ GOOGLE_CLIENT_ID: "",
+ GOOGLE_CLIENT_SECRET: "",
+ TURSO_AUTH_TOKEN: "",
+ RESEND_API_KEY: "",
+ SMTP_HOST: "",
+ SMTP_PORT: "",
+ SMTP_SECURE: "false",
+ HACKKIT_EMAIL_FROM: "HackKit ",
+ HACKKIT_EMAIL_REPLY_TO: "",
+ SMTP_PASSWORD: "",
+ SMTP_USERNAME: "",
+ HACKKIT_BLOB_ADAPTER: template.id === "full" ? "s3" : "local",
+ HACKKIT_S3_BUCKET: "e2e",
+ HACKKIT_S3_REGION: "auto",
+ HACKKIT_S3_ENDPOINT: "https://example.invalid",
+ HACKKIT_S3_ACCESS_KEY_ID: "e2e",
+ HACKKIT_S3_SECRET_ACCESS_KEY: "e2e",
+ DISCORD_GUILD_ID: "e2e",
+ DISCORD_VERIFICATION_BASE_URL: template.origin,
+ DISCORD_PARTICIPANT_ROLE_NAME: "",
+ DISCORD_BOT_API_URL: "https://example.invalid",
+ DISCORD_INTERNAL_AUTH_KEY: "e2e",
+ DISCORD_PARTICIPANT_ROLE_ID: "e2e",
+ };
+}
diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json
new file mode 100644
index 000000000..d82831cce
--- /dev/null
+++ b/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "target": "ES2022", "module": "ESNext", "moduleResolution": "bundler",
+ "lib": ["ES2022", "DOM"], "strict": true, "noEmit": true,
+ "allowJs": true, "skipLibCheck": true, "esModuleInterop": true,
+ "resolveJsonModule": true
+ },
+ "include": ["**/*.ts", "support/templates.mjs"],
+ "exclude": ["node_modules", "test-results", "playwright-report"]
+}
diff --git a/e2e/vitest.config.ts b/e2e/vitest.config.ts
new file mode 100644
index 000000000..86ad38a22
--- /dev/null
+++ b/e2e/vitest.config.ts
@@ -0,0 +1,26 @@
+import { defineConfig } from "vitest/config";
+import {
+ e2eDirectory,
+ templates,
+ testEnvironment,
+} from "./support/templates.mjs";
+import { join } from "node:path";
+import { tmpdir } from "node:os";
+
+export default defineConfig({
+ test: {
+ root: e2eDirectory,
+ include: ["database/**/*.test.ts"],
+ setupFiles: ["./support/database-env.ts"],
+ fileParallelism: false,
+ testTimeout: 120000,
+ hookTimeout: 30000,
+ env: {
+ ...testEnvironment(
+ templates.full,
+ join(tmpdir(), "hackkit-unused-config"),
+ ),
+ NODE_ENV: "test",
+ },
+ },
+});
diff --git a/idea.md b/idea.md
index 4df342d16..b183a0655 100644
--- a/idea.md
+++ b/idea.md
@@ -29,8 +29,8 @@
## Organization
-- `hackkit/core` hackkit instance exposed by something like `const hk = createHackkit({})` and passing in a config object
-- `hackkit/ui` Hackkit UI package uses the hackkit api exposed by the API
- - UI components can either be replaced in the web app by the developer or new UI elements can be added into select “slots”
-- `create-hackkit` - Start new hackkit app from template built out with hackkit ui
-- `hackkit` cli - add plugins
+- `hackkit/core` hackkit instance exposed by something like `const hk = createHackkit({})` and passing in a config object
+- `hackkit/ui` Hackkit UI package uses the hackkit api exposed by the API
+ - UI components can either be replaced in the web app by the developer or new UI elements can be added into select “slots”
+- `create-hackkit` - Start new hackkit app from template built out with hackkit ui
+- `hackkit` cli - add plugins
diff --git a/package.json b/package.json
index ecff63ec1..f3be83eca 100644
--- a/package.json
+++ b/package.json
@@ -2,36 +2,50 @@
"private": true,
"scripts": {
"build": "turbo run build",
- "start": "turbo run start",
- "dev": "turbo run dev",
+ "start": "turbo run start --filter=@hackkit/template-nextjs-full",
+ "dev": "turbo run dev --filter=@hackkit/template-nextjs-full",
"lint": "turbo run lint",
"preinstall": "npx only-allow pnpm",
- "db:generate": "pnpm --filter=web db:generate",
- "db:migrate": "pnpm --filter=web db:migrate",
- "db:seed": "pnpm --filter=web db:seed",
- "db:reset": "pnpm --filter=web db:reset",
+ "db:generate": "pnpm --filter=@hackkit/template-nextjs-full db:generate",
+ "db:migrate": "pnpm --filter=@hackkit/template-nextjs-full db:migrate",
+ "db:seed": "pnpm --filter=@hackkit/template-nextjs-full db:seed",
+ "db:reset": "pnpm --filter=@hackkit/template-nextjs-full db:reset",
"deploy-discord:dev": "pnpm --filter=bot deploy:dev",
"deploy-discord:prod": "pnpm --filter=bot deploy:prod",
"format": "prettier --write .",
"format-check": "prettier --check .",
- "db:status": "pnpm --filter=web db:status",
- "db:check": "pnpm --filter=web db:check",
- "db:rollback": "pnpm --filter=web db:rollback"
+ "db:status": "pnpm --filter=@hackkit/template-nextjs-full db:status",
+ "db:check": "pnpm --filter=@hackkit/template-nextjs-full db:check",
+ "db:rollback": "pnpm --filter=@hackkit/template-nextjs-full db:rollback",
+ "dev:full": "turbo run dev --filter=@hackkit/template-nextjs-full",
+ "dev:minimal": "turbo run dev --filter=@hackkit/template-nextjs-minimal",
+ "test": "turbo run test --filter=./packages/*",
+ "typecheck": "turbo run typecheck",
+ "test:e2e": "pnpm --filter @hackkit/e2e test",
+ "test:e2e:db": "pnpm --filter @hackkit/e2e test:db",
+ "test:e2e:http": "pnpm --filter @hackkit/e2e test:http",
+ "test:e2e:browser": "pnpm --filter @hackkit/e2e test:browser",
+ "dev:demo": "turbo run dev --filter=@hackkit/demo",
+ "dev:docs": "pnpm --filter @hackkit/docs dev",
+ "build:demo": "turbo run build --filter=@hackkit/demo",
+ "build:docs": "pnpm --filter @hackkit/docs build",
+ "deploy:demo": "pnpm --filter @hackkit/demo run deploy",
+ "deploy:docs": "pnpm --filter @hackkit/docs run deploy"
},
"devDependencies": {
"@turbo/gen": "^2.0.9",
"@types/node": "20.14.11",
"dotenv-cli": "^7.4.2",
- "eslint": "^9.7.0",
+ "eslint": "^10.13.0",
"prettier": "^3.3.3",
"turbo": "^2.0.9"
},
- "packageManager": "pnpm@8.3.1+sha512.d264f6640bf4f09de7cfcc547568515bcf0613cf485a03e8ff16616fa69c4172b6f9a0a2925ee44fb060df565c9c9a8eaf061749e77af318cb77f6684a7051f3",
"name": "hackkit",
"dependencies": {
"prettier-plugin-tailwindcss": "^0.6.5"
},
"engines": {
"node": ">=22.17.0"
- }
+ },
+ "packageManager": "pnpm@12.15.0"
}
diff --git a/packages/config/src/__tests__/config.test.ts b/packages/config/src/__tests__/config.test.ts
index 628afcb54..0937b5a7c 100644
--- a/packages/config/src/__tests__/config.test.ts
+++ b/packages/config/src/__tests__/config.test.ts
@@ -1,6 +1,6 @@
import { SqliteDriver } from "@mikro-orm/sqlite";
import { describe, expect, expectTypeOf, it } from "vitest";
-import { dirname, resolve } from "node:path";
+import { dirname } from "node:path";
import { fileURLToPath } from "node:url";
import {
defineHackkitConfig,
@@ -23,25 +23,13 @@ describe("HackKit config", () => {
expect(config.database).toBe(database);
});
- it("loads the web HackKit config through the shared loader", async () => {
- const repoRoot = resolve(
- dirname(fileURLToPath(import.meta.url)),
- "../../../..",
- );
- const config = await loadHackkitConfig("apps/web/hackkit.config.ts", {
- cwd: repoRoot,
+ it("loads a config through the shared loader", async () => {
+ const cwd = dirname(fileURLToPath(import.meta.url));
+ const config = await loadHackkitConfig("fixtures/hackkit.config.ts", {
+ cwd,
});
-
- expect(config.database).toBeDefined();
- expect(config.plugins.map((plugin) => plugin.id)).toEqual([
- "teams",
- "discord",
- "notificationsEmail",
- ]);
- expect(config.seedRoles.map((role) => role.id)).toEqual([
- "core.participant",
- "core.owner",
- ]);
+ expect(config.database.dbName).toBe(":memory:");
+ expect(config.plugins).toEqual([]);
});
});
diff --git a/packages/config/src/__tests__/fixtures/hackkit.config.ts b/packages/config/src/__tests__/fixtures/hackkit.config.ts
new file mode 100644
index 000000000..2ab459645
--- /dev/null
+++ b/packages/config/src/__tests__/fixtures/hackkit.config.ts
@@ -0,0 +1,5 @@
+import { SqliteDriver } from "@mikro-orm/sqlite";
+export default {
+ database: { driver: SqliteDriver, dbName: ":memory:" },
+ auth: {},
+};
diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts
index 82c2cb7ba..e648d79f2 100644
--- a/packages/config/src/index.ts
+++ b/packages/config/src/index.ts
@@ -9,7 +9,6 @@ import type {
SeedRoleInput,
UserDataOptionsInput,
} from "@hackkit/core";
-import { createJiti } from "jiti";
import { resolve } from "node:path";
import { fileURLToPath } from "node:url";
@@ -94,12 +93,12 @@ export function resolveHackkitConfig<
};
}
-const jiti = createJiti(fileURLToPath(import.meta.url));
-
export async function loadHackkitConfig(
configFile = "hackkit.config.ts",
options: { cwd?: string } = {},
): Promise {
+ const { createJiti } = await import("jiti");
+ const jiti = createJiti(fileURLToPath(import.meta.url));
const configPath = resolve(options.cwd ?? process.cwd(), configFile);
const module = await jiti.import(configPath);
const config = ((module as { default?: HackkitConfig }).default ??
diff --git a/packages/core/package.json b/packages/core/package.json
index 1ae955d35..8d4bb8c76 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -51,7 +51,8 @@
"better-auth": "1.7.6",
"zod": "^3.25.67",
"better-call": "1.4.0",
- "@better-fetch/fetch": "1.3.2"
+ "@better-fetch/fetch": "1.3.2",
+ "@mikro-orm/sql": "7.2.1"
},
"devDependencies": {
"typescript": "5.9.3",
diff --git a/packages/core/src/__tests__/public-profile.test.ts b/packages/core/src/__tests__/public-profile.test.ts
index 098470500..bd40ece2b 100644
--- a/packages/core/src/__tests__/public-profile.test.ts
+++ b/packages/core/src/__tests__/public-profile.test.ts
@@ -46,7 +46,7 @@ describe("public profiles", () => {
pronouns: "they/them",
skills: ["TypeScript", "Design"],
discordDisplayHandle: "hacker",
- profilePhotoUrl: "/api/files/view?key=profile-photos%2Favatar.png",
+ image: "/api/files/view?key=profile-photos%2Favatar.png",
isProfileSearchable: true,
});
diff --git a/packages/core/src/functions/events.ts b/packages/core/src/functions/events.ts
index 538de3b57..93690e0fc 100644
--- a/packages/core/src/functions/events.ts
+++ b/packages/core/src/functions/events.ts
@@ -1,6 +1,6 @@
import { serialize } from "@mikro-orm/core";
import type { HackkitRuntimeContext } from "../hackkit-context";
-import { eventTypeValueSchema } from "../event-types";
+import { eventTypeValueSchema, type EventTypes } from "../event-types";
import { HackKitError, parseInput } from "../errors";
import { withDomainLog } from "../domain-log";
import { coreModels } from "../models";
@@ -45,13 +45,20 @@ function filterVisibleEvents(events: Event[], includeHidden: boolean): Event[] {
return events.filter((event) => !event.hidden);
}
-export function createEventsApi(context: EventsApiContext) {
- const createEventSchema = createEventSchemaFactory(
- eventTypeValueSchema(context.eventTypes),
- );
- const updateEventSchema = updateEventSchemaFactory(
- eventTypeValueSchema(context.eventTypes),
- );
+/** Compile event validation once for a runtime's configured event types. */
+export function createEventSchemas(eventTypes: EventTypes) {
+ const typeSchema = eventTypeValueSchema(eventTypes);
+ return {
+ createEventSchema: createEventSchemaFactory(typeSchema),
+ updateEventSchema: updateEventSchemaFactory(typeSchema),
+ };
+}
+
+export function createEventsApi(
+ context: EventsApiContext,
+ schemas = createEventSchemas(context.eventTypes),
+) {
+ const { createEventSchema, updateEventSchema } = schemas;
const { em, now, id, logger, getUserOrThrow, requirePermission } = context;
diff --git a/packages/core/src/functions/users.ts b/packages/core/src/functions/users.ts
index 6e0080596..4928b02bc 100644
--- a/packages/core/src/functions/users.ts
+++ b/packages/core/src/functions/users.ts
@@ -73,7 +73,7 @@ export function createUsersApi(context: UsersApiContext) {
user: {
id: user.id,
name: user.name,
- profilePhotoUrl: user.profilePhotoUrl,
+ image: user.image,
hackTag: user.hackTag,
bio: user.bio,
pronouns: user.pronouns,
@@ -186,7 +186,7 @@ export function createUsersApi(context: UsersApiContext) {
updated,
{
name: parsed.name,
- profilePhotoUrl: parsed.profilePhotoUrl,
+ image: parsed.image,
hackTag: parsed.hackTag,
bio: parsed.bio,
pronouns: parsed.pronouns,
diff --git a/packages/core/src/hackkit.ts b/packages/core/src/hackkit.ts
index 37f306286..e9cf45867 100644
--- a/packages/core/src/hackkit.ts
+++ b/packages/core/src/hackkit.ts
@@ -31,7 +31,7 @@ import type {
UserId,
} from "./types";
import { createUsersApi } from "./functions/users";
-import { createEventsApi } from "./functions/events";
+import { createEventsApi, createEventSchemas } from "./functions/events";
import { createSettingsApi } from "./functions/settings";
import { createAdminApi } from "./functions/admin";
import { createCompetitorRegistrationPolicy } from "./functions/registration-policy";
@@ -70,366 +70,407 @@ const defaultId = () =>
export function createHackkit<
const TPlugins extends readonly HackKitPlugin[] = [],
>(options: CreateHackkitOptions) {
+ return createHackkitFactory(options)(
+ options.em,
+ options.actorAuthId,
+ );
+}
+
+/** Prepare shared configuration once; bind a fresh EntityManager for each execution. */
+export function createHackkitFactory<
+ const TPlugins extends readonly HackKitPlugin[] = [],
+>(options: Omit, "em" | "actorAuthId">) {
const plugins = options.plugins ?? ([] as unknown as TPlugins);
const registry = options.registry ?? createPluginRegistry(plugins);
const now = options.clock ?? (() => new Date());
const id = options.id ?? defaultId;
- const em = options.em;
const userDataOptions = resolveUserDataOptions(options.userDataOptions);
const eventTypes = resolveEventTypes(options.eventTypes);
+ const eventSchemas = createEventSchemas(eventTypes);
const groups = resolveGroups(options.groups);
const completeUserDataSchema =
createCompleteUserDataSchema(userDataOptions);
const logger = createLogger(options.logger);
const defaultCompetitorRoleId = options.defaultCompetitorRoleId;
- const notificationsApi = createNotificationsApi({ em, now });
- async function getUserOrThrow(authId: AuthId): Promise {
- const user = await readUser(em, { id: authId });
- if (!user) throw new HackKitError("NOT_FOUND", "User not found.");
- return user;
- }
+ return function createScopedHackkit(
+ em: EntityManager,
+ actorAuthId?: string,
+ ) {
+ const notificationsApi = createNotificationsApi({ em, now });
- async function getRoleOrThrow(roleId: RoleId): Promise {
- const role = await em.findOne(coreModels.role, { id: roleId });
- if (!role) throw new HackKitError("NOT_FOUND", "Role not found.");
- return serialize(role);
- }
+ async function getUserOrThrow(authId: AuthId): Promise {
+ const user = await readUser(em, { id: authId });
+ if (!user) throw new HackKitError("NOT_FOUND", "User not found.");
+ return user;
+ }
- const accessControl = createAccessControl({
- getUserOrThrow,
- getRoleOrThrow,
- });
- const settingsApi = createSettingsApi({
- em,
- now,
- logger,
- settings: registry.settings,
- requirePermission: accessControl.requirePermission,
- });
- const pluginApis = setupPluginApis(plugins, {
- em,
- actorAuthId: options.actorAuthId,
- getUser: (authId) => readUser(em, { id: authId }),
- registry,
- getSettingValue: settingsApi.getValue,
- notifications: notificationsApi,
- groups,
- });
+ async function getRoleOrThrow(roleId: RoleId): Promise {
+ const role = await em.findOne(coreModels.role, { id: roleId });
+ if (!role) throw new HackKitError("NOT_FOUND", "Role not found.");
+ return serialize(role);
+ }
- const runtimeContext: HackkitRuntimeContext = {
- em,
- now,
- id,
- logger,
- defaultCompetitorRoleId,
- getSettingValue: settingsApi.getValue,
- eventTypes,
- userDataOptions,
- groups,
- getUserOrThrow,
- getRoleOrThrow,
- requirePermission: accessControl.requirePermission,
- assertCanManageRole: accessControl.assertCanManageRole,
- accessControl,
- notifications: notificationsApi,
- };
+ const accessControl = createAccessControl({
+ getUserOrThrow,
+ getRoleOrThrow,
+ });
+ const settingsApi = createSettingsApi({
+ em,
+ now,
+ logger,
+ settings: registry.settings,
+ requirePermission: accessControl.requirePermission,
+ });
+ const pluginApis = setupPluginApis(plugins, {
+ em,
+ actorAuthId,
+ getUser: (authId) => readUser(em, { id: authId }),
+ registry,
+ getSettingValue: settingsApi.getValue,
+ notifications: notificationsApi,
+ groups,
+ });
- const registrationPolicy =
- createCompetitorRegistrationPolicy(runtimeContext);
- const rsvpApi = createRsvpApi(runtimeContext);
- const groupsApi = createGroupsApi(runtimeContext);
+ const runtimeContext: HackkitRuntimeContext = {
+ em,
+ now,
+ id,
+ logger,
+ defaultCompetitorRoleId,
+ getSettingValue: settingsApi.getValue,
+ eventTypes,
+ userDataOptions,
+ groups,
+ getUserOrThrow,
+ getRoleOrThrow,
+ requirePermission: accessControl.requirePermission,
+ assertCanManageRole: accessControl.assertCanManageRole,
+ accessControl,
+ notifications: notificationsApi,
+ };
- async function registerHacker(input: unknown): Promise {
- return withOperationLock(em, "registration", async () => {
- const parsed = parseInput(registerHackerSchema, input);
- return withDomainLog(
- logger,
- "hackers.register",
- { targetAuthId: parsed.userId },
- async () => {
- await getUserOrThrow(parsed.userId);
- const userData = await em.findOne(coreModels.userData, {
- authId: parsed.userId,
- });
- if (!userData)
- throw new HackKitError(
- "INVALID_OPERATION",
- "User Data must be completed before registering as a Hacker.",
- );
- const existing = await em.findOne(coreModels.hacker, {
- userId: parsed.userId,
- });
- const timestamp = now();
- const value: Hacker = {
- ...parsed,
- registeredAt: existing?.registeredAt ?? timestamp,
- updatedAt: timestamp,
- };
+ const registrationPolicy =
+ createCompetitorRegistrationPolicy(runtimeContext);
+ const rsvpApi = createRsvpApi(runtimeContext);
+ const groupsApi = createGroupsApi(runtimeContext);
+
+ async function registerHacker(input: unknown): Promise {
+ return withOperationLock(em, "registration", async () => {
+ const parsed = parseInput(registerHackerSchema, input);
+ return withDomainLog(
+ logger,
+ "hackers.register",
+ { targetAuthId: parsed.userId },
+ async () => {
+ await getUserOrThrow(parsed.userId);
+ const userData = await em.findOne(coreModels.userData, {
+ authId: parsed.userId,
+ });
+ if (!userData)
+ throw new HackKitError(
+ "INVALID_OPERATION",
+ "User Data must be completed before registering as a Hacker.",
+ );
+ const existing = await em.findOne(coreModels.hacker, {
+ userId: parsed.userId,
+ });
+ const timestamp = now();
+ const value: Hacker = {
+ ...parsed,
+ registeredAt: existing?.registeredAt ?? timestamp,
+ updatedAt: timestamp,
+ };
- if (existing) {
- em.assign(existing, value, { ignoreUndefined: true });
+ if (existing) {
+ em.assign(existing, value, {
+ ignoreUndefined: true,
+ });
+ await em.flush();
+ return serialize(existing);
+ }
+ const { requireApproval } =
+ await registrationPolicy.assertCanRegisterNewHacker();
+ const hacker = em.create(coreModels.hacker, value);
+ const profile = await em.findOneOrFail(
+ coreModels.user,
+ {
+ id: parsed.userId,
+ },
+ );
+ if (defaultCompetitorRoleId) {
+ await getRoleOrThrow(defaultCompetitorRoleId);
+ profile.roleId = defaultCompetitorRoleId;
+ profile.isApproved = !requireApproval;
+ } else if (!requireApproval) {
+ profile.isApproved = true;
+ }
+ profile.updatedAt = timestamp;
await em.flush();
- return serialize(existing);
- }
- const { requireApproval } =
- await registrationPolicy.assertCanRegisterNewHacker();
- const hacker = em.create(coreModels.hacker, value);
- const profile = await em.findOneOrFail(coreModels.user, {
- id: parsed.userId,
- });
- if (defaultCompetitorRoleId) {
- await getRoleOrThrow(defaultCompetitorRoleId);
- profile.roleId = defaultCompetitorRoleId;
- profile.isApproved = !requireApproval;
- } else if (!requireApproval) {
- profile.isApproved = true;
- }
- profile.updatedAt = timestamp;
- await em.flush();
- return serialize(hacker);
- },
- );
- });
- }
+ return serialize(hacker);
+ },
+ );
+ });
+ }
- const hackkit = {
- models: coreModels,
- permissions: CorePermission,
- registry,
- plugins: pluginApis,
- isPluginEnabled(pluginId: string): boolean {
- const plugin = registry.plugins[pluginId];
- return (
- Object.hasOwn(registry.plugins, pluginId) &&
- plugin.enabled !== false
- );
- },
- accessControl,
- settings: settingsApi,
- notifications: notificationsApi,
- users: createUsersApi({
- ...runtimeContext,
- registrationPolicy,
+ const hackkit = {
+ models: coreModels,
+ permissions: CorePermission,
+ registry,
+ plugins: pluginApis,
+ isPluginEnabled(pluginId: string): boolean {
+ const plugin = registry.plugins[pluginId];
+ return (
+ Object.hasOwn(registry.plugins, pluginId) &&
+ plugin.enabled !== false
+ );
+ },
+ accessControl,
+ settings: settingsApi,
+ notifications: notificationsApi,
+ users: createUsersApi({
+ ...runtimeContext,
+ registrationPolicy,
+ groups: groupsApi,
+ }),
+ rsvp: rsvpApi,
groups: groupsApi,
- }),
- rsvp: rsvpApi,
- groups: groupsApi,
- events: createEventsApi(runtimeContext),
- admin: createAdminApi(runtimeContext),
+ events: createEventsApi(runtimeContext, eventSchemas),
+ admin: createAdminApi(runtimeContext),
- userData: {
- options: userDataOptions,
+ userData: {
+ options: userDataOptions,
- async getUserData(authId: AuthId): Promise {
- const record = await em.findOne(coreModels.userData, {
- authId,
- });
- return record ? serialize(record) : null;
- },
+ async getUserData(authId: AuthId): Promise {
+ const record = await em.findOne(coreModels.userData, {
+ authId,
+ });
+ return record ? serialize(record) : null;
+ },
- async completeUserData(input: unknown): Promise {
- return withOperationLock(em, "user-data", async () => {
- const parsed = parseInput(completeUserDataSchema, input);
- await getUserOrThrow(parsed.authId);
- const existing = await em.findOne(coreModels.userData, {
- authId: parsed.authId,
+ async completeUserData(input: unknown): Promise {
+ return withOperationLock(em, "user-data", async () => {
+ const parsed = parseInput(
+ completeUserDataSchema,
+ input,
+ );
+ await getUserOrThrow(parsed.authId);
+ const existing = await em.findOne(coreModels.userData, {
+ authId: parsed.authId,
+ });
+ const timestamp = now();
+ const value: UserData = {
+ ...parsed,
+ completedAt: existing?.completedAt ?? timestamp,
+ updatedAt: timestamp,
+ };
+ const record = existing
+ ? em.assign(existing, value, {
+ ignoreUndefined: true,
+ })
+ : em.create(coreModels.userData, value);
+ await em.flush();
+ return serialize(record);
});
- const timestamp = now();
- const value: UserData = {
- ...parsed,
- completedAt: existing?.completedAt ?? timestamp,
- updatedAt: timestamp,
- };
- const record = existing
- ? em.assign(existing, value, { ignoreUndefined: true })
- : em.create(coreModels.userData, value);
- await em.flush();
- return serialize(record);
- });
+ },
},
- },
- hackers: {
- registerHacker,
+ hackers: {
+ registerHacker,
- async getHacker(userId: UserId): Promise {
- const record = await em.findOne(coreModels.hacker, { userId });
- return record ? serialize(record) : null;
+ async getHacker(userId: UserId): Promise {
+ const record = await em.findOne(coreModels.hacker, {
+ userId,
+ });
+ return record ? serialize(record) : null;
+ },
},
- },
- roles: {
- async listRoles(input?: { actorAuthId?: AuthId }): Promise {
- if (input?.actorAuthId)
- await accessControl.requirePermission(
- input.actorAuthId,
- CorePermission.RolesView,
+ roles: {
+ async listRoles(input?: {
+ actorAuthId?: AuthId;
+ }): Promise {
+ if (input?.actorAuthId)
+ await accessControl.requirePermission(
+ input.actorAuthId,
+ CorePermission.RolesView,
+ );
+ return serialize(
+ await em.find(
+ coreModels.role,
+ {},
+ { orderBy: { position: "asc" } },
+ ),
);
- return serialize(
- await em.find(
- coreModels.role,
- {},
- { orderBy: { position: "asc" } },
- ),
- );
- },
-
- async getRole(roleId: RoleId): Promise {
- const record = await em.findOne(coreModels.role, {
- id: roleId,
- });
- return record ? serialize(record) : null;
- },
+ },
- async createRole(input: unknown): Promise {
- return withOperationLock(em, "roles", async () => {
- const parsed = parseInput(createRoleSchema, input);
- const principal = await accessControl.requirePermission(
- parsed.actorAuthId,
- CorePermission.RolesCreate,
- );
- const rolePosition = {
- ...principal.role,
- position: parsed.position,
- };
- accessControl.assertCanManageRole(principal, rolePosition);
- accessControl.assertCanGrantPermissions(
- principal,
- parsed.permissions as PermissionKey[],
- );
- const existingName = await em.findOne(coreModels.role, {
- name: parsed.name,
+ async getRole(roleId: RoleId): Promise {
+ const record = await em.findOne(coreModels.role, {
+ id: roleId,
});
- if (existingName)
- throw new HackKitError(
- "CONFLICT",
- "Role name already exists.",
- );
- const timestamp = now();
- {
- const created = em.create(coreModels.role, {
- id: parsed.id ?? id(),
- name: parsed.name,
- position: parsed.position,
- permissions: parsed.permissions as PermissionKey[],
- color: parsed.color,
- createdAt: timestamp,
- updatedAt: timestamp,
- });
- await em.flush();
- return serialize(created);
- }
- });
- },
+ return record ? serialize(record) : null;
+ },
- async updateRole(input: unknown): Promise {
- return withOperationLock(em, "roles", async () => {
- const parsed = parseInput(updateRoleSchema, input);
- const principal = await accessControl.requirePermission(
- parsed.actorAuthId,
- CorePermission.RolesUpdate,
- );
- const role = await getRoleOrThrow(parsed.roleId);
- accessControl.assertCanManageRole(principal, role);
- if (parsed.position !== undefined)
- accessControl.assertCanManageRole(principal, {
- ...role,
+ async createRole(input: unknown): Promise {
+ return withOperationLock(em, "roles", async () => {
+ const parsed = parseInput(createRoleSchema, input);
+ const principal = await accessControl.requirePermission(
+ parsed.actorAuthId,
+ CorePermission.RolesCreate,
+ );
+ const rolePosition = {
+ ...principal.role,
position: parsed.position,
- });
- if (parsed.permissions)
+ };
+ accessControl.assertCanManageRole(
+ principal,
+ rolePosition,
+ );
accessControl.assertCanGrantPermissions(
principal,
parsed.permissions as PermissionKey[],
);
- const updated = await em.findOne(coreModels.role, {
- id: parsed.roleId,
- });
- if (updated) {
- em.assign(
- updated,
- {
+ const existingName = await em.findOne(coreModels.role, {
+ name: parsed.name,
+ });
+ if (existingName)
+ throw new HackKitError(
+ "CONFLICT",
+ "Role name already exists.",
+ );
+ const timestamp = now();
+ {
+ const created = em.create(coreModels.role, {
+ id: parsed.id ?? id(),
name: parsed.name,
position: parsed.position,
- permissions: parsed.permissions as
- | PermissionKey[]
- | undefined,
+ permissions:
+ parsed.permissions as PermissionKey[],
color: parsed.color,
- updatedAt: now(),
- },
- { ignoreUndefined: true },
- );
- await em.flush();
- }
- if (!updated)
- throw new HackKitError("NOT_FOUND", "Role not found.");
- return serialize(updated);
- });
- },
+ createdAt: timestamp,
+ updatedAt: timestamp,
+ });
+ await em.flush();
+ return serialize(created);
+ }
+ });
+ },
- async deleteRole(input: unknown): Promise {
- return withOperationLock(em, "roles", async () => {
- const parsed = parseInput(deleteRoleSchema, input);
- const principal = await accessControl.requirePermission(
- parsed.actorAuthId,
- CorePermission.RolesDelete,
- );
- const role = await getRoleOrThrow(parsed.roleId);
- accessControl.assertCanManageRole(principal, role);
- const usersWithRole = await em.find(
- coreModels.user,
- { roleId: parsed.roleId },
- { limit: 1 },
- );
- if (usersWithRole.length > 0)
- throw new HackKitError(
- "INVALID_OPERATION",
- "Cannot delete a role assigned to users.",
+ async updateRole(input: unknown): Promise {
+ return withOperationLock(em, "roles", async () => {
+ const parsed = parseInput(updateRoleSchema, input);
+ const principal = await accessControl.requirePermission(
+ parsed.actorAuthId,
+ CorePermission.RolesUpdate,
);
- await em.nativeDelete(coreModels.role, {
- id: parsed.roleId,
+ const role = await getRoleOrThrow(parsed.roleId);
+ accessControl.assertCanManageRole(principal, role);
+ if (parsed.position !== undefined)
+ accessControl.assertCanManageRole(principal, {
+ ...role,
+ position: parsed.position,
+ });
+ if (parsed.permissions)
+ accessControl.assertCanGrantPermissions(
+ principal,
+ parsed.permissions as PermissionKey[],
+ );
+ const updated = await em.findOne(coreModels.role, {
+ id: parsed.roleId,
+ });
+ if (updated) {
+ em.assign(
+ updated,
+ {
+ name: parsed.name,
+ position: parsed.position,
+ permissions: parsed.permissions as
+ PermissionKey[] | undefined,
+ color: parsed.color,
+ updatedAt: now(),
+ },
+ { ignoreUndefined: true },
+ );
+ await em.flush();
+ }
+ if (!updated)
+ throw new HackKitError(
+ "NOT_FOUND",
+ "Role not found.",
+ );
+ return serialize(updated);
});
- });
- },
+ },
- async assignRoleToUser(input: unknown): Promise {
- return withOperationLock(em, "roles", async () => {
- const parsed = parseInput(assignRoleSchema, input);
- const principal = await accessControl.requirePermission(
- parsed.actorAuthId,
- CorePermission.RolesAssign,
- );
- const target = await getUserOrThrow(parsed.targetAuthId);
- const nextRole = await getRoleOrThrow(parsed.roleId);
- accessControl.assertCanManageRole(principal, nextRole);
- if (target.roleId)
- accessControl.assertCanManageRole(
- principal,
- await getRoleOrThrow(target.roleId),
+ async deleteRole(input: unknown): Promise {
+ return withOperationLock(em, "roles", async () => {
+ const parsed = parseInput(deleteRoleSchema, input);
+ const principal = await accessControl.requirePermission(
+ parsed.actorAuthId,
+ CorePermission.RolesDelete,
+ );
+ const role = await getRoleOrThrow(parsed.roleId);
+ accessControl.assertCanManageRole(principal, role);
+ const usersWithRole = await em.find(
+ coreModels.user,
+ { roleId: parsed.roleId },
+ { limit: 1 },
);
- const updated = await em.findOne(coreModels.user, {
- id: parsed.targetAuthId,
+ if (usersWithRole.length > 0)
+ throw new HackKitError(
+ "INVALID_OPERATION",
+ "Cannot delete a role assigned to users.",
+ );
+ await em.nativeDelete(coreModels.role, {
+ id: parsed.roleId,
+ });
});
- if (updated) {
- em.assign(
- updated,
- {
- roleId: parsed.roleId,
- updatedAt: now(),
- },
- { ignoreUndefined: true },
+ },
+
+ async assignRoleToUser(input: unknown): Promise {
+ return withOperationLock(em, "roles", async () => {
+ const parsed = parseInput(assignRoleSchema, input);
+ const principal = await accessControl.requirePermission(
+ parsed.actorAuthId,
+ CorePermission.RolesAssign,
);
- await em.flush();
- }
- if (!updated)
- throw new HackKitError("NOT_FOUND", "User not found.");
- return getUserOrThrow(parsed.targetAuthId);
- });
+ const target = await getUserOrThrow(
+ parsed.targetAuthId,
+ );
+ const nextRole = await getRoleOrThrow(parsed.roleId);
+ accessControl.assertCanManageRole(principal, nextRole);
+ if (target.roleId)
+ accessControl.assertCanManageRole(
+ principal,
+ await getRoleOrThrow(target.roleId),
+ );
+ const updated = await em.findOne(coreModels.user, {
+ id: parsed.targetAuthId,
+ });
+ if (updated) {
+ em.assign(
+ updated,
+ {
+ roleId: parsed.roleId,
+ updatedAt: now(),
+ },
+ { ignoreUndefined: true },
+ );
+ await em.flush();
+ }
+ if (!updated)
+ throw new HackKitError(
+ "NOT_FOUND",
+ "User not found.",
+ );
+ return getUserOrThrow(parsed.targetAuthId);
+ });
+ },
},
- },
- };
+ };
- return hackkit as typeof hackkit & { plugins: PluginApiMap };
+ return hackkit as typeof hackkit & { plugins: PluginApiMap };
+ };
}
export type HackKit = ReturnType;
diff --git a/packages/core/src/mikro/auth-lifecycle.test.ts b/packages/core/src/mikro/auth-lifecycle.test.ts
index bf929057b..193ccc90a 100644
--- a/packages/core/src/mikro/auth-lifecycle.test.ts
+++ b/packages/core/src/mikro/auth-lifecycle.test.ts
@@ -92,7 +92,7 @@ describe("Core auth lifecycle", () => {
await hackkit.users.updateProfile({
authId: id,
name: "Joshua Silva",
- profilePhotoUrl: "/api/files/view/avatar.png",
+ image: "/api/files/view/avatar.png",
bio: "Hello",
});
expect(
@@ -114,7 +114,7 @@ describe("Core auth lifecycle", () => {
).toMatchObject({
id,
name: "Josh",
- profilePhotoUrl: "https://example.com/avatar.png",
+ image: "https://example.com/avatar.png",
bio: "Hello",
});
const signin = await auth.api.signInEmail({
diff --git a/packages/core/src/mikro/auth.ts b/packages/core/src/mikro/auth.ts
index 4e1b7c1aa..5779ac345 100644
--- a/packages/core/src/mikro/auth.ts
+++ b/packages/core/src/mikro/auth.ts
@@ -15,7 +15,7 @@ const authUserProperties = new Set([
"name",
"email",
"emailVerified",
- "profilePhotoUrl",
+ "image",
"createdAt",
"updatedAt",
]);
@@ -34,7 +34,6 @@ export function resolveHackKitAuthOptions<
user: {
...options.user,
modelName: "core_user",
- fields: { image: "profilePhotoUrl" },
},
};
}
diff --git a/packages/core/src/mikro/options.ts b/packages/core/src/mikro/options.ts
index 2b381db6c..2275acd09 100644
--- a/packages/core/src/mikro/options.ts
+++ b/packages/core/src/mikro/options.ts
@@ -1,5 +1,6 @@
import type { Options, EntitySchema } from "@mikro-orm/core";
import type { SqliteDriver } from "@mikro-orm/sqlite";
+import type { SqliteDriver as GenericSqliteDriver } from "@mikro-orm/sql";
import type { LibSqlDriver } from "@mikro-orm/libsql";
import type { MySqlDriver } from "@mikro-orm/mysql";
import type { PostgreSqlDriver } from "@mikro-orm/postgresql";
@@ -9,6 +10,7 @@ import { assertAuthEntitySchema, type HackKitAuthOptions } from "./auth";
export type HackKitDriver =
| SqliteDriver
+ | GenericSqliteDriver
| LibSqlDriver
| MySqlDriver
| PostgreSqlDriver;
diff --git a/packages/core/src/models.ts b/packages/core/src/models.ts
index 32dd1a9b4..23e4ff3f8 100644
--- a/packages/core/src/models.ts
+++ b/packages/core/src/models.ts
@@ -29,7 +29,7 @@ export const HackKitUser = defineEntity({
name: p.string(),
email: p.string().unique(),
emailVerified: p.boolean().default(false),
- profilePhotoUrl: p.text().nullable(),
+ image: p.text().nullable(),
hackTag: p.string().nullable().unique(),
bio: p.text().nullable(),
pronouns: p.string().nullable(),
diff --git a/packages/core/src/notifications.ts b/packages/core/src/notifications.ts
index c727f8b1d..70e87cdcd 100644
--- a/packages/core/src/notifications.ts
+++ b/packages/core/src/notifications.ts
@@ -59,8 +59,7 @@ export type CoreNotificationPayloadMap = {
};
export type NotificationPayload =
- | CoreNotificationPayloadMap[CoreNotificationKind]
- | Record;
+ CoreNotificationPayloadMap[CoreNotificationKind] | Record;
export type QueueNotificationIntentInput<
TKind extends NotificationKind = NotificationKind,
diff --git a/packages/core/src/runtime.test.ts b/packages/core/src/runtime.test.ts
index 56fb90000..00a157d93 100644
--- a/packages/core/src/runtime.test.ts
+++ b/packages/core/src/runtime.test.ts
@@ -1,6 +1,9 @@
import { SqliteDriver } from "@mikro-orm/sqlite";
+import { RequestContext } from "@mikro-orm/core";
import { expect, it } from "vitest";
import { initializeHackkit } from "./runtime";
+import { coreModels } from "./models";
+import type { HackKitPlugin } from "./plugins";
it("shares auth and connections while isolating domain execution scopes", async () => {
const runtime = await initializeHackkit({
@@ -43,3 +46,74 @@ it("shares auth and connections while isolating domain execution scopes", async
await runtime.orm.close();
}
});
+
+it("shares prepared configuration while isolating concurrent actors and managed entities", async () => {
+ const plugins = [
+ { id: "probe", setup: (context) => context },
+ ] as const satisfies readonly HackKitPlugin[];
+ const runtime = await initializeHackkit({
+ database: { driver: SqliteDriver, dbName: ":memory:" },
+ auth: { secret: "local-test-secret-with-at-least-32-characters" },
+ logger: { disabled: true },
+ groups: ["builders"],
+ plugins,
+ });
+ try {
+ await runtime.orm.schema.create();
+ const first = runtime.createScope("first");
+ const second = runtime.createScope("second");
+ expect(first.hackkit.events.options).toBe(
+ second.hackkit.events.options,
+ );
+ expect(first.hackkit.userData.options).toBe(
+ second.hackkit.userData.options,
+ );
+ expect(first.hackkit.plugins.probe.groups).toBe(
+ second.hackkit.plugins.probe.groups,
+ );
+ expect(first.hackkit.plugins.probe.em).toBe(first.em);
+ expect(second.hackkit.plugins.probe.em).toBe(second.em);
+ first.em.create(coreModels.user, {
+ id: "participant",
+ name: "Participant",
+ email: "participant@example.com",
+ });
+ await first.em.flush();
+
+ let arrive = () => {};
+ const bothStarted = new Promise((resolve) => {
+ arrive = resolve;
+ });
+ let started = 0;
+ const results = await Promise.all(
+ ["first", "second"].map((actor) =>
+ runtime.run(async ({ em, hackkit }) => {
+ if (++started === 2) arrive();
+ await bothStarted;
+ expect(RequestContext.getEntityManager()).toBe(em);
+ expect(em.getContext()).toBe(em);
+ expect(hackkit.plugins.probe.em).toBe(em);
+ expect(hackkit.plugins.probe.actorAuthId).toBe(actor);
+ const user = await em.findOneOrFail(coreModels.user, {
+ id: "participant",
+ });
+ user.name = actor;
+ await Promise.resolve();
+ expect(user.name).toBe(actor);
+ return { em, user };
+ }, actor),
+ ),
+ );
+ expect(results[0]?.em).not.toBe(results[1]?.em);
+ expect(results[0]?.user).not.toBe(results[1]?.user);
+ expect(
+ (
+ await second.em.findOneOrFail(coreModels.user, {
+ id: "participant",
+ })
+ ).name,
+ ).toBe("Participant");
+ } finally {
+ await runtime.orm.close();
+ }
+});
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 9c881d9b6..1e73cf5bb 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -1,6 +1,10 @@
import { MikroORM, RequestContext, type EntityManager } from "@mikro-orm/core";
import { createLogger } from "./adapters/logger";
-import { createHackkit, type CreateHackkitOptions } from "./hackkit";
+import {
+ createHackkitFactory,
+ type createHackkit,
+ type CreateHackkitOptions,
+} from "./hackkit";
import {
createPluginRegistry,
type HackKitPlugin,
@@ -45,6 +49,10 @@ export async function initializeHackkit<
options: InitializeHackkitOptions,
): Promise> {
const registry = createPluginRegistry(options.plugins, options.entities);
+ const createScopedHackkit = createHackkitFactory({
+ ...options,
+ registry,
+ });
const orm = await MikroORM.init(createOrmOptions(options));
let auth: ReturnType;
try {
@@ -66,15 +74,20 @@ export async function initializeHackkit<
const em = orm.em.fork({ useContext: true });
return {
em,
- hackkit: createHackkit({ ...options, em, registry, actorAuthId }),
+ hackkit: createScopedHackkit(em, actorAuthId),
};
}
function run(
operation: (scope: ReturnType) => Promise,
actorAuthId?: string,
) {
- const scope = createScope(actorAuthId);
- return RequestContext.create(scope.em, () => operation(scope));
+ return RequestContext.create(orm.em, () => {
+ const em = orm.em.getContext();
+ return operation({
+ em,
+ hackkit: createScopedHackkit(em, actorAuthId),
+ });
+ });
}
return { orm, auth, registry, createScope, run };
}
diff --git a/packages/core/src/schemas.ts b/packages/core/src/schemas.ts
index 463ab5dd2..c4106c6e5 100644
--- a/packages/core/src/schemas.ts
+++ b/packages/core/src/schemas.ts
@@ -19,7 +19,7 @@ export const hackTagSchema = z
export const updateUserProfileSchema = z.object({
authId: authIdSchema,
name: z.string().trim().min(1).max(200).optional(),
- profilePhotoUrl: z
+ image: z
.union([
z.string().url(),
z
diff --git a/packages/core/src/settings.ts b/packages/core/src/settings.ts
index ebaea054e..9c2ef1c57 100644
--- a/packages/core/src/settings.ts
+++ b/packages/core/src/settings.ts
@@ -28,8 +28,7 @@ export type NumberSettingDefinition = {
};
export type HackathonSettingDefinition =
- | BooleanSettingDefinition
- | NumberSettingDefinition;
+ BooleanSettingDefinition | NumberSettingDefinition;
export type SettingValueForDefinition =
TDefinition extends BooleanSettingDefinition
@@ -148,7 +147,9 @@ export const coreSettings = [
export type CoreSettingDefinition = (typeof coreSettings)[number];
export type CoreSettingValueMap = {
- [Definition in CoreSettingDefinition as Definition["key"]]: SettingValueForDefinition;
+ [
+ Definition in CoreSettingDefinition as Definition["key"]
+ ]: SettingValueForDefinition;
};
export function defineSetting<
diff --git a/packages/core/src/testing.ts b/packages/core/src/testing.ts
index d2357241f..9ff504342 100644
--- a/packages/core/src/testing.ts
+++ b/packages/core/src/testing.ts
@@ -49,14 +49,14 @@ export async function createTestUser(
authId: string;
email: string;
name: string;
- profilePhotoUrl?: string;
+ image?: string;
},
) {
context.em.create(HackKitUser, {
id: input.authId,
email: input.email,
name: input.name,
- profilePhotoUrl: input.profilePhotoUrl,
+ image: input.image,
createdAt: new Date("2026-05-24T12:00:00.000Z"),
updatedAt: new Date("2026-05-24T12:00:00.000Z"),
});
diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts
index cbbc018a9..81f490c78 100644
--- a/packages/core/src/types.ts
+++ b/packages/core/src/types.ts
@@ -38,7 +38,7 @@ export type PublicUserProfile = {
User,
| "id"
| "name"
- | "profilePhotoUrl"
+ | "image"
| "hackTag"
| "bio"
| "pronouns"
diff --git a/packages/next/README.md b/packages/next/README.md
index 55ca3199f..c0c23172a 100644
--- a/packages/next/README.md
+++ b/packages/next/README.md
@@ -4,7 +4,7 @@ Next.js request setup and page guards for HackKit. Core owns the HTTP endpoints
## Runtime setup
-`createHackkitRuntimeFromConfig({ config, afterCurrentUser? })` returns a shared `core` promise, a request-local `getRuntime` factory, and an HTTP `handler`. Register `host.getRuntime` with `setHackkitRuntime` for package-owned plugin pages. The reference implementation is [the app runtime](../../apps/web/lib/runtime.ts).
+`createHackkitRuntimeFromConfig({ config, afterCurrentUser? })` returns a shared `core` promise, a request-local `getRuntime` factory, and an HTTP `handler`. Register `host.getRuntime` with `setHackkitRuntime` for package-owned plugin pages. The reference implementation is [the app runtime](../../templates/nextjs-full/lib/runtime.ts).
The host initializes one Core ORM and Better Auth instance. Each server render resolves its session from Next headers and creates a fresh domain scope. React caches this runtime within that render. HTTP calls resolve the session from their Web Request and run their operation inside Core's native MikroORM RequestContext. Shared endpoint definitions never retain a request's actor or EntityManager.
diff --git a/packages/plugin-discord/src/api.ts b/packages/plugin-discord/src/api.ts
index 3c60c2055..4ac4f9ad2 100644
--- a/packages/plugin-discord/src/api.ts
+++ b/packages/plugin-discord/src/api.ts
@@ -73,7 +73,7 @@ function addMs(date: Date, ms: number): Date {
function roleRefsEqual(left: DiscordRoleRef, right: DiscordRoleRef): boolean {
return Boolean(
(left.id && left.id === right.id) ||
- (left.name && left.name === right.name),
+ (left.name && left.name === right.name),
);
}
diff --git a/packages/plugin-teams/package.json b/packages/plugin-teams/package.json
index 050d6ace3..526ec7a7a 100644
--- a/packages/plugin-teams/package.json
+++ b/packages/plugin-teams/package.json
@@ -51,6 +51,9 @@
"react-dom": ">=18"
},
"devDependencies": {
+ "next": "14.2.35",
+ "react": "18.3.1",
+ "react-dom": "18.3.1",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"typescript": "5.9.3",
diff --git a/packages/plugin-teams/src/components/team-dashboard.tsx b/packages/plugin-teams/src/components/team-dashboard.tsx
index 0b5371f24..d2db913f9 100644
--- a/packages/plugin-teams/src/components/team-dashboard.tsx
+++ b/packages/plugin-teams/src/components/team-dashboard.tsx
@@ -94,7 +94,7 @@ export function TeamDashboard({
Members
-
+
{team.members.map((member) => (
=18"
},
"devDependencies": {
+ "next": "14.2.35",
+ "react": "18.3.1",
+ "react-dom": "18.3.1",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"typescript": "5.9.3",
diff --git a/packages/ui/src/components/admin-console-controls.tsx b/packages/ui/src/components/admin-console-controls.tsx
index 3b30448cc..69229811e 100644
--- a/packages/ui/src/components/admin-console-controls.tsx
+++ b/packages/ui/src/components/admin-console-controls.tsx
@@ -50,9 +50,11 @@ const permissionValues = Object.values(CorePermission);
export function AdminUserActions({
record,
roles,
+ showEventOperations = true,
}: {
record: AdminUserRecord;
roles: Role[];
+ showEventOperations?: boolean;
}) {
const { client, navigation } = useHackKitUI();
const [pendingAction, setPendingAction] =
@@ -215,97 +217,104 @@ export function AdminUserActions({
)}
-
-
RSVP
-
- Current status: {formatRsvpStatus(record.rsvp)}
-
-
-
- run(
- "rsvpConfirm",
- () =>
- client("@post/rsvp/set-status", {
- body: {
- targetAuthId: record.user.id,
- status: "confirmed",
- },
- }),
- "RSVP marked confirmed.",
- )
- }
- >
- Confirm
-
-
- run(
- "rsvpWaitlist",
- () =>
- client("@post/rsvp/set-status", {
- body: {
- targetAuthId: record.user.id,
- status: "waitlisted",
- },
- }),
- "RSVP moved to waitlist.",
- )
- }
- >
- Waitlist
-
-
- run(
- "rsvpPromote",
- () =>
- client("@post/rsvp/promote", {
- body: {
- targetAuthId: record.user.id,
- },
- }),
- "Waitlisted RSVP promoted.",
- )
- }
- >
- Promote
-
-
- run(
- "rsvpCancel",
- () =>
- client("@post/rsvp/cancel", {
- body: {
- targetAuthId: record.user.id,
- },
- }),
- "RSVP cancelled.",
- )
- }
- >
- Cancel
-
+ {showEventOperations ? (
+
+
RSVP
+
+ Current status: {formatRsvpStatus(record.rsvp)}
+
+
+
+ run(
+ "rsvpConfirm",
+ () =>
+ client("@post/rsvp/set-status", {
+ body: {
+ targetAuthId:
+ record.user.id,
+ status: "confirmed",
+ },
+ }),
+ "RSVP marked confirmed.",
+ )
+ }
+ >
+ Confirm
+
+
+ run(
+ "rsvpWaitlist",
+ () =>
+ client("@post/rsvp/set-status", {
+ body: {
+ targetAuthId:
+ record.user.id,
+ status: "waitlisted",
+ },
+ }),
+ "RSVP moved to waitlist.",
+ )
+ }
+ >
+ Waitlist
+
+
+ run(
+ "rsvpPromote",
+ () =>
+ client("@post/rsvp/promote", {
+ body: {
+ targetAuthId:
+ record.user.id,
+ },
+ }),
+ "Waitlisted RSVP promoted.",
+ )
+ }
+ >
+ Promote
+
+
+ run(
+ "rsvpCancel",
+ () =>
+ client("@post/rsvp/cancel", {
+ body: {
+ targetAuthId:
+ record.user.id,
+ },
+ }),
+ "RSVP cancelled.",
+ )
+ }
+ >
+ Cancel
+
+
-
+ ) : null}
);
diff --git a/packages/ui/src/components/admin-console.tsx b/packages/ui/src/components/admin-console.tsx
index c7e3d602c..c063ed287 100644
--- a/packages/ui/src/components/admin-console.tsx
+++ b/packages/ui/src/components/admin-console.tsx
@@ -19,9 +19,13 @@ import { AdminUserActions, AdminRoleManager } from "./admin-console-controls";
export type AdminOverviewPanelProps = {
overview: AdminOverview;
+ showEventOperations?: boolean;
};
-export function AdminOverviewPanel({ overview }: AdminOverviewPanelProps) {
+export function AdminOverviewPanel({
+ overview,
+ showEventOperations = true,
+}: AdminOverviewPanelProps) {
const { Link, routes } = useHackKitNavigation();
const stats = [
["Registrations", overview.totalUsers],
@@ -29,9 +33,13 @@ export function AdminOverviewPanel({ overview }: AdminOverviewPanelProps) {
["Approved", overview.approvedUsers],
["Pending Approval", overview.pendingApprovalUsers],
["Suspended", overview.bannedUsers],
- ["Check-ins", overview.checkedInUsers],
- ["RSVPs", overview.confirmedRsvps],
- ["Waitlist", overview.waitlistedRsvps],
+ ...(showEventOperations
+ ? ([
+ ["Check-ins", overview.checkedInUsers],
+ ["RSVPs", overview.confirmedRsvps],
+ ["Waitlist", overview.waitlistedRsvps],
+ ] as const)
+ : []),
] as const;
return (
@@ -118,9 +126,14 @@ export function AdminOverviewPanel({ overview }: AdminOverviewPanelProps) {
export type AdminUsersTableProps = {
users: AdminUserRecord[];
exportHref?: string;
+ showEventOperations?: boolean;
};
-export function AdminUsersTable({ users, exportHref }: AdminUsersTableProps) {
+export function AdminUsersTable({
+ users,
+ exportHref,
+ showEventOperations = true,
+}: AdminUsersTableProps) {
const { Link, routes } = useHackKitNavigation();
return (
@@ -142,11 +155,17 @@ export function AdminUsersTable({ users, exportHref }: AdminUsersTableProps) {
User
Role
Status
-
RSVP
+ {showEventOperations ? (
+
RSVP
+ ) : null}
Registered
-
Check-in
+ {showEventOperations ? (
+
+ Check-in
+
+ ) : null}
@@ -198,19 +217,23 @@ export function AdminUsersTable({ users, exportHref }: AdminUsersTableProps) {
) : null}
-
- {formatRsvpStatus(record.rsvp)}
-
+ {showEventOperations ? (
+
+ {formatRsvpStatus(record.rsvp)}
+
+ ) : null}
{formatDateTime(record.user.createdAt)}
-
- {record.user.checkedInAt
- ? formatDateTime(
- record.user.checkedInAt,
- )
- : "Not checked in"}
-
+ {showEventOperations ? (
+
+ {record.user.checkedInAt
+ ? formatDateTime(
+ record.user.checkedInAt,
+ )
+ : "Not checked in"}
+
+ ) : null}
))}
@@ -223,9 +246,14 @@ export function AdminUsersTable({ users, exportHref }: AdminUsersTableProps) {
export type AdminUserDetailProps = {
record: AdminUserRecord;
roles: Role[];
+ showEventOperations?: boolean;
};
-export function AdminUserDetail({ record, roles }: AdminUserDetailProps) {
+export function AdminUserDetail({
+ record,
+ roles,
+ showEventOperations = true,
+}: AdminUserDetailProps) {
return (
@@ -258,18 +286,24 @@ export function AdminUserDetail({ record, roles }: AdminUserDetailProps) {
record.user.isApproved ? "Approved" : "Pending"
}
/>
-
-
+ {showEventOperations ? (
+ <>
+
+
+ >
+ ) : null}
@@ -366,7 +400,11 @@ export function AdminUserDetail({ record, roles }: AdminUserDetailProps) {
-
+
);
}
diff --git a/packages/ui/src/components/hacker-registration-form.tsx b/packages/ui/src/components/hacker-registration-form.tsx
index 0bf6b23ff..938b14b00 100644
--- a/packages/ui/src/components/hacker-registration-form.tsx
+++ b/packages/ui/src/components/hacker-registration-form.tsx
@@ -94,11 +94,12 @@ function SelectField({
options: readonly { value: string; label: string }[];
error?: string;
}) {
+ const id = React.useId();
return (
-
{label}
+
{label}
-
+
diff --git a/packages/ui/src/components/public-profile-card.tsx b/packages/ui/src/components/public-profile-card.tsx
index f0be53447..5b829a10a 100644
--- a/packages/ui/src/components/public-profile-card.tsx
+++ b/packages/ui/src/components/public-profile-card.tsx
@@ -35,10 +35,10 @@ export function PublicProfileCard({
return (
- {user.profilePhotoUrl ? (
+ {user.image ? (
// eslint-disable-next-line @next/next/no-img-element
diff --git a/packages/ui/src/components/public-shell.tsx b/packages/ui/src/components/public-shell.tsx
index bff7762a5..49dca1061 100644
--- a/packages/ui/src/components/public-shell.tsx
+++ b/packages/ui/src/components/public-shell.tsx
@@ -61,7 +61,8 @@ export type ParticipantDashboardProps = {
participantName: string;
eventName: string;
roleName?: string;
- checkedIn: boolean;
+ checkedIn?: boolean;
+ description?: string;
requireApproval?: boolean;
approved?: boolean;
onboarding?: {
@@ -309,6 +310,7 @@ export function ParticipantDashboard({
eventName,
roleName,
checkedIn,
+ description = "Use this dashboard for your event pass, schedule, RSVP, team links, settings, and day-of help.",
requireApproval,
approved,
onboarding,
@@ -319,7 +321,14 @@ export function ParticipantDashboard({
}: ParticipantDashboardProps) {
const resolvedStatusItems = [
{ label: "Role", value: roleName ?? "Participant" },
- { label: "Check-in", value: checkedIn ? "Complete" : "Not checked in" },
+ ...(checkedIn === undefined
+ ? []
+ : [
+ {
+ label: "Check-in",
+ value: checkedIn ? "Complete" : "Not checked in",
+ },
+ ]),
...(requireApproval
? [{ label: "Approval", value: approved ? "Approved" : "Pending" }]
: []),
@@ -337,8 +346,7 @@ export function ParticipantDashboard({
Welcome, {participantName}
- Use this dashboard for your event pass, schedule, RSVP,
- team links, settings, and day-of help.
+ {description}
{primaryActions.map((action) =>
diff --git a/packages/ui/src/components/ui/button.tsx b/packages/ui/src/components/ui/button.tsx
index fb60c2698..b1ad94c45 100644
--- a/packages/ui/src/components/ui/button.tsx
+++ b/packages/ui/src/components/ui/button.tsx
@@ -29,7 +29,8 @@ const buttonVariants = cva(
);
export interface ButtonProps
- extends React.ButtonHTMLAttributes
,
+ extends
+ React.ButtonHTMLAttributes,
VariantProps {
asChild?: boolean;
}
diff --git a/packages/ui/src/components/user-data-form.tsx b/packages/ui/src/components/user-data-form.tsx
index faded7271..dff20b442 100644
--- a/packages/ui/src/components/user-data-form.tsx
+++ b/packages/ui/src/components/user-data-form.tsx
@@ -97,11 +97,12 @@ function SelectField({
options: readonly { value: string; label: string }[];
error?: string;
}) {
+ const id = React.useId();
return (
- {label}
+ {label}
-
+
diff --git a/packages/ui/src/components/user-profile-settings-form.tsx b/packages/ui/src/components/user-profile-settings-form.tsx
index 5a8a9468a..9cf6c3997 100644
--- a/packages/ui/src/components/user-profile-settings-form.tsx
+++ b/packages/ui/src/components/user-profile-settings-form.tsx
@@ -38,6 +38,7 @@ type FormValues = z.input;
export type UserProfileSettingsFormProps = {
currentUser: User;
uploadProfilePhoto?: (file: File) => Promise;
+ showDiscordHandle?: boolean;
className?: string;
};
@@ -67,13 +68,14 @@ function userToFormValues(user: User | Wire): FormValues {
skillsText: skillsToText(user.skills),
isProfileSearchable: user.isProfileSearchable ?? true,
discordDisplayHandle: user.discordDisplayHandle ?? "",
- profilePhotoUrl: user.profilePhotoUrl ?? undefined,
+ image: user.image ?? undefined,
};
}
export function UserProfileSettingsForm({
currentUser,
uploadProfilePhoto,
+ showDiscordHandle = true,
className,
}: UserProfileSettingsFormProps) {
const { client, navigation } = useHackKitUI();
@@ -90,7 +92,7 @@ export function UserProfileSettingsForm({
}, [currentUser, form]);
const previewPhoto = profilePhotoFile
? URL.createObjectURL(profilePhotoFile)
- : currentUser.profilePhotoUrl;
+ : currentUser.image;
React.useEffect(() => {
if (!profilePhotoFile) return;
@@ -101,10 +103,10 @@ export function UserProfileSettingsForm({
}, [profilePhotoFile, previewPhoto]);
async function onSubmit(values: FormValues) {
- let profilePhotoUrl = values.profilePhotoUrl;
+ let image = values.image;
if (profilePhotoFile && uploadProfilePhoto) {
try {
- profilePhotoUrl = await uploadProfilePhoto(profilePhotoFile);
+ image = await uploadProfilePhoto(profilePhotoFile);
} catch (error) {
toast.error(
error instanceof Error
@@ -123,7 +125,7 @@ export function UserProfileSettingsForm({
skills: textToSkills(values.skillsText),
isProfileSearchable: values.isProfileSearchable ?? true,
discordDisplayHandle: values.discordDisplayHandle,
- profilePhotoUrl,
+ image,
};
let result;
try {
@@ -150,8 +152,9 @@ export function UserProfileSettingsForm({
Profile
- Update your public profile, HackTag, and Discord display
- handle.
+ {showDiscordHandle
+ ? "Update your public profile, HackTag, and Discord display handle."
+ : "Update your public profile and HackTag."}
@@ -222,21 +225,23 @@ export function UserProfileSettingsForm({
}
/>
-
-
- Discord display handle
-
-
-
-
+ {showDiscordHandle ? (
+
+
+ Discord display handle
+
+
+
+
+ ) : null}
diff --git a/packages/ui/src/lib/onboarding-steps.ts b/packages/ui/src/lib/onboarding-steps.ts
index 04ad967e7..6f090872f 100644
--- a/packages/ui/src/lib/onboarding-steps.ts
+++ b/packages/ui/src/lib/onboarding-steps.ts
@@ -7,10 +7,7 @@ import {
} from "../navigation";
export type CompetitorOnboardingStepId =
- | "hacktag"
- | "user-data"
- | "hacker"
- | "approval";
+ "hacktag" | "user-data" | "hacker" | "approval";
export type CompetitorOnboardingStep = {
id: CompetitorOnboardingStepId;
diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts
index 598dd697a..8410cbdfb 100644
--- a/packages/ui/src/types.ts
+++ b/packages/ui/src/types.ts
@@ -44,7 +44,7 @@ export type UserProfileFormValues = {
skills: string[];
isProfileSearchable: boolean;
discordDisplayHandle?: string;
- profilePhotoUrl?: string;
+ image?: string;
};
export type HackerRegistrationFormValues = {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6cb146045..8117b2f89 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,4 +1,171 @@
-lockfileVersion: '6.0'
+---
+lockfileVersion: '9.0'
+
+importers:
+
+ .:
+ configDependencies: {}
+ packageManagerDependencies:
+ pnpm:
+ specifier: 12.15.0
+ version: 12.15.0
+
+packages:
+
+ '@pnpm/exe.android-arm64@12.15.0':
+ resolution: {integrity: sha512-eVCqmscY70LGvgRzu3mi8IBWBFGix+a6mNZoWmXxESsBdeiKEF9xQSuaeel10yn+zI7TXy2jlI63vFLzETk+aQ==}
+ cpu: [arm64]
+ os: [android]
+
+ '@pnpm/exe.android-x64@12.15.0':
+ resolution: {integrity: sha512-Gx/WbkFcdUFUg8g8AShezcS9EiQxfYvdAm2hfKLO8sfJmJvKOCt5fzlgHWDzmGhoclibgW+tUGZ/KF4F4wOTCA==}
+ cpu: [x64]
+ os: [android]
+
+ '@pnpm/exe.darwin-arm64@12.15.0':
+ resolution: {integrity: sha512-N0ZykiDWCvqSBJvt71j7cSoBR993FqvYZFtmpCtqvW3pguiI+NAgraLPA5OTwu5mV+/d8hYpVcPktJA3xFDLtA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@pnpm/exe.darwin-x64@12.15.0':
+ resolution: {integrity: sha512-7Ntr2HlBUxzwWOg7NwDxCbRW/3vXuqKO+hcXm+w3SBi9rrHY53li1wLqWVT7Gjxd+lVEHM1QJZo6WJEGFU8C6A==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@pnpm/exe.freebsd-x64@12.15.0':
+ resolution: {integrity: sha512-btOiyL7fL7W4uQGH0aqFai2TNC3IoKcZ7gNHBVbEFZt2dWrnrD0SufL3iGs3fLlmb4OtuU35uf4Zpr9V9Jh9mA==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@pnpm/exe.linux-arm64-musl@12.15.0':
+ resolution: {integrity: sha512-pNC38k+O+90FOjbPNSnw0E7apq1PKTmz3fFe1amn+lys/U5kL++uzir8bRiho8ONcyA3d9EU7wdqcY0DKkj+JA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@pnpm/exe.linux-arm64@12.15.0':
+ resolution: {integrity: sha512-qML/8aCXslh8td/w4U+HJNqUcZ2+m6EfTbWScIzZRmyPsRFN+xB4LP1U/hymxc1iSJiKtG56HJx2fvUErWFIGw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@pnpm/exe.linux-ppc64@12.15.0':
+ resolution: {integrity: sha512-tjRDUUl7RCJ6T/6eoNPxOqkwU4Mzi5RtTXmSAxujyz37OTwwsMU7Ps087Zk4gHcUvRSeyF40ZFsew3vtE+nmUA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@pnpm/exe.linux-riscv64@12.15.0':
+ resolution: {integrity: sha512-bF1uBWEfbwaeryz6lIiaJ8AWD082otZfvzGX5l+6LZRpRwUEpJHUsJrORaYP5/cNMv5ZR2p6TvvcJcQzwtDzmw==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@pnpm/exe.linux-s390x@12.15.0':
+ resolution: {integrity: sha512-zKMhIzsexYMToeLmqV5jPsvV/f9vwsJb2kUH2NFYzalbxImeBrlA4kL7GwF8gD4pagV6jYYcJb8RjbZIdjHptg==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@pnpm/exe.linux-x64-musl@12.15.0':
+ resolution: {integrity: sha512-A9J0Jg0Rdx+qQU4qXtwyST5tto9IOu1zi4fDk35nbc6DWahggbcKtFvZPKFwL2qgUXGXOX//hXv6z/sp6emO8A==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@pnpm/exe.linux-x64@12.15.0':
+ resolution: {integrity: sha512-yc+QlZR+9+nr29J4fRzhMoapgxTBDndq/+peyoq1XUufnQFnfbXUMFudDIKzHi545linGqmOmXfn0NoufNgcOg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@pnpm/exe.win32-arm64@12.15.0':
+ resolution: {integrity: sha512-fPXZxuY1VclkOga9bc53qNCXcegfeoBR8+Ue+AospDwKzuGGSHll0oDxkLfkmpjyRqpe7bH5DyQPYp/xSMaIVA==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@pnpm/exe.win32-x64@12.15.0':
+ resolution: {integrity: sha512-nrd+Tp1We1DGj4DGG5Bea9lZNh9y1PjlLBdEwdInS4D0h0UIDtM7JaGGGDJhNzIwcHASyihWI7HLV+dtG+fhYg==}
+ cpu: [x64]
+ os: [win32]
+
+ pnpm@12.15.0:
+ resolution: {integrity: sha512-s5UdbW/0qfE9x89WzSjSuOs328ycaOUuHhGRhz6p+CoBcoerULqtxczElPA2xnwOR+sTYIwvo29HcRth6hKOYQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+snapshots:
+
+ '@pnpm/exe.android-arm64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.android-x64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.darwin-arm64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.darwin-x64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.freebsd-x64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.linux-arm64-musl@12.15.0':
+ optional: true
+
+ '@pnpm/exe.linux-arm64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.linux-ppc64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.linux-riscv64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.linux-s390x@12.15.0':
+ optional: true
+
+ '@pnpm/exe.linux-x64-musl@12.15.0':
+ optional: true
+
+ '@pnpm/exe.linux-x64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.win32-arm64@12.15.0':
+ optional: true
+
+ '@pnpm/exe.win32-x64@12.15.0':
+ optional: true
+
+ pnpm@12.15.0:
+ optionalDependencies:
+ '@pnpm/exe.android-arm64': 12.15.0
+ '@pnpm/exe.android-x64': 12.15.0
+ '@pnpm/exe.darwin-arm64': 12.15.0
+ '@pnpm/exe.darwin-x64': 12.15.0
+ '@pnpm/exe.freebsd-x64': 12.15.0
+ '@pnpm/exe.linux-arm64': 12.15.0
+ '@pnpm/exe.linux-arm64-musl': 12.15.0
+ '@pnpm/exe.linux-ppc64': 12.15.0
+ '@pnpm/exe.linux-riscv64': 12.15.0
+ '@pnpm/exe.linux-s390x': 12.15.0
+ '@pnpm/exe.linux-x64': 12.15.0
+ '@pnpm/exe.linux-x64-musl': 12.15.0
+ '@pnpm/exe.win32-arm64': 12.15.0
+ '@pnpm/exe.win32-x64': 12.15.0
+
+---
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+overrides:
+ '@libsql/kysely-libsql>@libsql/client': 0.17.4
+
+packageExtensionsChecksum: sha256-fUKBU8JkqVHLyag+QvOzgbRoRIXlBrMZC5u5GfPR3x4=
importers:
@@ -6,35 +173,29 @@ importers:
dependencies:
prettier-plugin-tailwindcss:
specifier: ^0.6.5
- version: 0.6.5(prettier@3.3.3)
+ version: 0.6.14(prettier@3.9.10)
devDependencies:
'@turbo/gen':
specifier: ^2.0.9
- version: 2.0.9(@types/node@20.14.11)(typescript@5.9.3)
+ version: 2.11.10(@types/node@20.14.11)
'@types/node':
specifier: 20.14.11
version: 20.14.11
dotenv-cli:
specifier: ^7.4.2
- version: 7.4.2
+ version: 7.4.4
eslint:
- specifier: ^9.7.0
- version: 9.7.0
+ specifier: ^10.13.0
+ version: 10.13.0(jiti@2.7.0)(supports-color@10.2.2)
prettier:
specifier: ^3.3.3
- version: 3.3.3
+ version: 3.9.10
turbo:
specifier: ^2.0.9
- version: 2.0.9
+ version: 2.11.10
- apps/web:
+ apps/demo:
dependencies:
- '@hackkit/blob-local':
- specifier: workspace:*
- version: link:../../packages/blob-local
- '@hackkit/blob-s3':
- specifier: workspace:*
- version: link:../../packages/blob-s3
'@hackkit/cli':
specifier: workspace:*
version: link:../../packages/cli
@@ -47,34 +208,25 @@ importers:
'@hackkit/next':
specifier: workspace:*
version: link:../../packages/next
- '@hackkit/plugin-discord':
- specifier: workspace:*
- version: link:../../packages/plugin-discord
- '@hackkit/plugin-notifications-email':
- specifier: workspace:*
- version: link:../../packages/plugin-notifications-email
'@hackkit/plugin-teams':
specifier: workspace:*
version: link:../../packages/plugin-teams
'@hackkit/ui':
specifier: workspace:*
version: link:../../packages/ui
+ '@libsql/client':
+ specifier: 0.17.4
+ version: 0.17.4
+ '@libsql/kysely-libsql':
+ specifier: 0.4.1
+ version: 0.4.1(kysely@0.29.6)
'@mikro-orm/core':
specifier: 7.2.1
version: 7.2.1
- '@mikro-orm/libsql':
- specifier: 7.2.1
- version: 7.2.1(@mikro-orm/core@7.2.1)
'@mikro-orm/migrations':
specifier: 7.2.1
version: 7.2.1(@mikro-orm/core@7.2.1)
- '@mikro-orm/mysql':
- specifier: 7.2.1
- version: 7.2.1(@mikro-orm/core@7.2.1)(@types/node@22.18.6)
- '@mikro-orm/postgresql':
- specifier: 7.2.1
- version: 7.2.1(@mikro-orm/core@7.2.1)
- '@mikro-orm/sqlite':
+ '@mikro-orm/sql':
specifier: 7.2.1
version: 7.2.1(@mikro-orm/core@7.2.1)
'@next/env':
@@ -82,38 +234,71 @@ importers:
version: 14.2.35
better-auth:
specifier: 1.7.6
- version: 1.7.6(next@14.2.35)(pg@8.23.0)(react-dom@18.3.1)(react@18.3.1)(vitest@3.2.4)
+ version: 1.7.6(mysql2@3.24.4(@types/node@22.18.6))(next@14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1))
jiti:
specifier: 2.4.2
version: 2.4.2
+ kysely:
+ specifier: 0.29.6
+ version: 0.29.6
next:
specifier: 14.2.35
- version: 14.2.35(react-dom@18.3.1)(react@18.3.1)
+ version: 14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
react:
- specifier: 18.3.1
- version: 18.3.1
+ specifier: 19.3.1
+ version: 19.3.1
react-dom:
- specifier: 18.3.1
- version: 18.3.1(react@18.3.1)
+ specifier: 19.3.1
+ version: 19.3.1(react@19.3.1)
+ react-server-dom-webpack:
+ specifier: 19.3.1
+ version: 19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6)))
sonner:
specifier: ^1.5.0
- version: 1.5.0(react-dom@18.3.1)(react@18.3.1)
+ version: 1.7.4(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
typescript:
specifier: 5.9.3
version: 5.9.3
+ vinext:
+ specifier: 1.2.1
+ version: 1.2.1(@types/node@22.18.6)(@vitejs/plugin-react@6.0.1(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)))(@vitejs/plugin-rsc@0.5.38(react-dom@19.3.1(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))))(react@19.3.1)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)))(next@14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))))(react@19.3.1)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))
+ zod:
+ specifier: ^3.25.67
+ version: 3.25.76
devDependencies:
+ '@cloudflare/vite-plugin':
+ specifier: 1.64.0
+ version: 1.64.0(@types/node@22.18.6)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))(wrangler@4.151.3(@cloudflare/workers-types@5.20261019.1)(@types/node@22.18.6))
+ '@cloudflare/workers-types':
+ specifier: 5.20261019.1
+ version: 5.20261019.1
+ '@mikro-orm/cli':
+ specifier: 7.2.1
+ version: 7.2.1
+ '@playwright/test':
+ specifier: 1.64.1
+ version: 1.64.1
'@types/node':
specifier: 22.18.6
version: 22.18.6
'@types/react':
- specifier: 18.3.3
- version: 18.3.3
+ specifier: 19.3.0
+ version: 19.3.0
'@types/react-dom':
- specifier: 18.3.0
- version: 18.3.0
+ specifier: 19.3.0
+ version: 19.3.0(@types/react@19.3.0)
+ '@vitejs/plugin-react':
+ specifier: 6.0.1
+ version: 6.0.1(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))
+ '@vitejs/plugin-rsc':
+ specifier: 0.5.38
+ version: 0.5.38(react-dom@19.3.1(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))))(react@19.3.1)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))
autoprefixer:
specifier: 10.4.19
version: 10.4.19(postcss@8.4.39)
+ dotenv:
+ specifier: 16.6.1
+ version: 16.6.1
postcss:
specifier: 8.4.39
version: 8.4.39
@@ -123,9 +308,127 @@ importers:
tailwindcss-animate:
specifier: 1.0.7
version: 1.0.7(tailwindcss@3.4.6)
+ vite:
+ specifier: 8.3.4
+ version: 8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)
+ wrangler:
+ specifier: 4.151.3
+ version: 4.151.3(@cloudflare/workers-types@5.20261019.1)(@types/node@22.18.6)
+
+ apps/docs:
+ dependencies:
+ cn:
+ specifier: ^0.5.0
+ version: 0.5.0
+ fumadocs-core:
+ specifier: 16.17.7
+ version: 16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7)
+ fumadocs-mdx:
+ specifier: 15.4.9
+ version: 15.4.9(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.3.0)(fumadocs-core@16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react@19.3.1)(rolldown@1.2.15)(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))
+ fumadocs-ui:
+ specifier: npm:@fumadocs/base-ui@16.17.7
+ version: '@fumadocs/base-ui@16.17.7(@types/mdx@2.0.14)(@types/react@19.3.0)(fumadocs-core@16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(tailwindcss@4.3.3)'
+ lucide-react:
+ specifier: ^1.59.0
+ version: 1.61.0(@types/react@19.3.0)(react@19.3.1)
+ next:
+ specifier: 16.4.2
+ version: 16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ react:
+ specifier: ^19.3.1
+ version: 19.3.1
+ react-dom:
+ specifier: ^19.3.1
+ version: 19.3.1(react@19.3.1)
+ devDependencies:
+ '@tailwindcss/postcss':
+ specifier: ^4.3.3
+ version: 4.3.3
+ '@types/mdx':
+ specifier: ^2.0.14
+ version: 2.0.14
+ '@types/node':
+ specifier: ^26.6.5
+ version: 26.6.5
+ '@types/react':
+ specifier: ^19.3.0
+ version: 19.3.0
+ '@types/react-dom':
+ specifier: ^19.3.0
+ version: 19.3.0(@types/react@19.3.0)
+ postcss:
+ specifier: ^8.5.31
+ version: 8.5.32
+ serve:
+ specifier: ^14.2.6
+ version: 14.2.6(supports-color@10.2.2)
+ tailwindcss:
+ specifier: ^4.3.3
+ version: 4.3.3
+ typescript:
+ specifier: ^7.0.2
+ version: 7.0.2
+ wrangler:
+ specifier: 4.151.3
+ version: 4.151.3(@cloudflare/workers-types@5.20261019.1)(@types/node@26.6.5)
+
+ e2e:
+ devDependencies:
+ '@hackkit/cli':
+ specifier: workspace:*
+ version: link:../packages/cli
+ '@hackkit/config':
+ specifier: workspace:*
+ version: link:../packages/config
+ '@hackkit/core':
+ specifier: workspace:*
+ version: link:../packages/core
+ '@hackkit/plugin-discord':
+ specifier: workspace:*
+ version: link:../packages/plugin-discord
+ '@hackkit/plugin-notifications-email':
+ specifier: workspace:*
+ version: link:../packages/plugin-notifications-email
+ '@hackkit/plugin-teams':
+ specifier: workspace:*
+ version: link:../packages/plugin-teams
+ '@mikro-orm/core':
+ specifier: 7.2.1
+ version: 7.2.1
+ '@mikro-orm/libsql':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/migrations':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/mysql':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)(@types/node@22.18.6)
+ '@mikro-orm/postgresql':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/sqlite':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@playwright/test':
+ specifier: 1.64.1
+ version: 1.64.1
+ '@types/node':
+ specifier: 22.18.6
+ version: 22.18.6
+ esbuild:
+ specifier: 0.25.12
+ version: 0.25.12
+ jiti:
+ specifier: 2.4.2
+ version: 2.4.2
+ typescript:
+ specifier: 5.9.3
+ version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/blob-local:
dependencies:
@@ -138,7 +441,7 @@ importers:
version: 22.18.6
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
@@ -147,10 +450,10 @@ importers:
dependencies:
'@aws-sdk/client-s3':
specifier: ^3.744.0
- version: 3.744.0
+ version: 3.1157.0
'@aws-sdk/s3-request-presigner':
specifier: ^3.744.0
- version: 3.744.0
+ version: 3.1157.0
'@hackkit/core':
specifier: workspace:*
version: link:../core
@@ -160,7 +463,7 @@ importers:
version: 22.18.6
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
@@ -197,13 +500,13 @@ importers:
version: 22.18.6
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.4.2)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/config:
dependencies:
@@ -222,19 +525,19 @@ importers:
version: 22.18.6
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.4.2)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/core:
dependencies:
'@a77ay/better-auth-mikro-orm':
specifier: 0.1.1
- version: 0.1.1(@mikro-orm/core@7.2.1)(better-auth@1.7.6)
+ version: 0.1.1(@mikro-orm/core@7.2.1)(better-auth@1.7.6(mysql2@3.24.4(@types/node@20.14.11))(next@16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)))
'@better-fetch/fetch':
specifier: 1.3.2
version: 1.3.2
@@ -249,32 +552,35 @@ importers:
version: 7.2.1(@mikro-orm/core@7.2.1)
'@mikro-orm/mysql':
specifier: 7.2.1
- version: 7.2.1(@mikro-orm/core@7.2.1)(@types/node@22.18.6)
+ version: 7.2.1(@mikro-orm/core@7.2.1)(@types/node@20.14.11)
'@mikro-orm/postgresql':
specifier: 7.2.1
version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/sql':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
'@mikro-orm/sqlite':
specifier: 7.2.1
version: 7.2.1(@mikro-orm/core@7.2.1)
better-auth:
specifier: 1.7.6
- version: 1.7.6(next@14.2.35)(pg@8.23.0)(react-dom@18.3.1)(react@18.3.1)(vitest@3.2.4)
+ version: 1.7.6(mysql2@3.24.4(@types/node@20.14.11))(next@16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1))
better-call:
specifier: 1.4.0
- version: 1.4.0(zod@3.25.67)
+ version: 1.4.0(zod@3.25.76)
zod:
specifier: ^3.25.67
- version: 3.25.67
+ version: 3.25.76
devDependencies:
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/next:
dependencies:
@@ -286,10 +592,10 @@ importers:
version: link:../core
better-auth:
specifier: 1.7.6
- version: 1.7.6(next@14.2.35)(pg@8.23.0)(react-dom@18.3.1)(react@18.3.1)(vitest@3.2.4)
+ version: 1.7.6(mysql2@3.24.4(@types/node@22.18.6))(next@14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@18.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1))
react:
specifier: '>=18'
- version: 18.3.1
+ version: 19.3.1
devDependencies:
'@types/node':
specifier: 22.18.6
@@ -299,16 +605,16 @@ importers:
version: 18.3.3
next:
specifier: 14.2.35
- version: 14.2.35(react-dom@18.3.1)(react@18.3.1)
+ version: 14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@19.3.1))(react@19.3.1)
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/plugin-discord:
dependencies:
@@ -326,22 +632,22 @@ importers:
version: 7.2.1
better-call:
specifier: 1.4.0
- version: 1.4.0(zod@3.25.67)
+ version: 1.4.0(zod@3.25.76)
next:
specifier: '>=14'
- version: 14.2.35(react-dom@18.3.1)(react@18.3.1)
+ version: 16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
react:
specifier: '>=18'
- version: 18.3.1
+ version: 19.3.1
react-dom:
specifier: '>=18'
- version: 18.3.1(react@18.3.1)
+ version: 19.3.1(react@19.3.1)
sonner:
specifier: ^1.5.0
- version: 1.5.0(react-dom@18.3.1)(react@18.3.1)
+ version: 1.7.4(@types/react@18.3.3)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
zod:
specifier: ^3.25.67
- version: 3.25.67
+ version: 3.25.76
devDependencies:
'@types/react':
specifier: 18.3.3
@@ -351,13 +657,13 @@ importers:
version: 18.3.0
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/plugin-notifications-email:
dependencies:
@@ -370,13 +676,13 @@ importers:
version: 22.18.6
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/plugin-teams:
dependencies:
@@ -394,22 +700,13 @@ importers:
version: 7.2.1
better-call:
specifier: 1.4.0
- version: 1.4.0(zod@3.25.67)
- next:
- specifier: '>=14'
- version: 14.2.35(react-dom@18.3.1)(react@18.3.1)
- react:
- specifier: '>=18'
- version: 18.3.1
- react-dom:
- specifier: '>=18'
- version: 18.3.1(react@18.3.1)
+ version: 1.4.0(zod@3.25.76)
sonner:
specifier: ^1.5.0
- version: 1.5.0(react-dom@18.3.1)(react@18.3.1)
+ version: 1.7.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
zod:
specifier: ^3.25.67
- version: 3.25.67
+ version: 3.25.76
devDependencies:
'@types/react':
specifier: 18.3.3
@@ -417,15 +714,24 @@ importers:
'@types/react-dom':
specifier: 18.3.0
version: 18.3.0
+ next:
+ specifier: 14.2.35
+ version: 14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react:
+ specifier: 18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: 18.3.1
+ version: 18.3.1(react@18.3.1)
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ version: 3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
packages/tsconfig: {}
@@ -436,52 +742,43 @@ importers:
version: link:../core
'@hookform/resolvers':
specifier: ^3.9.0
- version: 3.9.0(react-hook-form@7.52.1)
+ version: 3.10.0(react-hook-form@7.52.1(react@18.3.1))
'@radix-ui/react-checkbox':
specifier: ^1.0.4
- version: 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ version: 1.4.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-label':
specifier: ^2.0.2
- version: 2.0.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ version: 2.1.17(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-select':
specifier: ^1.2.2
- version: 1.2.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ version: 1.2.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-slot':
specifier: ^1.0.2
- version: 1.0.2(@types/react@18.3.3)(react@18.3.1)
+ version: 1.5.0(@types/react@18.3.3)(react@18.3.1)
'@yudiel/react-qr-scanner':
specifier: ^2.1.0
- version: 2.1.0(react-dom@18.3.1)(react@18.3.1)
+ version: 2.6.0(@types/emscripten@1.41.6)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
class-variance-authority:
specifier: ^0.7.0
- version: 0.7.0
+ version: 0.7.1
clsx:
specifier: ^2.1.1
version: 2.1.1
- next:
- specifier: '>=14'
- version: 14.2.35(react-dom@18.3.1)(react@18.3.1)
qrcode.react:
specifier: ^4.2.0
- version: 4.2.0(react@18.3.1)
- react:
- specifier: '>=18'
- version: 18.3.1
- react-dom:
- specifier: '>=18'
- version: 18.3.1(react@18.3.1)
+ version: 4.2.0(@types/react@18.3.3)(react@18.3.1)
react-hook-form:
specifier: 7.52.1
version: 7.52.1(react@18.3.1)
sonner:
specifier: ^1.5.0
- version: 1.5.0(react-dom@18.3.1)(react@18.3.1)
+ version: 1.7.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
tailwind-merge:
specifier: ^2.4.0
- version: 2.4.0
+ version: 2.6.1
zod:
specifier: ^3.25.67
- version: 3.25.67
+ version: 3.25.76
devDependencies:
'@types/react':
specifier: 18.3.3
@@ -489,1461 +786,6942 @@ importers:
'@types/react-dom':
specifier: 18.3.0
version: 18.3.0
+ next:
+ specifier: 14.2.35
+ version: 14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react:
+ specifier: 18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: 18.3.1
+ version: 18.3.1(react@18.3.1)
tsup:
specifier: ^8.5.1
- version: 8.5.1(jiti@2.4.2)(typescript@5.9.3)
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1)
typescript:
specifier: 5.9.3
version: 5.9.3
-packages:
-
- /@a77ay/better-auth-mikro-orm@0.1.1(@mikro-orm/core@7.2.1)(better-auth@1.7.6):
- resolution: {integrity: sha512-WT0EwaIwG6TI0crFDD5bzF823p2o4qMVgSCDFqqzw2pdWSA0TzSVTL8GGjUxNTiPFgOVjFc/GLQnKSYVjnQaPg==}
- hasBin: true
- peerDependencies:
- '@mikro-orm/core': ^7.0.0
- better-auth: ^1.0.0
- dependencies:
- '@mikro-orm/core': 7.2.1
- better-auth: 1.7.6(next@14.2.35)(pg@8.23.0)(react-dom@18.3.1)(react@18.3.1)(vitest@3.2.4)
- jiti: 2.7.0
- dev: false
-
- /@alloc/quick-lru@5.2.0:
- resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
- engines: {node: '>=10'}
- dev: true
-
- /@aws-crypto/crc32@5.2.0:
- resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==}
- engines: {node: '>=16.0.0'}
- dependencies:
- '@aws-crypto/util': 5.2.0
- '@aws-sdk/types': 3.734.0
- tslib: 2.8.1
- dev: false
-
- /@aws-crypto/crc32c@5.2.0:
- resolution: {integrity: sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==}
- dependencies:
- '@aws-crypto/util': 5.2.0
- '@aws-sdk/types': 3.734.0
- tslib: 2.8.1
- dev: false
-
- /@aws-crypto/sha1-browser@5.2.0:
- resolution: {integrity: sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==}
- dependencies:
- '@aws-crypto/supports-web-crypto': 5.2.0
- '@aws-crypto/util': 5.2.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-locate-window': 3.965.8
- '@smithy/util-utf8': 2.3.0
- tslib: 2.8.1
- dev: false
-
- /@aws-crypto/sha256-browser@5.2.0:
- resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==}
- dependencies:
- '@aws-crypto/sha256-js': 5.2.0
- '@aws-crypto/supports-web-crypto': 5.2.0
- '@aws-crypto/util': 5.2.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-locate-window': 3.965.8
- '@smithy/util-utf8': 2.3.0
- tslib: 2.8.1
- dev: false
-
- /@aws-crypto/sha256-js@5.2.0:
- resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==}
- engines: {node: '>=16.0.0'}
- dependencies:
- '@aws-crypto/util': 5.2.0
- '@aws-sdk/types': 3.734.0
- tslib: 2.8.1
- dev: false
-
- /@aws-crypto/supports-web-crypto@5.2.0:
- resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==}
- dependencies:
- tslib: 2.8.1
- dev: false
-
- /@aws-crypto/util@5.2.0:
- resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/util-utf8': 2.3.0
- tslib: 2.8.1
- dev: false
-
- /@aws-sdk/client-s3@3.744.0:
- resolution: {integrity: sha512-UuiqxVI5FKlnNcWoDP8bsyJcMJa7XjGcCbVCfKSpSboNeBM4tQS3ZIViSYuz+BeO8/MuwCy7hKn7+Zjivit1nA==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-crypto/sha1-browser': 5.2.0
- '@aws-crypto/sha256-browser': 5.2.0
- '@aws-crypto/sha256-js': 5.2.0
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/credential-provider-node': 3.744.0
- '@aws-sdk/middleware-bucket-endpoint': 3.734.0
- '@aws-sdk/middleware-expect-continue': 3.734.0
- '@aws-sdk/middleware-flexible-checksums': 3.744.0
- '@aws-sdk/middleware-host-header': 3.734.0
- '@aws-sdk/middleware-location-constraint': 3.734.0
- '@aws-sdk/middleware-logger': 3.734.0
- '@aws-sdk/middleware-recursion-detection': 3.734.0
- '@aws-sdk/middleware-sdk-s3': 3.744.0
- '@aws-sdk/middleware-ssec': 3.734.0
- '@aws-sdk/middleware-user-agent': 3.744.0
- '@aws-sdk/region-config-resolver': 3.734.0
- '@aws-sdk/signature-v4-multi-region': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-endpoints': 3.743.0
- '@aws-sdk/util-user-agent-browser': 3.734.0
- '@aws-sdk/util-user-agent-node': 3.744.0
- '@aws-sdk/xml-builder': 3.734.0
- '@smithy/config-resolver': 4.6.8
- '@smithy/core': 3.29.3
- '@smithy/eventstream-serde-browser': 4.4.8
- '@smithy/eventstream-serde-config-resolver': 4.5.8
- '@smithy/eventstream-serde-node': 4.4.8
- '@smithy/fetch-http-handler': 5.6.5
- '@smithy/hash-blob-browser': 4.4.8
- '@smithy/hash-node': 4.4.8
- '@smithy/hash-stream-node': 4.4.8
- '@smithy/invalid-dependency': 4.4.8
- '@smithy/md5-js': 4.4.8
- '@smithy/middleware-content-length': 4.4.8
- '@smithy/middleware-endpoint': 4.6.8
- '@smithy/middleware-retry': 4.7.8
- '@smithy/middleware-serde': 4.4.8
- '@smithy/middleware-stack': 4.4.8
- '@smithy/node-config-provider': 4.5.8
- '@smithy/node-http-handler': 4.9.5
- '@smithy/protocol-http': 5.5.8
- '@smithy/smithy-client': 4.14.8
- '@smithy/types': 4.16.1
- '@smithy/url-parser': 4.4.8
- '@smithy/util-base64': 4.5.8
- '@smithy/util-body-length-browser': 4.4.8
- '@smithy/util-body-length-node': 4.4.8
- '@smithy/util-defaults-mode-browser': 4.5.8
- '@smithy/util-defaults-mode-node': 4.4.8
- '@smithy/util-endpoints': 3.6.8
- '@smithy/util-middleware': 4.4.8
- '@smithy/util-retry': 4.5.8
- '@smithy/util-stream': 4.7.8
- '@smithy/util-utf8': 4.4.8
- '@smithy/util-waiter': 4.5.8
- tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
-
- /@aws-sdk/client-sso@3.744.0:
- resolution: {integrity: sha512-mzJxPQ9mcnNY50pi7+pxB34/Dt7PUn0OgkashHdJPTnavoriLWvPcaQCG1NEVAtyzxNdowhpi4KjC+aN1EwAeA==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-crypto/sha256-browser': 5.2.0
- '@aws-crypto/sha256-js': 5.2.0
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/middleware-host-header': 3.734.0
- '@aws-sdk/middleware-logger': 3.734.0
- '@aws-sdk/middleware-recursion-detection': 3.734.0
- '@aws-sdk/middleware-user-agent': 3.744.0
- '@aws-sdk/region-config-resolver': 3.734.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-endpoints': 3.743.0
- '@aws-sdk/util-user-agent-browser': 3.734.0
- '@aws-sdk/util-user-agent-node': 3.744.0
- '@smithy/config-resolver': 4.6.8
- '@smithy/core': 3.29.3
- '@smithy/fetch-http-handler': 5.6.5
- '@smithy/hash-node': 4.4.8
- '@smithy/invalid-dependency': 4.4.8
- '@smithy/middleware-content-length': 4.4.8
- '@smithy/middleware-endpoint': 4.6.8
- '@smithy/middleware-retry': 4.7.8
- '@smithy/middleware-serde': 4.4.8
- '@smithy/middleware-stack': 4.4.8
- '@smithy/node-config-provider': 4.5.8
- '@smithy/node-http-handler': 4.9.5
- '@smithy/protocol-http': 5.5.8
- '@smithy/smithy-client': 4.14.8
- '@smithy/types': 4.16.1
- '@smithy/url-parser': 4.4.8
- '@smithy/util-base64': 4.5.8
- '@smithy/util-body-length-browser': 4.4.8
- '@smithy/util-body-length-node': 4.4.8
- '@smithy/util-defaults-mode-browser': 4.5.8
- '@smithy/util-defaults-mode-node': 4.4.8
- '@smithy/util-endpoints': 3.6.8
- '@smithy/util-middleware': 4.4.8
- '@smithy/util-retry': 4.5.8
- '@smithy/util-utf8': 4.4.8
- tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
-
- /@aws-sdk/core@3.744.0:
- resolution: {integrity: sha512-R0XLfDDq7MAXYyDf7tPb+m0R7gmzTRRDtPNQ5jvuq8dbkefph5gFMkxZ2zSx7dfTsfYHhBPuTBsQ0c5Xjal3Vg==}
- engines: {node: '>=18.0.0'}
+ templates/nextjs-full:
dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/core': 3.29.3
- '@smithy/node-config-provider': 4.5.8
- '@smithy/property-provider': 4.4.8
- '@smithy/protocol-http': 5.5.8
- '@smithy/signature-v4': 5.6.4
- '@smithy/smithy-client': 4.14.8
- '@smithy/types': 4.16.1
- '@smithy/util-middleware': 4.4.8
- fast-xml-parser: 4.4.1
+ '@hackkit/blob-local':
+ specifier: workspace:*
+ version: link:../../packages/blob-local
+ '@hackkit/blob-s3':
+ specifier: workspace:*
+ version: link:../../packages/blob-s3
+ '@hackkit/cli':
+ specifier: workspace:*
+ version: link:../../packages/cli
+ '@hackkit/config':
+ specifier: workspace:*
+ version: link:../../packages/config
+ '@hackkit/core':
+ specifier: workspace:*
+ version: link:../../packages/core
+ '@hackkit/next':
+ specifier: workspace:*
+ version: link:../../packages/next
+ '@hackkit/plugin-discord':
+ specifier: workspace:*
+ version: link:../../packages/plugin-discord
+ '@hackkit/plugin-notifications-email':
+ specifier: workspace:*
+ version: link:../../packages/plugin-notifications-email
+ '@hackkit/plugin-teams':
+ specifier: workspace:*
+ version: link:../../packages/plugin-teams
+ '@hackkit/ui':
+ specifier: workspace:*
+ version: link:../../packages/ui
+ '@mikro-orm/core':
+ specifier: 7.2.1
+ version: 7.2.1
+ '@mikro-orm/libsql':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/migrations':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/mysql':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)(@types/node@22.18.6)
+ '@mikro-orm/postgresql':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/sqlite':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@next/env':
+ specifier: 14.2.35
+ version: 14.2.35
+ better-auth:
+ specifier: 1.7.6
+ version: 1.7.6(mysql2@3.24.4(@types/node@22.18.6))(next@14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(pg@8.23.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1))
+ jiti:
+ specifier: 2.4.2
+ version: 2.4.2
+ next:
+ specifier: 14.2.35
+ version: 14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react:
+ specifier: 18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: 18.3.1
+ version: 18.3.1(react@18.3.1)
+ sonner:
+ specifier: ^1.5.0
+ version: 1.7.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ typescript:
+ specifier: 5.9.3
+ version: 5.9.3
+ devDependencies:
+ '@types/node':
+ specifier: 22.18.6
+ version: 22.18.6
+ '@types/react':
+ specifier: 18.3.3
+ version: 18.3.3
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
+ autoprefixer:
+ specifier: 10.4.19
+ version: 10.4.19(postcss@8.4.39)
+ postcss:
+ specifier: 8.4.39
+ version: 8.4.39
+ tailwindcss:
+ specifier: 3.4.6
+ version: 3.4.6
+ tailwindcss-animate:
+ specifier: 1.0.7
+ version: 1.0.7(tailwindcss@3.4.6)
+
+ templates/nextjs-minimal:
+ dependencies:
+ '@hackkit/blob-local':
+ specifier: workspace:*
+ version: link:../../packages/blob-local
+ '@hackkit/cli':
+ specifier: workspace:*
+ version: link:../../packages/cli
+ '@hackkit/config':
+ specifier: workspace:*
+ version: link:../../packages/config
+ '@hackkit/core':
+ specifier: workspace:*
+ version: link:../../packages/core
+ '@hackkit/next':
+ specifier: workspace:*
+ version: link:../../packages/next
+ '@hackkit/ui':
+ specifier: workspace:*
+ version: link:../../packages/ui
+ '@mikro-orm/core':
+ specifier: 7.2.1
+ version: 7.2.1
+ '@mikro-orm/migrations':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@mikro-orm/sqlite':
+ specifier: 7.2.1
+ version: 7.2.1(@mikro-orm/core@7.2.1)
+ '@next/env':
+ specifier: 14.2.35
+ version: 14.2.35
+ better-auth:
+ specifier: 1.7.6
+ version: 1.7.6(mysql2@3.24.4(@types/node@22.18.6))(next@14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(pg@8.23.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1))
+ jiti:
+ specifier: 2.4.2
+ version: 2.4.2
+ next:
+ specifier: 14.2.35
+ version: 14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react:
+ specifier: 18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: 18.3.1
+ version: 18.3.1(react@18.3.1)
+ sonner:
+ specifier: ^1.5.0
+ version: 1.7.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ typescript:
+ specifier: 5.9.3
+ version: 5.9.3
+ devDependencies:
+ '@types/node':
+ specifier: 22.18.6
+ version: 22.18.6
+ '@types/react':
+ specifier: 18.3.3
+ version: 18.3.3
+ '@types/react-dom':
+ specifier: 18.3.0
+ version: 18.3.0
+ autoprefixer:
+ specifier: 10.4.19
+ version: 10.4.19(postcss@8.4.39)
+ postcss:
+ specifier: 8.4.39
+ version: 8.4.39
+ tailwindcss:
+ specifier: 3.4.6
+ version: 3.4.6
+ tailwindcss-animate:
+ specifier: 1.0.7
+ version: 1.0.7(tailwindcss@3.4.6)
+
+packages:
+
+ '@a77ay/better-auth-mikro-orm@0.1.1':
+ resolution: {integrity: sha512-WT0EwaIwG6TI0crFDD5bzF823p2o4qMVgSCDFqqzw2pdWSA0TzSVTL8GGjUxNTiPFgOVjFc/GLQnKSYVjnQaPg==}
+ hasBin: true
+ peerDependencies:
+ '@mikro-orm/core': ^7.0.0
+ better-auth: ^1.0.0
+
+ '@alloc/quick-lru@5.3.0':
+ resolution: {integrity: sha512-U4+70Pc5ZS9osnCBCE5Jha/ciHM+Yp+CNMNC/7HvYbNRk1Ldd+f7qO65W5qfhu/TCv+/ozljlXXe9Nj8419DMA==}
+ engines: {node: '>=10'}
+
+ '@aws-sdk/checksums@3.1001.6':
+ resolution: {integrity: sha512-DSo+EqLq2PkS8gjit311LliRrYzydneP6vRhxMzDh9c8P3wWGzHf4fjmQN3d8sl4qh+aMqzn9+o+gZZo4+uqIQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/client-s3@3.1157.0':
+ resolution: {integrity: sha512-fbZIxqZVzK/PMLj9az3+ieAcYdZhzpTrfIVAnrE4PnRc1C6SokMDnaxAJycKTNmzLlY1fvmlItZWBDPUEFlGLQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/core@3.978.6':
+ resolution: {integrity: sha512-ykF/MiYoM15dgZwF/WLgjJXVbAK2wU6vjPigeEnOHwyUJ0rdlraO5uekecKNVPkvOnz+oju/5zljViQs1nI1FQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-env@3.972.77':
+ resolution: {integrity: sha512-CN6dQCDo32a8n2gvm2HBeqGV5BNI9noG96nTj5bGO2HWtt0Rucu/A8pcnJIqkzILOHSuilnCk0Do8/7h6SOXhQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-http@3.972.79':
+ resolution: {integrity: sha512-Netsu0nnmvP2HiN1ZFQBeUu+JehQIuubqz+j2kHDgeSE4HDzniCpIZ7RzoWABq+LTcbCi9W03hywifUagoVIWQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-ini@3.973.22':
+ resolution: {integrity: sha512-x7/5h58cqOoZR0RWUZC7v/cJOADQR42iSIQkvU+00HVHR4jh8ZpqEgRPGf2zei59iH5qP40lL3bkq49PuWl71g==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-login@3.972.84':
+ resolution: {integrity: sha512-G9Ty1uIV0laEvEp2KiMbEhsuBAjgaD3KYrwVjAM5VUxpcIuPBqQI5riA7/qzrnSgYiAKQbubbgkwcqCICKCIxg==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-node@3.972.89':
+ resolution: {integrity: sha512-O8xj7/sanrnXfFHu/LUujVBiiwn5mknYenU7xt1w6+yvhR1QoDZWXLFh1gLITaFVPtb1jWgEirC+kFNw+//tyw==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-process@3.972.77':
+ resolution: {integrity: sha512-sWA8Jm+ASzkTxoqLizHWRbt8Gj3yZCmZ0hYdvg0uIxuLzWseYcfrDFzaSnkRWlEWSJV38rAWFimdrN0J4NR7Pg==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-sso@3.973.21':
+ resolution: {integrity: sha512-KV2LM8fbYUhDzGEBnPwb+ISNfNlhmnpLS+y6A6VsJpg1EI9aUJ0+dRTxh2GrGdneFH0T4TiuboHxz8i6+M38JA==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-web-identity@3.972.83':
+ resolution: {integrity: sha512-iekYilmo2Re51fC7gMkEfZ7jFDXwehSCmXjDESaYQsdgYhsLQFG7rTYr3GBvRIyj+Fkda2NxbZX7hAZDaFD0JQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/middleware-sdk-s3@3.972.82':
+ resolution: {integrity: sha512-MTW3FIYs3yFuSuBKCrm3nWLWzHyz454SPxKQjhY2pcpV4ijKBXselC7wh9VdDstVKJn5ESWx5s1OGvB+p6XUzA==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/nested-clients@3.997.51':
+ resolution: {integrity: sha512-DJK4iGIHWU8Jh8ODMvqFYcX9yGBMXV4tSZAvqlHF5EDd8hbmF3eFO9KIWOnA7wcQjPzEkyMMW1/FgZ9RU8oimQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/s3-request-presigner@3.1157.0':
+ resolution: {integrity: sha512-zHdXg1UuA4Z2ICQeGCBfSL5A+0TbFCkS6uq4WoX74jpv3PozoPsaDswu2OBU6cIUJLg6JWUZd226SLM/MGHAKA==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/signature-v4-multi-region@3.996.49':
+ resolution: {integrity: sha512-nvuAZNRrRRVCiARRKsYlQ0VnXiEQiq7vXPH+UA+LSo+kN3Djl9eo/V2r0udkw85PnsNshmv2Em1clld5M3j67w==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/token-providers@3.1157.0':
+ resolution: {integrity: sha512-AeAzcwWRP2uANO2TjFpKjRdvOCzgfIu6YQl9Ceibd6E0gnq5dfOzujFnq2aeqgbLg4wRtXbUZE4gekCCPrz/OQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/types@3.975.0':
+ resolution: {integrity: sha512-WQlhs6juByzWOzj5fwxOx0mPJaEqMcG/sDpl3Id61B3XhKE63xY+0QWcnG+sWR/sCfprmreyUo1lM7IKZmHMzw==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/xml-builder@3.972.41':
+ resolution: {integrity: sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws/lambda-invoke-store@0.3.0':
+ resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==}
+ engines: {node: '>=18.0.0'}
+
+ '@babel/runtime@7.29.10':
+ resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/runtime@8.0.8':
+ resolution: {integrity: sha512-dEu8nGlRqjsJsvviUUoSMfcRHpwomCiRlXsc2mPfJ79+ffTpDm+JtfUtTMzUrqCApHQnCsVPD3gT1ZT8RgBRCQ==}
+
+ '@base-ui/react@1.9.0':
+ resolution: {integrity: sha512-S8CSYosASBKtpL8SWUfS78rFElfLijiCgA7oHOK22jCJ95FULsYyKwBNFOgudt0RA+/7yNc7F81bOvQnRgbBiQ==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ '@date-fns/tz': ^1.2.0
+ '@types/react': ^17 || ^18 || ^19
+ date-fns: ^4.0.0
+ react: ^17 || ^18 || ^19
+ react-dom: ^17 || ^18 || ^19
+ peerDependenciesMeta:
+ '@date-fns/tz':
+ optional: true
+ '@types/react':
+ optional: true
+ date-fns:
+ optional: true
+
+ '@base-ui/utils@0.5.0':
+ resolution: {integrity: sha512-dYGGcEttjkYiMoa5nHm8vLaJ2UcuTWxo3BFAwOYXeRg/q7UVVvA6cacEIXEs3FgBfK1CGtW1ptElqs7wsx+t9A==}
+ peerDependencies:
+ '@types/react': ^17 || ^18 || ^19
+ react: ^17 || ^18 || ^19
+ react-dom: ^17 || ^18 || ^19
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@better-auth/core@1.7.6':
+ resolution: {integrity: sha512-yBDDO0J4VCHT1qEZtzj6aMexX4etyLesitoxehcWHzPrzYqrFHwe/hgskye+imlGhQVOysuljMg8M8BA6GrtIg==}
+ peerDependencies:
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+ '@opentelemetry/api': ^1.9.0
+ better-call: 1.4.0
+ jose: ^6.1.0
+ kysely: ^0.28.5 || ^0.29.0
+ nanostores: ^1.0.1
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+
+ '@better-auth/drizzle-adapter@1.7.6':
+ resolution: {integrity: sha512-ENlhwC7kkTjquuiel3Efggik0hC4vtD7ppJ8FhsiHhRJA8K6RT4hbhzkfm6keNvjdnAeWwCejm7FmMO4GoSGpA==}
+ peerDependencies:
+ '@better-auth/core': ^1.7.6
+ '@better-auth/utils': 0.4.2
+ drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
+ peerDependenciesMeta:
+ drizzle-orm:
+ optional: true
+
+ '@better-auth/kysely-adapter@1.7.6':
+ resolution: {integrity: sha512-BV+DX2/z/6ozNC9DYSge78wjLerq6Bxd/lSPjzzuq9eEutkQDAJTuiaETzgGYqNV5LlEWi8TZFAQTEq/wavOEQ==}
+ peerDependencies:
+ '@better-auth/core': ^1.7.6
+ '@better-auth/utils': 0.4.2
+ kysely: ^0.28.17 || ^0.29.0
+ peerDependenciesMeta:
+ kysely:
+ optional: true
+
+ '@better-auth/memory-adapter@1.7.6':
+ resolution: {integrity: sha512-ng1xv8k2JsEIjnqzJzdoVOQrnoCLRuk4EiQL9yYAThyg6zYzV00LynlhH+O9OMUZ+yGVpGqGZmr5xcTiUSV2uA==}
+ peerDependencies:
+ '@better-auth/core': ^1.7.6
+ '@better-auth/utils': 0.4.2
+
+ '@better-auth/mongo-adapter@1.7.6':
+ resolution: {integrity: sha512-GvBwZli8i4XINMAj9tlW7eV9E8Dr+JWqavXjUs2o81GZt/Vh8wiX+31KK1jQ4iOuejfjpLoXcoFtlIPgf/pVog==}
+ peerDependencies:
+ '@better-auth/core': ^1.7.6
+ '@better-auth/utils': 0.4.2
+ mongodb: ^6.0.0 || ^7.0.0
+ peerDependenciesMeta:
+ mongodb:
+ optional: true
+
+ '@better-auth/prisma-adapter@1.7.6':
+ resolution: {integrity: sha512-31rz2OXIx2Q1L4Jhd5F71dafIWqder/Bo6vJ+eCgO5iZ0gvnv7fUmM95DvbVUoPC69XYpcIM/6PJmQ3M6RydWg==}
+ peerDependencies:
+ '@better-auth/core': ^1.7.6
+ '@better-auth/utils': 0.4.2
+ '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
+ prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
+ peerDependenciesMeta:
+ '@prisma/client':
+ optional: true
+ prisma:
+ optional: true
+
+ '@better-auth/telemetry@1.7.6':
+ resolution: {integrity: sha512-xgRwPja2wTJtcu+OQZR2IiNpAmviddnW3n5Do5umXRugJFW3v9KlSmYjYm580mVsPnU4upvZkvSRl9v8DgSDtA==}
+ peerDependencies:
+ '@better-auth/core': ^1.7.6
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+
+ '@better-auth/utils@0.4.2':
+ resolution: {integrity: sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==}
+
+ '@better-auth/utils@0.5.1':
+ resolution: {integrity: sha512-WETqw5vQ52uQ/xwWR4E8rTgT6fDEr/wnS+otDNkBCa/69281FCF32OKDdQUcahMCnjsvqXBNiEvAQHFB0EVRRg==}
+
+ '@better-fetch/fetch@1.3.2':
+ resolution: {integrity: sha512-Gs7n99b5tqUC6cQAPbV0uED3IraHB6xQbHLQ/C3l7ZFafHScOx9pQ+DYmP5blbLFShVWLqxNUlI9wi4xU/X+ow==}
+
+ '@cacheable/memory@2.2.0':
+ resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==}
+
+ '@cacheable/utils@2.5.0':
+ resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==}
+
+ '@cloudflare/kv-asset-handler@0.5.0':
+ resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==}
+ engines: {node: '>=22.0.0'}
+
+ '@cloudflare/unenv-preset@2.16.2':
+ resolution: {integrity: sha512-JBP1+Z7ZSNG/d4mRP+y8VC5dka3tZVMLEZRvS+rzQ4DGV1EoxRFQckcJTTkXbHSQiTj0DtNI01Zwb/V2fX0mvQ==}
+ peerDependencies:
+ unenv: 2.0.0-rc.24
+ workerd: '>1.20260305.0 <2.0.0-0'
+ peerDependenciesMeta:
+ workerd:
+ optional: true
+
+ '@cloudflare/vite-plugin@1.64.0':
+ resolution: {integrity: sha512-h7Tunx9Ou5fUoao8O9jYTH0ParfrtNZzZVPA0IS19O7AoWA1SpYjwzDA6pZC78qzuV8sQSEOpYCN/yTShmd+gg==}
+ hasBin: true
+ peerDependencies:
+ vite: ^6.1.0 || ^7.0.0 || ^8.0.0
+ wrangler: ^4.151.0
+
+ '@cloudflare/workerd-darwin-64@1.20261012.1':
+ resolution: {integrity: sha512-dkTL9aY3V4D40b+jBpGPCistWUPFQ/M61wlWi6i1o8MvHFFgEw7EQkcaYEv6Yd3bkPDD/3TFT4hRsMb2xVZSwQ==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@cloudflare/workerd-darwin-64@1.20261019.1':
+ resolution: {integrity: sha512-5ZILbAta/fBQvhmAYeCE7dKMMYIr7N9wJEX50fEGLKSIwGtvT0HzSfHNIK/O7cBQ4gHQ2WfIiPClvwcye6E0fA==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@cloudflare/workerd-darwin-arm64@1.20261012.1':
+ resolution: {integrity: sha512-2/nVGcKXjNNI+DhxKSepTKvFng9H7aN2WXv6Zu67iqgI6JrxypNt5kTPv4ZHosxrcfyKMci/2RfN7GIrN0BitQ==}
+ engines: {node: '>=16'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@cloudflare/workerd-darwin-arm64@1.20261019.1':
+ resolution: {integrity: sha512-cww2Ab6lVMxpTiEEjKmPI58p5EMo0vYTZSH+3WkqXJdQgc3ES66GuL247+U2B2YWajhhu2tqj7jySrXneU749g==}
+ engines: {node: '>=16'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@cloudflare/workerd-linux-64@1.20261012.1':
+ resolution: {integrity: sha512-uMe7ONHnLxStD1Ye0YFHBO36uj4cStv5P53rW+5GVWXFT8BRjqVixlH0IqCAHe1Pmcwyd1+7fVoGde89MZSCJg==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [linux]
+
+ '@cloudflare/workerd-linux-64@1.20261019.1':
+ resolution: {integrity: sha512-4++VRi9vkQROYqrpZYOixIJuVDmujkwrT4kszsxNFlvcmsX6Mr2GumvxIN3gIixS3vJUh3Umdtkthqj5X0S3Xw==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [linux]
+
+ '@cloudflare/workerd-linux-arm64@1.20261012.1':
+ resolution: {integrity: sha512-I0VMdcXk7ygG5vYDce0ePTBFdnBXC0i9WiBY5mWiv0iTinbfea6/rHqSQ7B1UMpjgrYVs9E0m4bZ9ufsk5GCFA==}
+ engines: {node: '>=16'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@cloudflare/workerd-linux-arm64@1.20261019.1':
+ resolution: {integrity: sha512-75PVtJOwfjScQ53sbLtQXI7D8yP1c21t+WEUPaYbqkzaz4ZqfR5wAd+zuWs8G5Q7kOj2SQIvEfY5Sn8Y+UVrnA==}
+ engines: {node: '>=16'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@cloudflare/workerd-windows-64@1.20261012.1':
+ resolution: {integrity: sha512-c5hQvNx574UEoknaCFvMa/NdLrrYiALNbe6sx1okW8uOiRYWxrFuA8WpXFnBJ5XJypm0TEAHYaUTGv3rRLpY7Q==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [win32]
+
+ '@cloudflare/workerd-windows-64@1.20261019.1':
+ resolution: {integrity: sha512-z49fvKTETMCnG6wnMcQwxx9CpryFceiKz04FRjq26EkhCyzRNJ6c3UXhyZz3r5f1CXnnBZc5DcU8ZouPkUJCqw==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [win32]
+
+ '@cloudflare/workers-types@5.20261019.1':
+ resolution: {integrity: sha512-llvvy7WBVhK+OfykyBkG9A7OgsGvgwHSNyU40XGVkiy/xVFy0t/xflyhEBHT+U59yQECZQbmcZsJtqCNnLpIRg==}
+
+ '@cspotcode/source-map-support@0.8.1':
+ resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
+ engines: {node: '>=12'}
+
+ '@emnapi/runtime@1.11.3':
+ resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
+
+ '@esbuild/aix-ppc64@0.25.12':
+ resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/aix-ppc64@0.27.7':
+ resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/aix-ppc64@0.28.2':
+ resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.25.12':
+ resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm64@0.27.7':
+ resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm64@0.28.2':
+ resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.25.12':
+ resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-arm@0.27.7':
+ resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-arm@0.28.2':
+ resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.25.12':
+ resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/android-x64@0.27.7':
+ resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/android-x64@0.28.2':
+ resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.25.12':
+ resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-arm64@0.27.7':
+ resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-arm64@0.28.2':
+ resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.25.12':
+ resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.27.7':
+ resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.28.2':
+ resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.25.12':
+ resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-arm64@0.28.2':
+ resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.25.12':
+ resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.27.7':
+ resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.28.2':
+ resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.25.12':
+ resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm64@0.27.7':
+ resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm64@0.28.2':
+ resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.25.12':
+ resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.27.7':
+ resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.28.2':
+ resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.25.12':
+ resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.27.7':
+ resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.28.2':
+ resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.25.12':
+ resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.27.7':
+ resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.28.2':
+ resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.25.12':
+ resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.27.7':
+ resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.28.2':
+ resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.25.12':
+ resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.27.7':
+ resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.28.2':
+ resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.25.12':
+ resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.27.7':
+ resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.28.2':
+ resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.25.12':
+ resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.27.7':
+ resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.28.2':
+ resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.25.12':
+ resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.27.7':
+ resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.28.2':
+ resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-arm64@0.28.2':
+ resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.25.12':
+ resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.7':
+ resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.28.2':
+ resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-arm64@0.28.2':
+ resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.25.12':
+ resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.7':
+ resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.28.2':
+ resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.25.12':
+ resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/openharmony-arm64@0.28.2':
+ resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.25.12':
+ resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/sunos-x64@0.27.7':
+ resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/sunos-x64@0.28.2':
+ resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.25.12':
+ resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-arm64@0.27.7':
+ resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-arm64@0.28.2':
+ resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.25.12':
+ resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.27.7':
+ resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.28.2':
+ resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.25.12':
+ resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.7':
+ resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.28.2':
+ resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@eslint-community/eslint-utils@4.10.1':
+ resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+ '@eslint-community/regexpp@4.12.2':
+ resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ '@eslint/config-array@0.23.5':
+ resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ '@eslint/config-helpers@0.7.0':
+ resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ '@eslint/core@1.2.1':
+ resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ '@eslint/object-schema@3.0.5':
+ resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ '@eslint/plugin-kit@0.7.3':
+ resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ '@floating-ui/core@1.8.0':
+ resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==}
+
+ '@floating-ui/dom@1.8.0':
+ resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==}
+
+ '@floating-ui/react-dom@2.1.9':
+ resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@floating-ui/utils@0.2.12':
+ resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==}
+
+ '@fuma-translate/react@1.0.2':
+ resolution: {integrity: sha512-uOiOtBx3nRXR8Nu1GzBf1tApgF1FErDBTHxRIAQeyQdyOoZbrNRN6H4kDCWObY4qyGeGbHydG0DHzgeUgFDMIw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^19.2.0
+ react-dom: ^19.2.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@fumadocs/base-ui@16.17.7':
+ resolution: {integrity: sha512-t9Am0mxPrGuAG9BeC/ACLhNbBtxXbc+JIbTTzr7j5apnCFRQSDxGaZT9/+BRWG6DqltnsccGqGB1x3kPz7WaYw==}
+ peerDependencies:
+ '@types/mdx': '*'
+ '@types/react': '*'
+ fumadocs-core: 16.17.7
+ next: 16.x.x
+ react: ^19.2.0
+ react-dom: ^19.2.0
+ takumi-js: '*'
+ peerDependenciesMeta:
+ '@types/mdx':
+ optional: true
+ '@types/react':
+ optional: true
+ next:
+ optional: true
+ takumi-js:
+ optional: true
+
+ '@fumadocs/tailwind@0.1.4':
+ resolution: {integrity: sha512-1LAmuroJ6TJoQodyODRhMC9ThAkfrV2N5vZjaj4KKs+dpF2bs0d/2z0604iMKBLv2BKstR7zE9TUa/L0pxGnhA==}
+ peerDependencies:
+ tailwindcss: ^4.0.0
+ peerDependenciesMeta:
+ tailwindcss:
+ optional: true
+
+ '@fumari/image-size@0.1.1':
+ resolution: {integrity: sha512-iaiV2wyzJ4mW358NX4CX3yGit+WjKYzpaQ+rldK9BjL/5jFpeV6ruWnZVq7MEyMn3Gd0DLi8g/79NZAAQaGscw==}
+
+ '@hookform/resolvers@3.10.0':
+ resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==}
+ peerDependencies:
+ react-hook-form: ^7.0.0
+
+ '@humanfs/core@0.19.2':
+ resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/node@0.16.8':
+ resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/types@0.15.0':
+ resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/retry@0.4.3':
+ resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
+ engines: {node: '>=18.18'}
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.35.5':
+ resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.35.5':
+ resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-freebsd-wasm32@0.35.5':
+ resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==}
+ engines: {node: '>=20.9.0'}
+ os: [freebsd]
+
+ '@img/sharp-libvips-darwin-arm64@1.3.4':
+ resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.3.4':
+ resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.3.4':
+ resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-arm@1.3.4':
+ resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-ppc64@1.3.4':
+ resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-riscv64@1.3.4':
+ resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-s390x@1.3.4':
+ resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-x64@1.3.4':
+ resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.3.4':
+ resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.3.4':
+ resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linux-arm64@0.35.5':
+ resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-arm@0.35.5':
+ resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-ppc64@0.35.5':
+ resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==}
+ engines: {node: '>=20.9.0'}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-riscv64@0.35.5':
+ resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==}
+ engines: {node: '>=20.9.0'}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-s390x@0.35.5':
+ resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==}
+ engines: {node: '>=20.9.0'}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-x64@0.35.5':
+ resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linuxmusl-arm64@0.35.5':
+ resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linuxmusl-x64@0.35.5':
+ resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-wasm32@0.35.5':
+ resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==}
+ engines: {node: '>=20.9.0'}
+
+ '@img/sharp-webcontainers-wasm32@0.35.5':
+ resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==}
+ engines: {node: '>=20.9.0'}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.35.5':
+ resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.35.5':
+ resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==}
+ engines: {node: ^20.9.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.35.5':
+ resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [win32]
+
+ '@inquirer/ansi@1.0.2':
+ resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/checkbox@4.3.2':
+ resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/confirm@5.1.21':
+ resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/core@10.3.2':
+ resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/editor@4.2.23':
+ resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/expand@4.0.23':
+ resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/external-editor@1.0.3':
+ resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/figures@1.0.15':
+ resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==}
+ engines: {node: '>=18'}
+
+ '@inquirer/input@4.3.1':
+ resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/number@3.0.23':
+ resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/password@4.0.23':
+ resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/prompts@7.10.1':
+ resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/rawlist@4.1.11':
+ resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/search@3.2.2':
+ resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/select@4.4.2':
+ resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@inquirer/type@3.0.10':
+ resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@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/source-map@0.3.11':
+ resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==}
+
+ '@jridgewell/sourcemap-codec@1.6.0':
+ resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@jridgewell/trace-mapping@0.3.9':
+ resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+
+ '@keyv/bigmap@1.3.1':
+ resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ keyv: ^5.6.0
+
+ '@keyv/serialize@1.1.1':
+ resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==}
+
+ '@libsql/client@0.17.4':
+ resolution: {integrity: sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==}
+
+ '@libsql/core@0.17.4':
+ resolution: {integrity: sha512-LqF9gIvnJ38nmAH1y/ChizHqDO/MO1wLgA96XrraulEEbqXxLjleSH92YWTolbuJKgPUmGu4aJk9W3UnAcxLOQ==}
+
+ '@libsql/darwin-arm64@0.5.29':
+ resolution: {integrity: sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@libsql/darwin-x64@0.5.29':
+ resolution: {integrity: sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@libsql/hrana-client@0.10.0':
+ resolution: {integrity: sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==}
+
+ '@libsql/isomorphic-ws@0.1.5':
+ resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==}
+
+ '@libsql/kysely-libsql@0.4.1':
+ resolution: {integrity: sha512-mCTa6OWgoME8LNu22COM6XjKBmcMAvNtIO6DYM10jSAFq779fVlrTKQEmXIB8TwJVU65dA5jGCpT8gkDdWS0HQ==}
+ peerDependencies:
+ kysely: '*'
+
+ '@libsql/linux-arm-gnueabihf@0.5.29':
+ resolution: {integrity: sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==}
+ cpu: [arm]
+ os: [linux]
+
+ '@libsql/linux-arm-musleabihf@0.5.29':
+ resolution: {integrity: sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==}
+ cpu: [arm]
+ os: [linux]
+
+ '@libsql/linux-arm64-gnu@0.5.29':
+ resolution: {integrity: sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@libsql/linux-arm64-musl@0.5.29':
+ resolution: {integrity: sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@libsql/linux-x64-gnu@0.5.29':
+ resolution: {integrity: sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@libsql/linux-x64-musl@0.5.29':
+ resolution: {integrity: sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==}
+ cpu: [x64]
+ os: [linux]
+
+ '@libsql/win32-x64-msvc@0.5.29':
+ resolution: {integrity: sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==}
+ cpu: [x64]
+ os: [win32]
+
+ '@mdx-js/mdx@3.1.1':
+ resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
+
+ '@mikro-orm/cli@7.2.1':
+ resolution: {integrity: sha512-YNt8HKsb90awZqcionp1oZgL2ZLRyGl76x0lYdcfVkYkYY0zrNQs3ZZ76+6AS/FXSX5oEp6q94LCIiYwnr04jA==}
+ engines: {node: '>= 22.17.0'}
+ hasBin: true
+
+ '@mikro-orm/core@7.2.1':
+ resolution: {integrity: sha512-+gtJoScbin/C3wPItSZkj5vlMTq/LphBLIxHyi5brCbeA6VDcYuoMopiqoFUMQxdhXXrZlKNIHXGrhb8r3biVg==}
+ engines: {node: '>= 22.17.0'}
+ peerDependencies:
+ dataloader: 2.2.3
+ peerDependenciesMeta:
+ dataloader:
+ optional: true
+
+ '@mikro-orm/libsql@7.2.1':
+ resolution: {integrity: sha512-jXvptoHpbzfj8XUy5V5BvVee2LOsxgI/GnITfmh6Jl42tpIEDJx6Talqbv+z1PNGkHhw8OU5GoHXDJqYpNqo5w==}
+ engines: {node: '>= 22.17.0'}
+ peerDependencies:
+ '@mikro-orm/core': 7.2.1
+
+ '@mikro-orm/migrations@7.2.1':
+ resolution: {integrity: sha512-sxGcB7na0AkcREsD5U3xP+Psb/nhQFkx7/eY1Nsqq9MBs67O5RoCL97bn3lmgq6GwKZFbktMuuOGozq42+GaNg==}
+ engines: {node: '>= 22.17.0'}
+ peerDependencies:
+ '@mikro-orm/core': 7.2.1
+
+ '@mikro-orm/mysql@7.2.1':
+ resolution: {integrity: sha512-IxCEnfHUzFcxVkRCVaC0KtGoHRRLogxxgeI+J4Pk7oxtDf/jtvYQuFL4tSbmlrH3qzmLQeYYPyJPuDr+a2F7ag==}
+ engines: {node: '>= 22.17.0'}
+ peerDependencies:
+ '@mikro-orm/core': 7.2.1
+
+ '@mikro-orm/postgresql@7.2.1':
+ resolution: {integrity: sha512-PQ1qe4Bj/hQSHYJjR02l06FfEDwniAvncduwZSCLSKuaCUddHc5AN2Utj3yo4xRIVRY8pOa7DFitEQPBozTMJA==}
+ engines: {node: '>= 22.17.0'}
+ peerDependencies:
+ '@mikro-orm/core': 7.2.1
+
+ '@mikro-orm/sql@7.2.1':
+ resolution: {integrity: sha512-3M9dQeUDLlvAT5VJr/KBGAk9C7xez+psVCnvNkAO4hRhwx2Wm7N1HkuyP4Bwj0MjkHVB6LYvhTw/V6pYsVM8lA==}
+ engines: {node: '>= 22.17.0'}
+ peerDependencies:
+ '@mikro-orm/core': 7.2.1
+
+ '@mikro-orm/sqlite@7.2.1':
+ resolution: {integrity: sha512-+iAPGORAqLl+TcBF+JSLOfRq+PwTQG1NLts+AvN9D8C2czlbDpyjyeaAFSR+5wJlMEZ4wv2rdzt4jSS5T7x3XQ==}
+ engines: {node: '>= 22.17.0'}
+ peerDependencies:
+ '@mikro-orm/core': 7.2.1
+
+ '@napi-rs/lzma-linux-x64-gnu@1.5.1':
+ resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==}
+ engines: {node: ^22.20 || ^24.12 || >=25}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@neon-rs/load@0.0.4':
+ resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==}
+
+ '@next/env@14.2.35':
+ resolution: {integrity: sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==}
+
+ '@next/env@16.4.2':
+ resolution: {integrity: sha512-nTUTFH7G5/J/fmpkjVLegOkqyKOP0CEsJcMsyO4UCYeN1su+YMW/MfaSErnJskL7XM+UDK6aTvslxsRCyya/sA==}
+
+ '@next/swc-darwin-arm64@14.2.33':
+ resolution: {integrity: sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-arm64@16.4.2':
+ resolution: {integrity: sha512-ONkhFvZNFWlsEHOM/81AtxdyuJP2KRYKYR0JxPwvcu1AuPMMMgcL+wW2luldJvMtZwKtUxoSkCychW5wIeoYSw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@14.2.33':
+ resolution: {integrity: sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@16.4.2':
+ resolution: {integrity: sha512-luPCMbOsCoaF+kXJEUjmjmOZg1lC3BflhmUu+ZmW4tBu2vW/4AXak8JBFvePizGkxVmNiAw/r9ra+6UviCWtWQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@14.2.33':
+ resolution: {integrity: sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-arm64-gnu@16.4.2':
+ resolution: {integrity: sha512-xhwFTAncJyaCNy5KqKKuKaIIdCy1/1ZV1s5S1G0hhT7wGMkDTlfJ6aQbfRFnIG/s3/kDrxQ8aycVe+c5QnP8ow==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-arm64-musl@14.2.33':
+ resolution: {integrity: sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-arm64-musl@16.4.2':
+ resolution: {integrity: sha512-T1PNmfbPcxr5ndtWUL/3wQtLXsz808lq6sc2GrNT5k2oquF7UyqZddHSuAewHVsWsGXe6nsl9HoN1YNriVjuSg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-x64-gnu@14.2.33':
+ resolution: {integrity: sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-x64-gnu@16.4.2':
+ resolution: {integrity: sha512-N9cDUOCGtkJG5PNKDFZUF3xXndrJJcpLp121uAGjIGvO/U2p9tfdNOM9htj7+5f72l0m8rMw/cvYacUJBQoudg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-x64-musl@14.2.33':
+ resolution: {integrity: sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-x64-musl@16.4.2':
+ resolution: {integrity: sha512-yY2uh1YhX6ufuYy2FCbw1dqblbhI57GLYAJfCkqD9auTv6pLrH67Uccjc3QMKBeCYAG6lkgu08ExmX1bbjejjQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-win32-arm64-msvc@14.2.33':
+ resolution: {integrity: sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-arm64-msvc@16.4.2':
+ resolution: {integrity: sha512-j/ArWRIHpMMB6wYLMhr2puTguBt70lNU/Cmjl9p6dTDE8DGknYJMP9PdwPk2dqpCNL/KIX9yfngDvIesxJPmsg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-ia32-msvc@14.2.33':
+ resolution: {integrity: sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==}
+ engines: {node: '>= 10'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@14.2.33':
+ resolution: {integrity: sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@16.4.2':
+ resolution: {integrity: sha512-AA4edyWHDko3NCSo0x6GomsdgFb0oR1J3MXU1b5xt6FRFg4AucrMPW3S0hCe/9onU0O1BbpGQBsqo1r0Gneu1g==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@noble/ciphers@2.4.0':
+ resolution: {integrity: sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw==}
+ engines: {node: '>= 20.19.0'}
+
+ '@noble/hashes@2.4.0':
+ resolution: {integrity: sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==}
+ engines: {node: '>= 20.19.0'}
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@opentelemetry/semantic-conventions@1.43.0':
+ resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==}
+ engines: {node: '>=14'}
+
+ '@oxc-project/types@0.155.0':
+ resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==}
+
+ '@playwright/test@1.64.1':
+ resolution: {integrity: sha512-IaYGml/nSOiZWROfPtuIL7neuu9qDOZ3TNvNljUIrhDMxiGTgPjzj/g9p9RxpS2tSepPDRY+UwAaEeiKtUvIAg==}
+ engines: {node: '>=20'}
+ hasBin: true
+
+ '@poppinss/colors@4.1.6':
+ resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==}
+
+ '@poppinss/dumper@0.6.5':
+ resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==}
+
+ '@poppinss/exception@1.2.3':
+ resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==}
+
+ '@radix-ui/number@1.0.1':
+ resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==}
+
+ '@radix-ui/primitive@1.0.1':
+ resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==}
+
+ '@radix-ui/primitive@1.2.0':
+ resolution: {integrity: sha512-KABY+VMIRPJL+Vyzv/335FEhXXD/xDv8BMb1kl48/aXJZMH0LtHCTx5ga5RnxaEP3nZHtmTLf1P9vanmFX46bw==}
+
+ '@radix-ui/react-arrow@1.0.3':
+ resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-checkbox@1.4.1':
+ resolution: {integrity: sha512-KWtwhh+98ML3seZ9vO9yRY2OwaQG90dCiDAxjpSNY2AaZ3Hik3B0dsk6m0ILywo/no3A9/SozadyPMNweVT8yw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-collection@1.0.3':
+ resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-compose-refs@1.0.1':
+ resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-compose-refs@1.1.5':
+ resolution: {integrity: sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-context@1.0.1':
+ resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-context@1.3.0':
+ resolution: {integrity: sha512-v5AYEocMISkbJ+1fTXzZpiFv7NRr3D2WiYbLIKf+FkmJ8VkP6d503eV2n34MFussHXY1pcoq3yfJiQH77dc4Mg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-direction@1.0.1':
+ resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-dismissable-layer@1.0.4':
+ resolution: {integrity: sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-focus-guards@1.0.1':
+ resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-focus-scope@1.0.3':
+ resolution: {integrity: sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-id@1.0.1':
+ resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-label@2.1.17':
+ resolution: {integrity: sha512-xmj7MN/drx1oUAXkfiFIvyDmGNUIN/omGobvA5oAoNqu9zO2MkISYGZOkBcqSzs/UZXXwV+/3ACRE7q7mGcmkA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-popper@1.1.2':
+ resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-portal@1.0.3':
+ resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-presence@1.1.11':
+ resolution: {integrity: sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-primitive@1.0.3':
+ resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-primitive@2.2.0':
+ resolution: {integrity: sha512-HCTSPMNqv55Qk0IX4geJbpyXazmqulcimwuyjxTkKi29v+QZbG2Zho9BnbBq4YS2PF+KlNb2CXoLz66uUmblkg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-select@1.2.2':
+ resolution: {integrity: sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-slot@1.0.2':
+ resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-slot@1.5.0':
+ resolution: {integrity: sha512-tyYd9ddPXAysAbdbD9eYxgwpCSv6f3PncqVSNKQFSR5lcJVLz3cb/pANDoYrLiHBpXv7skortyUgGUWsYuPPFQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-callback-ref@1.0.1':
+ resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-controllable-state@1.0.1':
+ resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-controllable-state@1.3.0':
+ resolution: {integrity: sha512-TAcBI7bw2ljYCbv4+zuTSd6zICu8pRt6SDN2vJ/Z06K2MXh6I9WYFe/A9ovlFDtR5HVHGm5iDxDoABm/++dbKg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-effect-event@0.0.5':
+ resolution: {integrity: sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-escape-keydown@1.0.3':
+ resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-layout-effect@1.0.1':
+ resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-layout-effect@1.1.4':
+ resolution: {integrity: sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-previous@1.0.1':
+ resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-rect@1.0.1':
+ resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-size@1.0.1':
+ resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-size@1.1.5':
+ resolution: {integrity: sha512-V1McDQkMGzgivwqdu7u96APs7oi0Jvj9LTzgq3WWrDZqxWdAqU9yZnZQqk5OizGFR8badUQwZsrlao7MOlWYOA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-visually-hidden@1.0.3':
+ resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/rect@1.0.1':
+ resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
+
+ '@resvg/resvg-wasm@2.4.1':
+ resolution: {integrity: sha512-yi6R0HyHtsoWTRA06Col4WoDs7SvlXU3DLMNP2bdAgs7HK18dTEVl1weXgxRzi8gwLteGUbIg29zulxIB3GSdg==}
+ engines: {node: '>= 10'}
+
+ '@rolldown/binding-android-arm-eabi@1.2.15':
+ resolution: {integrity: sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [android]
+
+ '@rolldown/binding-android-arm64@1.2.15':
+ resolution: {integrity: sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@rolldown/binding-darwin-arm64@1.2.15':
+ resolution: {integrity: sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rolldown/binding-darwin-x64@1.2.15':
+ resolution: {integrity: sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rolldown/binding-freebsd-x64@1.2.15':
+ resolution: {integrity: sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.2.15':
+ resolution: {integrity: sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@rolldown/binding-linux-arm64-gnu@1.2.15':
+ resolution: {integrity: sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-arm64-musl@1.2.15':
+ resolution: {integrity: sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rolldown/binding-linux-ppc64-gnu@1.2.15':
+ resolution: {integrity: sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-s390x-gnu@1.2.15':
+ resolution: {integrity: sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-x64-gnu@1.2.15':
+ resolution: {integrity: sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-x64-musl@1.2.15':
+ resolution: {integrity: sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rolldown/binding-openharmony-arm64@1.2.15':
+ resolution: {integrity: sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rolldown/binding-win32-arm64-msvc@1.2.15':
+ resolution: {integrity: sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rolldown/binding-win32-x64-msvc@1.2.15':
+ resolution: {integrity: sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@rolldown/pluginutils@1.0.0-rc.7':
+ resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==}
+
+ '@rolldown/pluginutils@1.0.1':
+ resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
+
+ '@rollup/rollup-android-arm-eabi@4.65.1':
+ resolution: {integrity: sha512-5coxNSjqOI2J3NkVhlp3u+zGcyjnowQFsU9sg7MMz4UPXY4Dv63kFGLt7ConXz9CNq2i0yuOJZAF/2RMrgI2OA==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.65.1':
+ resolution: {integrity: sha512-K0HFf6XMB3IYs+jDZ1/RRhZaVOwxNXrl0n4MDEyGDjuK7+B6K/nDJp8DCBitO3S1sK/fzNxAf9QZAny4AIUPtg==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.65.1':
+ resolution: {integrity: sha512-zkZrXYwNlIcSUmcwY2DpsaDHr0XjVUeQHCuSunG3eQD7/5Wn/DvI7OMUE8NRRweK87yG8ebJ1xGOzmwpMsbZQA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.65.1':
+ resolution: {integrity: sha512-Zaed+R3cpkkA3aiNd7NO0GV5KFh/LVf8j6bGcoRdpoXkSm/mWH8M0oX2/3u/nyGcx/bHEovD9CzX+w9/gcpI4A==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.65.1':
+ resolution: {integrity: sha512-h12p3WJWhyJ9kir0zqAPr0rKNmBzOWIjoaOMT9OULs9KZQZCeOMKd+mGSvERjd9VxJYShd3zIxtrVxkYz6BEVA==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.65.1':
+ resolution: {integrity: sha512-yRBwh/5imKY4DydDulVtrjy8Jf7h7NQJUqZbgmZ3zFsCD9QqlnWvZ7RtEF+ecO1b+IukKjXlu5Bb9fehV3tIbg==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.65.1':
+ resolution: {integrity: sha512-1XuPiWYYaLE1UDOqhbKVOfsqxvfmFS/lYPSk92U1hEX1qRfSYH0hNeAlbxFIgjp4d6+YQmL95EPRgdvjbZEddA==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.65.1':
+ resolution: {integrity: sha512-Y3C5e55Yrf6p2r5rBcc4P9hFWVNi6oqWy/53I/AyCJJGlp3KRSpTP8eoUmVntchTbEnhgBgAgLO9flj9AvOdUw==}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-arm64-gnu@4.65.1':
+ resolution: {integrity: sha512-Itj6coSswkYPIcVLczObXmwdplHNQQxyfnK1ppBg4czDaX8RiEzLKqU7EMc64BiBuiDZEUS+M93ktM18rv5llw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm64-musl@4.65.1':
+ resolution: {integrity: sha512-KeO8jTEqdrnhvcahufbimyMoI44vedRUp1bVz2QUnRX2vDm/hxzCPt5F8fERVD5fsHyTW/vXmCElT054VOSVOA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-loong64-gnu@4.65.1':
+ resolution: {integrity: sha512-dDOz5VZZ+ZGnglpmET6VJefamWXFsgaVtuhSClf2/URZBp048jprD6z1hddsIMN6n1w+oUzGZEBp9u6Mlszsfg==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-loong64-musl@4.65.1':
+ resolution: {integrity: sha512-JbfRKz8nJCuo8gn1Dqx8lQWEHw4qhZ3uRaHphw5vrSjnSptJTKTRC/bLKHh8QQMsEnhL4uq+bdg3tkiXbJ2q/A==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.65.1':
+ resolution: {integrity: sha512-3oQpe1q0emSeCAssVHMQdOz5fz3PBH5my/Fr0ZekV2UMNL4ZiRa1ciikYlGQXyDkeqseYYv1InwOY8YPqY7RIQ==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-ppc64-musl@4.65.1':
+ resolution: {integrity: sha512-nNV3HHi23o1LtpGGwH+Bav4hqnc4+klQtC96tSvCfvql8bLlNFTnTFiGl/jai2nve3eEr/vT2ocuyf+h+eMnYQ==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.65.1':
+ resolution: {integrity: sha512-b5zab0FryBxuocuDeqOsYGAg2EzjKw4mKA6LjQXCyewXjGv/BXqACBsY2cO45xM4hV2weYtdjGThP2VB2ByAYg==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-riscv64-musl@4.65.1':
+ resolution: {integrity: sha512-Rh08xZakiUxKNgI3hbgH9mivlx478lSqckS9s+Oc3/TX1VrAH3W8z/5wpJXR/v5VjqcJ/jJNVBg64PU1+iQsTQ==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-s390x-gnu@4.65.1':
+ resolution: {integrity: sha512-qDgtS6juN3/k97y4kcD6XLFpXEo4f6CnG8lTOGYwlhrUYTrMyhN0WHdZCPAW5rqS0MqQG7qI7dxnjugt6QB39Q==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-gnu@4.65.1':
+ resolution: {integrity: sha512-44IKzBPqXXVm0kt1O+F5eW4juR5FyIxGNlFkpP8qwIDzucBsjM1HCbdYUQrQw8rU/g6HRl/tfBm0+Qq4H4Ro3w==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-musl@4.65.1':
+ resolution: {integrity: sha512-tvYWZ/h2PCHs558Xu7B6LptuRCV8lXV2xI75ONMcldII1m2zlFwuI4BJZi9M6rSMkYqcPLLtPUPrjyqfbzLOdg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-openbsd-x64@4.65.1':
+ resolution: {integrity: sha512-gdyeucgZCnei3pXwadKVTEAOgRx0B+c847DUPR/PdOMmp3olhfkYo6r0J4PzRFZB5ZICZQTxntyvgmWH5xT7rg==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.65.1':
+ resolution: {integrity: sha512-Wf/NEKdn2SAL4Nvt8HyDtdkseWTwiLbZEOoNYnEaHkbso0B9eHO42vKnZh+OYsn+IMhAMcWcuIwPlBOgOXsUzg==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.65.1':
+ resolution: {integrity: sha512-x9VSsDmsMsEWy4cr/mFeaEsXnVJ6Kc4NCAU/lCnwml3s7LQbZoa9+/qwc9etWHbuuDT5mYxdyyKUwo76njtjZw==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.65.1':
+ resolution: {integrity: sha512-RIDbiVvvLkN45mOFpbo6eYMgnuiBEB62BGR/0s4QJgGg2AvVxucDDNn67kpAcUoYyfmY8iX8/RifMcmxmmnejA==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.65.1':
+ resolution: {integrity: sha512-+KN8HIr88vN59JNxlrM2fMimzY43Y0lQB7+0xdVsFbvFCAA74CLKCdfzIHzzvndJryBc94Pm+MvwtukKjaS2ug==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.65.1':
+ resolution: {integrity: sha512-+Y1Sd49cSDq60UOl8/U2HI0ebUvnSl/hDhMHQn+ouw17yb8fYwMWIazzJ4JFpSkjPE7sj5NTNSX9IoyEqcFfyQ==}
+ cpu: [x64]
+ os: [win32]
+
+ '@shikijs/core@4.5.0':
+ resolution: {integrity: sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-javascript@4.5.0':
+ resolution: {integrity: sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-oniguruma@4.5.0':
+ resolution: {integrity: sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/langs@4.5.0':
+ resolution: {integrity: sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==}
+ engines: {node: '>=20'}
+
+ '@shikijs/primitive@4.5.0':
+ resolution: {integrity: sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==}
+ engines: {node: '>=20'}
+
+ '@shikijs/themes@4.5.0':
+ resolution: {integrity: sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==}
+ engines: {node: '>=20'}
+
+ '@shikijs/types@4.5.0':
+ resolution: {integrity: sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/vscode-textmate@10.1.0':
+ resolution: {integrity: sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ==}
+
+ '@shuding/opentype.js@1.4.0-beta.0':
+ resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==}
+ engines: {node: '>= 8.0.0'}
+ hasBin: true
+
+ '@sindresorhus/is@7.2.0':
+ resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==}
+ engines: {node: '>=18'}
+
+ '@smithy/core@3.37.0':
+ resolution: {integrity: sha512-97imTcCyiPd8k0e9+ts/Sp0W65Dn9Ti357J7M09Ov4tI8Q1JDJVFSoAJtjEVKqfHEr3Pdo2jfolqKCaaiszH0g==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/credential-provider-imds@4.5.2':
+ resolution: {integrity: sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/fetch-http-handler@5.8.0':
+ resolution: {integrity: sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/node-http-handler@4.13.0':
+ resolution: {integrity: sha512-/GGcPoNJ2nzGytdAanpbx7mpp9Coa8LP+/Rpmbktr8YeLuIXs9B0SEz+X3AeonHdyzOIFJdKbN7jOZ+Tj+pMGw==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/signature-v4@5.7.4':
+ resolution: {integrity: sha512-tHy0K0VtqNd5Y7Y41h0a0Lhh0L1GzC08dTWg0F7vRJWFtTENg7IZikf3wQkanYIRdb7ngoIPMTmqgUi401fEeQ==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/types@4.19.0':
+ resolution: {integrity: sha512-r7jh49VJxGerfAcTQA6gXcKc+98zOp/tqRwzYjgOE+iSQsP6cEU1hq2QzbuipmP68QtYdY9wKEhiCQZIzHgZ4Q==}
+ engines: {node: '>=18.0.0'}
+
+ '@speed-highlight/core@1.2.24':
+ resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@swc/counter@0.1.3':
+ resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+
+ '@swc/helpers@0.5.23':
+ resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==}
+
+ '@swc/helpers@0.5.5':
+ resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
+
+ '@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/postcss@4.3.3':
+ resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==}
+
+ '@turbo/darwin-64@2.11.10':
+ resolution: {integrity: sha512-By4idRap5+nLnMuRzLB4qkOPRlvNdyY1ne4VJYDyUoUB11H94k7uif9mbe3JT8JSNXs1D68uMcBj6hJ/jMQRvA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@turbo/darwin-arm64@2.11.10':
+ resolution: {integrity: sha512-pyEYlVcuexOPa92p0Wlwl9YT1Is5D60lxN3ItWm3g30YLvFaUq86TF4BBWg5ZAc0uMTnrOzCvuCsOBTdzUWnRQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@turbo/gen@2.11.10':
+ resolution: {integrity: sha512-PL/OEEJLdsmS8zF/ijMrG9yi/j+PYe0nOCcZ1XbKndcjdYmeALnqHaxwoGmOo73FwDzC8mnsy2KrqNV6biaGlA==}
+ hasBin: true
+
+ '@turbo/linux-64@2.11.10':
+ resolution: {integrity: sha512-1tYeR/IDZ5HEdsb0jNq2L2xam5nMQ+g80tlV2BZmv4OFw+pMcUM0mMmUcfc5wXPPNHVNPuDMjh9Y8G8HgXPLZA==}
+ cpu: [x64]
+ os: [android, linux]
+
+ '@turbo/linux-arm64@2.11.10':
+ resolution: {integrity: sha512-HuekQxvVGhUd46g1Im/DKdOtglHr4/gguZAvzEpPUgtxNkztSa8lWhQEGQ+EmPQ0n7w19qjThFU+OfEEd0uvlw==}
+ cpu: [arm64]
+ os: [android, linux]
+
+ '@turbo/windows-64@2.11.10':
+ resolution: {integrity: sha512-UJOP3BkbreY3/JlMgJR6ZiimxYIBn+c+B4tnBIxD0E9c3Estmk+XoVNVBNBottZLNRXe3/ScgOU4+/k8tIWysg==}
+ cpu: [x64]
+ os: [win32]
+
+ '@turbo/windows-arm64@2.11.10':
+ resolution: {integrity: sha512-xOkEjF3ws/b/YNlc+bvJHMYBn+vL+QbEISZFVi0qS+ImmhA1X3/gmNmBrjjIG3dg6aeN+n6gQitzSkXQ286qJQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/debug@4.1.13':
+ resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+ '@types/emscripten@1.41.6':
+ resolution: {integrity: sha512-uN+9i8bFT5CUcZfyIEYDrSueACEyKGbUs5kC/72DGlZZoinh84sJfVV0i8UOJD1asdzkvLPBRrKs41kZ8MdEXg==}
+
+ '@types/esrecurse@4.3.1':
+ resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
+
+ '@types/estree-jsx@1.0.5':
+ resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/hast@3.0.5':
+ resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdx@2.0.14':
+ resolution: {integrity: sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
+ '@types/node@20.14.11':
+ resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==}
+
+ '@types/node@22.18.6':
+ resolution: {integrity: sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==}
+
+ '@types/node@26.6.5':
+ resolution: {integrity: sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==}
+
+ '@types/prop-types@15.7.15':
+ resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
+
+ '@types/react-dom@18.3.0':
+ resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
+
+ '@types/react-dom@19.3.0':
+ resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==}
+ peerDependencies:
+ '@types/react': ^19.3.0
+
+ '@types/react@18.3.3':
+ resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==}
+
+ '@types/react@19.3.0':
+ resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==}
+
+ '@types/unist@2.0.11':
+ resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/ws@8.18.2':
+ resolution: {integrity: sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==}
+
+ '@typescript/typescript-aix-ppc64@7.0.2':
+ resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@typescript/typescript-darwin-arm64@7.0.2':
+ resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@typescript/typescript-darwin-x64@7.0.2':
+ resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@typescript/typescript-freebsd-arm64@7.0.2':
+ resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@typescript/typescript-freebsd-x64@7.0.2':
+ resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@typescript/typescript-linux-arm64@7.0.2':
+ resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@typescript/typescript-linux-arm@7.0.2':
+ resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm]
+ os: [linux]
+
+ '@typescript/typescript-linux-loong64@7.0.2':
+ resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@typescript/typescript-linux-mips64el@7.0.2':
+ resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@typescript/typescript-linux-ppc64@7.0.2':
+ resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@typescript/typescript-linux-riscv64@7.0.2':
+ resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@typescript/typescript-linux-s390x@7.0.2':
+ resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==}
+ engines: {node: '>=16.20.0'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@typescript/typescript-linux-x64@7.0.2':
+ resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@typescript/typescript-netbsd-arm64@7.0.2':
+ resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@typescript/typescript-netbsd-x64@7.0.2':
+ resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@typescript/typescript-openbsd-arm64@7.0.2':
+ resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@typescript/typescript-openbsd-x64@7.0.2':
+ resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@typescript/typescript-sunos-x64@7.0.2':
+ resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@typescript/typescript-win32-arm64@7.0.2':
+ resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@typescript/typescript-win32-x64@7.0.2':
+ resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [win32]
+
+ '@ungap/structured-clone@1.4.0':
+ resolution: {integrity: sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==}
+
+ '@unpic/core@1.0.3':
+ resolution: {integrity: sha512-aum9YNVUGso7MjGLD0Rp/08kywCGLqZ03/q6VQBFFakDBOXWEc8D4kPGcZ8v5wEnGRex3lE+++bOuucBp3KJ/w==}
+
+ '@unpic/react@1.0.2':
+ resolution: {integrity: sha512-5RmRfELwTF8w+4zjtQGqjpvX+RU2VLvis3xDCS1O2uWk0PZN2cvatL+3/KAR3mshAuRrkFGTX1XwyAezSXaoCA==}
+ peerDependencies:
+ next: ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ next:
+ optional: true
+
+ '@vercel/og@1.0.3':
+ resolution: {integrity: sha512-/iYJ34PDu4lty1TXdL86qHEw8viveHTllG1PWLuJX8tSFfqKL7kyVJeUORJmQ250bHB0h+alcalXUlza3c/NSA==}
+ engines: {node: '>=22'}
+
+ '@vinext/types@1.0.2':
+ resolution: {integrity: sha512-ORcuy4DNiT2EFsLsCh2FtZz1I7Q3HGf1PSu80ALqwlq+en7UJeLKQE7FmKgvW0cJL79GvZuZe4jddzGpqDMw/Q==}
+ engines: {node: '>=22'}
+
+ '@vitejs/plugin-react@6.0.1':
+ resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ peerDependencies:
+ '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0
+ babel-plugin-react-compiler: ^1.0.0
+ vite: ^8.0.0
+ peerDependenciesMeta:
+ '@rolldown/plugin-babel':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+
+ '@vitejs/plugin-rsc@0.5.38':
+ resolution: {integrity: sha512-SoiRBJBVd3Qg6Frnvdk6LwugJYlQKgee+uqySxKz5T/KsCZUgdw529Klzg4IDJuP/EOfsIJ2YiOKAFY8tnr1kg==}
+ peerDependencies:
+ react: '*'
+ react-dom: '*'
+ react-server-dom-webpack: '*'
+ vite: '*'
+ peerDependenciesMeta:
+ react-server-dom-webpack:
+ optional: true
+
+ '@vitest/expect@3.2.7':
+ resolution: {integrity: sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==}
+
+ '@vitest/mocker@3.2.7':
+ resolution: {integrity: sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@3.2.7':
+ resolution: {integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==}
+
+ '@vitest/runner@3.2.7':
+ resolution: {integrity: sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==}
+
+ '@vitest/snapshot@3.2.7':
+ resolution: {integrity: sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==}
+
+ '@vitest/spy@3.2.7':
+ resolution: {integrity: sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==}
+
+ '@vitest/utils@3.2.7':
+ resolution: {integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==}
+
+ '@webassemblyjs/ast@1.14.1':
+ resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
+
+ '@webassemblyjs/floating-point-hex-parser@1.13.2':
+ resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==}
+
+ '@webassemblyjs/helper-api-error@1.13.2':
+ resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==}
+
+ '@webassemblyjs/helper-buffer@1.14.1':
+ resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==}
+
+ '@webassemblyjs/helper-numbers@1.13.2':
+ resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==}
+
+ '@webassemblyjs/helper-wasm-bytecode@1.13.2':
+ resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==}
+
+ '@webassemblyjs/helper-wasm-section@1.14.1':
+ resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==}
+
+ '@webassemblyjs/ieee754@1.13.2':
+ resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==}
+
+ '@webassemblyjs/leb128@1.13.2':
+ resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==}
+
+ '@webassemblyjs/utf8@1.13.2':
+ resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==}
+
+ '@webassemblyjs/wasm-edit@1.14.1':
+ resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==}
+
+ '@webassemblyjs/wasm-gen@1.14.1':
+ resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==}
+
+ '@webassemblyjs/wasm-opt@1.14.1':
+ resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==}
+
+ '@webassemblyjs/wasm-parser@1.14.1':
+ resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==}
+
+ '@webassemblyjs/wast-printer@1.14.1':
+ resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==}
+
+ '@xtuc/ieee754@1.2.0':
+ resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
+
+ '@xtuc/long@4.2.2':
+ resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
+
+ '@yudiel/react-qr-scanner@2.6.0':
+ resolution: {integrity: sha512-WjNcSt7qquYUz1LVbwKzSnRQI47sNrh4Vh6nNiGKVxnYcP+KgN5q9rcSzXyZ/7GRV9PPrnzoIuE5YdOxB9yAog==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^17 || ^18 || ^19
+ react-dom: ^17 || ^18 || ^19
+
+ '@yuku-core/binding-android-arm64@0.19.0':
+ resolution: {integrity: sha512-wdL2XmTiZixAOaHk9Z0JJZ8u9Qm8d333Zjpc6gaxXFX+UR5BlsfxZ7a2+2Rm71pamppsPYGUGFq2oVLbh6DISw==}
+ cpu: [arm64]
+ os: [android]
+
+ '@yuku-core/binding-darwin-arm64@0.19.0':
+ resolution: {integrity: sha512-7sNJa6XJhyetnTy64jw3NEi4YgUcezHk1G5GH9FSvXAuC8wIlbaOwT9lgq5qo5sspjrZJQlBR1TWflP49uRpMw==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@yuku-core/binding-darwin-x64@0.19.0':
+ resolution: {integrity: sha512-pTC7dYEc59isdyizc3nsuyFNBu2LU5wMYZ1be6UMr59PY/AJNtO1aBLWV0MgL/z7C1nv/2sX4TNjGgKLoeevJw==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@yuku-core/binding-freebsd-x64@0.19.0':
+ resolution: {integrity: sha512-xrZjF6XOEwyLOiDIfrwDdRCS6ghxcJeirNC1KivQhVcUwlRonaU79S3/Uiyx3lBylPnT8qKJ3/aMT+H52nGTJQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@yuku-core/binding-linux-arm-gnu@0.19.0':
+ resolution: {integrity: sha512-0OyIH53C0I1CbADHn9FSdCfX5qbpeLwJhmOVhonFJNYheybOnkSJ50qGMfTJIb8y5zrwqvLs7FVBvz6Fk8maZg==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@yuku-core/binding-linux-arm-musl@0.19.0':
+ resolution: {integrity: sha512-z/iPfkCOCSXE34VXNt0uP1ORSW+4mEa9b5CiJcWZeqZH08g49bFU/jRM2T04f+Wpw5mJ6HIzNBiojxeAbrHjeg==}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
+
+ '@yuku-core/binding-linux-arm64-gnu@0.19.0':
+ resolution: {integrity: sha512-jLNTi+gzaRwBJ+gwhCJ+rDb5dmx/8hEBx93UWd7hjMSqPTL1D1wvVSvXVAldV5kALvju7b0/m51EHEhs4+I1fA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@yuku-core/binding-linux-arm64-musl@0.19.0':
+ resolution: {integrity: sha512-YwyPIdW/rN2Fmv0MTFWi47FaB3F9g+2b+sJISyAw83Yd60RWH4T3Nx6XkAHHVN+uKJNBAd6So7/BVihSiFYvuQ==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@yuku-core/binding-linux-x64-gnu@0.19.0':
+ resolution: {integrity: sha512-/vskaAXVX3ESR43FiTdfiYS7z1b9uoQJwVQ/0RgUHgN2sWoAyCZs+aX4CgU7eKGIHTVfp9VFwv+c+2XchYiEtQ==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@yuku-core/binding-linux-x64-musl@0.19.0':
+ resolution: {integrity: sha512-FuXL5igeSKib9Rye02TdH+D6SQezTyGxIATMu1Qsn/QywrzwpGl35OLpS2C1x5vpGLeVE2XgiLd5mVPFHmIglQ==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@yuku-core/binding-win32-arm64@0.19.0':
+ resolution: {integrity: sha512-YuJAe7zEKT1Xa7LuHlhGJpPnYQeVtvo0rZvNjJRqkH0hQGOw4C8QeP30Tg5VKGzZfo2x8CjhjEhKt4TmLwfmdg==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@yuku-core/binding-win32-x64@0.19.0':
+ resolution: {integrity: sha512-o8iY/mXwlRkedp0LNTr4+TEfXTPQwoNZmv6k+1WIAd1ZXEn8xJJTBCtB0osaVvdZo/x/cNmV16UrWrrGpM5Mvw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@yuku-toolchain/types@0.19.0':
+ resolution: {integrity: sha512-tFkNbsP4WXX9UMUC5syJGdK9dPMLK0PPaIuXCcCYH75sZ8MrebfBZ2XvCILRTw8AgLivSSCfDa4R67iYBDa4Kg==}
+
+ '@zeit/schemas@2.36.0':
+ resolution: {integrity: sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==}
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn-loose@8.5.2:
+ resolution: {integrity: sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==}
+ engines: {node: '>=0.4.0'}
+
+ acorn@8.19.0:
+ resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv-formats@3.0.1:
+ resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv-keywords@5.1.0:
+ resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
+ peerDependencies:
+ ajv: ^8.8.2
+
+ ajv@6.15.0:
+ resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
+
+ ajv@8.18.0:
+ resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
+
+ ajv@8.20.0:
+ resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+
+ ansi-align@3.0.1:
+ resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.4.0:
+ resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==}
+ engines: {node: '>=12'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@6.2.3:
+ resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
+ engines: {node: '>=12'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arch@2.2.0:
+ resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ aria-hidden@1.2.6:
+ resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
+ engines: {node: '>=10'}
+
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
+ astring@1.9.0:
+ resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
+ hasBin: true
+
+ autoprefixer@10.4.19:
+ resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
+ aws-ssl-profiles@1.1.2:
+ resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==}
+ engines: {node: '>= 6.0.0'}
+
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
+ barcode-detector@3.2.3:
+ resolution: {integrity: sha512-PLinpWGiOQoQH4X+YObWZ6iXeffXKDM3d4vnOD86481SvukIfvkf7jEE/tud9oI4HTDxtDdlHaFilA5Kn7Xa7A==}
+
+ base64-js@0.0.8:
+ resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==}
+ engines: {node: '>= 0.4'}
+
+ baseline-browser-mapping@2.11.33:
+ resolution: {integrity: sha512-yiVKDX+qCMRKBE084lXvq9EcwFUhKZ2nU8TK1EQQuOgPNR/lmbGxXOeDdlGUqC2Zz11Cs9rk1d/8NfgBmlkt0w==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ better-auth@1.7.6:
+ resolution: {integrity: sha512-WTMqOpmTTj+oBoX7zzPOzL85342Upyf+/v0IkH1kvGRA85lV4JGRFIYMIRKqvjZ6ShsuL5VX/c9C13jtoZXcKA==}
+ peerDependencies:
+ '@lynx-js/react': '*'
+ '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
+ '@sveltejs/kit': ^2.0.0
+ '@tanstack/react-start': ^1.0.0
+ '@tanstack/solid-start': ^1.0.0
+ drizzle-kit: '>=0.31.4 || >=1.0.0-beta.1'
+ drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
+ mongodb: ^6.0.0 || ^7.0.0
+ mysql2: ^3.0.0
+ next: ^14.0.0 || ^15.0.0 || ^16.0.0
+ pg: ^8.0.0
+ prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ solid-js: ^1.0.0
+ svelte: ^4.0.0 || ^5.0.0
+ vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
+ vue: ^3.0.0
+ peerDependenciesMeta:
+ '@lynx-js/react':
+ optional: true
+ '@prisma/client':
+ optional: true
+ '@sveltejs/kit':
+ optional: true
+ '@tanstack/react-start':
+ optional: true
+ '@tanstack/solid-start':
+ optional: true
+ drizzle-kit:
+ optional: true
+ drizzle-orm:
+ optional: true
+ mongodb:
+ optional: true
+ mysql2:
+ optional: true
+ next:
+ optional: true
+ pg:
+ optional: true
+ prisma:
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ solid-js:
+ optional: true
+ svelte:
+ optional: true
+ vitest:
+ optional: true
+ vue:
+ optional: true
+
+ better-call@1.4.0:
+ resolution: {integrity: sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA==}
+ peerDependencies:
+ zod: ^4.0.0
+ peerDependenciesMeta:
+ zod:
+ optional: true
+
+ better-sqlite3@13.0.3:
+ resolution: {integrity: sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==}
+ engines: {node: '>=22'}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ blake3-wasm@2.1.5:
+ resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
+
+ bowser@2.15.0:
+ resolution: {integrity: sha512-xic6KSZglg/I4ymp45fdM4GWfYpBK79Fxd/TOvJktlaPgQqqDxvmGwOPZl2V0dyeS3Lj5c180bLhXF43iyAjZQ==}
+
+ boxen@7.0.0:
+ resolution: {integrity: sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==}
+ engines: {node: '>=14.16'}
+
+ brace-expansion@1.1.21:
+ resolution: {integrity: sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==}
+
+ brace-expansion@5.0.12:
+ resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==}
+ engines: {node: 20 || >=22}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.29.5:
+ resolution: {integrity: sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+ bundle-require@5.1.0:
+ resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ peerDependencies:
+ esbuild: '>=0.18'
+
+ busboy@1.6.0:
+ resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
+ engines: {node: '>=10.16.0'}
+
+ bytes@3.0.0:
+ resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
+ engines: {node: '>= 0.8'}
+
+ bytes@3.1.2:
+ resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
+ engines: {node: '>= 0.8'}
+
+ cac@6.7.14:
+ resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+ engines: {node: '>=8'}
+
+ cacheable@2.5.0:
+ resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==}
+
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ camelcase@7.0.1:
+ resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
+ engines: {node: '>=14.16'}
+
+ camelize@1.0.1:
+ resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
+
+ caniuse-lite@1.0.30001819:
+ resolution: {integrity: sha512-LFUqIIAwpzsIuevnKnsR9qnStBcgzPShTX61lBwN9uFkkf8o8zLiebEjbW8AYtZiF+1YKDWfdt/pWDtMuG8Xwg==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ chai@5.3.3:
+ resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
+ engines: {node: '>=18'}
+
+ chalk-template@0.4.0:
+ resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==}
+ engines: {node: '>=12'}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chalk@5.0.1:
+ resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ character-reference-invalid@2.0.1:
+ resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
+
+ chardet@2.2.0:
+ resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==}
+
+ check-error@2.1.3:
+ resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
+ engines: {node: '>= 16'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ chokidar@5.0.0:
+ resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
+ engines: {node: '>= 20.19.0'}
+
+ chrome-trace-event@1.0.4:
+ resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
+ engines: {node: '>=6.0'}
+
+ class-variance-authority@0.7.1:
+ resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
+
+ cli-boxes@3.0.0:
+ resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
+ engines: {node: '>=10'}
+
+ cli-width@4.1.0:
+ resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
+ engines: {node: '>= 12'}
+
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ clipboardy@3.0.0:
+ resolution: {integrity: sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ cn@0.4.0:
+ resolution: {integrity: sha512-qOAeUhPwPzBxx6jaeQdo646XIKliKHc2j1ZF7Ngb1o0pJZKH5gq8FkA0aVdUdPFUDXNXyUCXpCtoJISo6dhizg==}
+ engines: {node: '>=20'}
+ hasBin: true
+
+ cn@0.5.0:
+ resolution: {integrity: sha512-JGEixZEpfFXm1P5uXwvEobOFLlHwIWi5v4tjd1ZwfiYmcEilkuD2l+054rvJcYCR1B+uVThHeUbgmNz1FwuxuA==}
+ engines: {node: '>=22'}
+ hasBin: true
+
+ collapse-white-space@2.1.0:
+ resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ commander@12.1.0:
+ resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
+ engines: {node: '>=18'}
+
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ compressible@2.0.18:
+ resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
+ engines: {node: '>= 0.6'}
+
+ compression@1.8.1:
+ resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==}
+ engines: {node: '>= 0.8.0'}
+
+ compute-scroll-into-view@3.1.1:
+ resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
+ consola@3.4.2:
+ resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
+ engines: {node: ^14.18.0 || >=16.10.0}
+
+ content-disposition@0.5.2:
+ resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==}
+ engines: {node: '>= 0.6'}
+
+ cookie@1.1.1:
+ resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
+ engines: {node: '>=18'}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ css-background-parser@0.1.0:
+ resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==}
+
+ css-box-shadow@1.0.0-3:
+ resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==}
+
+ css-color-keywords@1.0.0:
+ resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
+ engines: {node: '>=4'}
+
+ css-gradient-parser@0.0.17:
+ resolution: {integrity: sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg==}
+ engines: {node: '>=16'}
+
+ css-to-react-native@3.2.0:
+ resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ debug@2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decode-named-character-reference@1.3.0:
+ resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
+
+ deep-eql@5.0.2:
+ resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
+ engines: {node: '>=6'}
+
+ deep-extend@0.6.0:
+ resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
+ engines: {node: '>=4.0.0'}
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ defu@6.1.7:
+ resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ detect-libc@2.0.2:
+ resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
+ engines: {node: '>=8'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ dotenv-cli@7.4.4:
+ resolution: {integrity: sha512-XkBYCG0tPIes+YZr4SpfFv76SQrV/LeCE8CI7JSEMi3VR9MvTihCGTOtbIexD6i2mXF+6px7trb1imVCXSNMDw==}
+ hasBin: true
+
+ dotenv-expand@10.0.0:
+ resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==}
+ engines: {node: '>=12'}
+
+ dotenv@16.6.1:
+ resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
+ engines: {node: '>=12'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ electron-to-chromium@1.5.465:
+ resolution: {integrity: sha512-zg4iUpbeGw7YNZsswc2xKr2uiBex2d8dELAXo92Icw3but1ULbrvK8USe6wVLaWjgJnKBARv0pchx9Owktx6wQ==}
+
+ emoji-regex-xs@2.0.1:
+ resolution: {integrity: sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==}
+ engines: {node: '>=10.0.0'}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ enhanced-resolve@5.26.0:
+ resolution: {integrity: sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==}
+ engines: {node: '>=10.13.0'}
+
+ error-stack-parser-es@1.0.5:
+ resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-module-lexer@1.7.0:
+ resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
+
+ es-module-lexer@2.3.2:
+ resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==}
+
+ es-module-lexer@3.0.4:
+ resolution: {integrity: sha512-BldNY5mwkVu+cQ5Ymn3e6hB9Sx8XHx4ZevWbiUyZbfKxJxYO27Hf0wfzkxIaD5CAJMaGl3YspKELj0ff/7nCMA==}
+
+ esast-util-from-estree@2.0.0:
+ resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
+
+ esast-util-from-js@2.0.1:
+ resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==}
+
+ esbuild@0.25.12:
+ resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ esbuild@0.27.7:
+ resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ esbuild@0.28.2:
+ resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-html@1.0.3:
+ resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ eslint-scope@9.1.2:
+ resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@5.0.1:
+ resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ eslint@10.13.0:
+ resolution: {integrity: sha512-UohDjD4zSzEwhf58M3O7vc/ycc8O1I7dNlhtD0WxE8Px8EHNJKtUwzBqrzeGhisRuv2ag4sAYswszCJRgKXYUg==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+ hasBin: true
+ peerDependencies:
+ jiti: '*'
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+
+ espree@11.2.0:
+ resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ esquery@1.7.0:
+ resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ estree-util-attach-comments@3.0.0:
+ resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
+
+ estree-util-build-jsx@3.0.1:
+ resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==}
+
+ estree-util-is-identifier-name@3.0.0:
+ resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
+
+ estree-util-scope@1.0.1:
+ resolution: {integrity: sha512-B0np3dcdxqILX5e9nEi5/Fr4K7gL4oYFVPV1zRa2e9wRCbQoZZNWOZFYyoInvXUPJXBXjss+QXlWLJChDEHDkA==}
+
+ estree-util-to-js@2.0.0:
+ resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==}
+
+ estree-util-value-to-estree@3.5.0:
+ resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==}
+
+ estree-util-visit@2.0.0:
+ resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ events@3.3.0:
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+ engines: {node: '>=0.8.x'}
+
+ execa@5.1.1:
+ resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+ engines: {node: '>=10'}
+
+ expect-type@1.4.0:
+ resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
+ engines: {node: '>=12.0.0'}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fast-uri@3.1.9:
+ resolution: {integrity: sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==}
+
+ fastq@1.20.3:
+ resolution: {integrity: sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ fflate@0.7.3:
+ resolution: {integrity: sha512-0Zz1jOzJWERhyhsimS54VTqOteCNwRtIlh8isdL0AXLo0g7xNTfTL7oWrkmCnPhZGocKIkWHBistBrrpoNH3aw==}
+
+ file-entry-cache@11.1.5:
+ resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ fix-dts-default-cjs-exports@1.0.1:
+ resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==}
+
+ flat-cache@6.1.23:
+ resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==}
+
+ flatted@3.4.4:
+ resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==}
+
+ fraction.js@4.3.7:
+ resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
+
+ framer-motion@14.6.0:
+ resolution: {integrity: sha512-MzBgZxGgoHPfSLEXmo4o5XlZvb+nVRFdHtGjVhm6LMIEJKTt/8hNO023euL5mYyzc8llV/hQTfjnN68tNRHalw==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ 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]
+
+ fumadocs-core@16.17.7:
+ resolution: {integrity: sha512-o8uR1JuFgAHrUSbX/hzThOsvW8tFXfV4vlrWf7VeFd+lbQsRqwr8R7gvs96Vwwzn5xSDfgg0boQalyv1llJAQQ==}
+ peerDependencies:
+ '@mdx-js/mdx': '*'
+ '@mixedbread/sdk': 0.x.x
+ '@modelcontextprotocol/server': 2.x.x
+ '@orama/core': 1.x.x
+ '@oramacloud/client': 2.x.x
+ '@tanstack/react-router': 1.x.x
+ '@types/estree-jsx': '*'
+ '@types/hast': '*'
+ '@types/mdast': '*'
+ '@types/react': '*'
+ algoliasearch: 5.x.x
+ flexsearch: '*'
+ lucide-react: '*'
+ meilisearch: '>=0.50.0 <1.0.0'
+ next: 16.x.x
+ react: ^19.2.0
+ react-dom: ^19.2.0
+ react-router: 7.x.x || 8.x.x
+ waku: '*'
+ zod: 4.x.x
+ peerDependenciesMeta:
+ '@mdx-js/mdx':
+ optional: true
+ '@mixedbread/sdk':
+ optional: true
+ '@modelcontextprotocol/server':
+ optional: true
+ '@orama/core':
+ optional: true
+ '@oramacloud/client':
+ optional: true
+ '@tanstack/react-router':
+ optional: true
+ '@types/estree-jsx':
+ optional: true
+ '@types/hast':
+ optional: true
+ '@types/mdast':
+ optional: true
+ '@types/react':
+ optional: true
+ algoliasearch:
+ optional: true
+ flexsearch:
+ optional: true
+ lucide-react:
+ optional: true
+ meilisearch:
+ optional: true
+ next:
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ react-router:
+ optional: true
+ waku:
+ optional: true
+ zod:
+ optional: true
+
+ fumadocs-mdx@15.4.9:
+ resolution: {integrity: sha512-vsZGzpGsWptlBAX8sWb7R87KIt9+3GhJa5GpkwJqBv/OaN9QGul34hJikKdq6C8pT2XOwKMB499lvj31JaHbGg==}
+ hasBin: true
+ peerDependencies:
+ '@fumadocs/satteri': 0.x.x
+ '@types/mdast': '*'
+ '@types/mdx': '*'
+ '@types/react': '*'
+ fumadocs-core: ^16.17.0
+ mdast-util-directive: '*'
+ next: ^15.3.0 || ^16.0.0
+ react: ^19.2.0
+ rolldown: '*'
+ satteri: ^0.10.5
+ vite: 7.x.x || 8.x.x
+ peerDependenciesMeta:
+ '@fumadocs/satteri':
+ optional: true
+ '@types/mdast':
+ optional: true
+ '@types/mdx':
+ optional: true
+ '@types/react':
+ optional: true
+ mdast-util-directive:
+ optional: true
+ next:
+ optional: true
+ react:
+ optional: true
+ rolldown:
+ optional: true
+ satteri:
+ optional: true
+ vite:
+ optional: true
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ generate-function@2.3.1:
+ resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+
+ get-stream@6.0.1:
+ resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+ engines: {node: '>=10'}
+
+ github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ harfbuzzjs@0.10.0:
+ resolution: {integrity: sha512-SN8LVwCOzvTq3OPNd0+EAghgXugItz56wst567D1vs7LnnKGWprhi3EG58aVOBwhN8HEbQxL4I9NDWkcXUutRw==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ hashery@1.5.1:
+ resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==}
+ engines: {node: '>=20'}
+
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
+ engines: {node: '>= 0.4'}
+
+ hast-util-from-dom@5.0.1:
+ resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==}
+
+ hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+
+ hast-util-to-estree@3.1.3:
+ resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==}
+
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-to-jsx-runtime@2.3.6:
+ resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hastscript@9.0.1:
+ resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
+
+ hex-rgb@4.3.0:
+ resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==}
+ engines: {node: '>=6'}
+
+ hookified@1.15.1:
+ resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==}
+
+ hookified@2.2.0:
+ resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ human-signals@2.1.0:
+ resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
+ engines: {node: '>=10.17.0'}
+
+ iconv-lite@0.7.3:
+ resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==}
+ engines: {node: '>=0.10.0'}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ ini@1.3.8:
+ resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+
+ inline-style-parser@0.2.7:
+ resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
+
+ ipaddr.js@2.5.0:
+ resolution: {integrity: sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==}
+ engines: {node: '>= 10'}
+
+ is-alphabetical@2.0.1:
+ resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+
+ is-alphanumerical@2.0.1:
+ resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-core-module@2.17.0:
+ resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==}
+ engines: {node: '>= 0.4'}
+
+ is-decimal@2.0.1:
+ resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+
+ is-docker@2.2.1:
+ resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-hexadecimal@2.0.1:
+ resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ is-port-reachable@4.0.0:
+ resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ is-property@1.0.2:
+ resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==}
+
+ is-stream@2.0.1:
+ resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+ engines: {node: '>=8'}
+
+ is-wsl@2.2.0:
+ resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
+ engines: {node: '>=8'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jest-worker@27.5.1:
+ resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
+ engines: {node: '>= 10.13.0'}
+
+ jiti@1.21.7:
+ resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
+ hasBin: true
+
+ jiti@2.4.2:
+ resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
+ hasBin: true
+
+ jiti@2.7.0:
+ resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
+ hasBin: true
+
+ jose@6.2.13:
+ resolution: {integrity: sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==}
+
+ joycon@3.1.1:
+ resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
+ engines: {node: '>=10'}
+
+ js-base64@3.9.5:
+ resolution: {integrity: sha512-u0CFDUca8BbBRkMkF/fDcuoLCx9nTNbXdVtbjVnBqySA9E221u0uYKbACiYGOEk1heY69qM4caeX3OwjSyxevw==}
+
+ js-tokens@10.0.0:
+ resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==}
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-tokens@9.0.1:
+ resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ keyv@5.6.0:
+ resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==}
+
+ kleur@4.1.5:
+ resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
+ engines: {node: '>=6'}
+
+ kysely@0.29.6:
+ resolution: {integrity: sha512-hHaB8C/rfzDDtr/t8YZwxAuPJTT0zHyaPoVzcXwDYhYNAgH/4sIfVhi/XLLIY+bL/FqaIJnjATDbi8ObSELmxg==}
+ engines: {node: '>=22.0.0'}
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ libsql@0.5.29:
+ resolution: {integrity: sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==}
+ cpu: [x64, arm64, wasm32, arm]
+ os: [darwin, linux, win32]
+
+ 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'}
+
+ lilconfig@2.1.0:
+ resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+ engines: {node: '>=10'}
+
+ lilconfig@3.1.4:
+ resolution: {integrity: sha512-zJZyBmQhArDRefuWTypZxwDpFDIYmrj8ypSBvwGD5P13Y95s6DjzKgu4DVdGbeQa5PDEsAOCAPNk4X+QOR006w==}
+ engines: {node: '>=14'}
+
+ linebreak@1.1.0:
+ resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ load-tsconfig@0.2.5:
+ resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ long@5.3.2:
+ resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
+
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
+ loupe@3.2.1:
+ resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
+
+ lru.min@1.1.5:
+ resolution: {integrity: sha512-5J9ysMYUpYIg9RF2vJpy9SinEmSviFSe0GyPpCQ4L5QSkLAgeLXlTAOu2ZwWUU5m+0SBl6gUU1R1ZQB3aKypfA==}
+ engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'}
+
+ lucide-react@1.61.0:
+ resolution: {integrity: sha512-v2SQPPPNjnr+BlhL9Spuzmo5yR+hLkftfuE4E3jaxdNPgSH0hJKPcLJBP7yAta87jQNPsSERS59PJjCJ/CorBA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ magic-string@1.4.4:
+ resolution: {integrity: sha512-jQz9sVhrZuphH4NrAIHSgkDJCluQO7Ioi4KGRLa7aTUjAODQ13hENX0YIytqYE/rIkO485gQG2LeBxJaW53kkQ==}
+
+ markdown-extensions@2.0.0:
+ resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
+ engines: {node: '>=16'}
+
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ mdast-util-find-and-replace@3.0.4:
+ resolution: {integrity: sha512-z4B5c6jrnJ1ltOQemhWYPBSAo6y42Z8Gt2yEgfgNTMcLSU59B8bfj8Z8AnAlJrBGLnqkdAUZ7jdDEqQw3KuipQ==}
+
+ mdast-util-from-markdown@2.1.0:
+ resolution: {integrity: sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
+
+ mdast-util-gfm-strikethrough@2.0.1:
+ resolution: {integrity: sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.1.0:
+ resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
+
+ mdast-util-mdx-expression@2.0.1:
+ resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
+
+ mdast-util-mdx-jsx@3.2.0:
+ resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
+
+ mdast-util-mdx@3.0.0:
+ resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==}
+
+ mdast-util-mdxjs-esm@2.0.1:
+ resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdast-util-to-markdown@2.2.0:
+ resolution: {integrity: sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromark-core-commonmark@2.0.4:
+ resolution: {integrity: sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==}
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.2:
+ resolution: {integrity: sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-extension-mdx-expression@3.0.1:
+ resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==}
+
+ micromark-extension-mdx-jsx@3.0.2:
+ resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==}
+
+ micromark-extension-mdx-md@2.0.0:
+ resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==}
+
+ micromark-extension-mdxjs-esm@3.0.0:
+ resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==}
+
+ micromark-extension-mdxjs@3.0.0:
+ resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-mdx-expression@2.0.3:
+ resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==}
+
+ micromark-factory-space@2.1.0:
+ resolution: {integrity: sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-edit-map@1.0.0:
+ resolution: {integrity: sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-events-to-acorn@2.0.3:
+ resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.3:
+ resolution: {integrity: sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==}
+
+ micromark@4.0.3:
+ resolution: {integrity: sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mikro-orm@7.2.1:
+ resolution: {integrity: sha512-IUUYgO5T+S67sw1Xp5r3vL0JeYnkampUIRJaHG6AzTcjujRbyRUOEc6NVAIsojKdXq9WbWRU0hI6ivUv9qSDLA==}
+ engines: {node: '>= 22.17.0'}
+
+ mime-db@1.33.0:
+ resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-db@1.54.0:
+ resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.18:
+ resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==}
+ engines: {node: '>= 0.6'}
+
+ mimic-fn@2.1.0:
+ resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+ engines: {node: '>=6'}
+
+ miniflare@5.20261012.0-beta:
+ resolution: {integrity: sha512-Cjrs+vHHQ7krLO4HYELYpYBJBuMhcnNZD/Z5z/UcQSnFqWSQY3DhtTCFalXgI1/yO1iK+YrRKK8EYkumrEopxg==}
+ engines: {node: '>=22.0.0'}
+
+ miniflare@5.20261019.1-beta:
+ resolution: {integrity: sha512-1n7MN2UqZnPniyYAqNuV1YEAaja66ozKGVCc5ZTmYQhTubnoAwGLccwb+ZWYLOajuw3pOaJ70u//bZMuURlRew==}
+ engines: {node: '>=22.0.0'}
+
+ minimatch@10.2.6:
+ resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==}
+ engines: {node: 18 || 20 || >=22}
+
+ minimatch@3.1.5:
+ resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minimizer-webpack-plugin@5.13.1:
+ resolution: {integrity: sha512-1mhAfvachWYYOm8tpmany5NLuvP+F2wxZWBSX8DC0uFS2wJpM9q3rWgN9wBooAH9d5V12wX0BjyJe4fMjHMarQ==}
+ engines: {node: '>= 10.13.0'}
+ peerDependencies:
+ '@minify-html/node': '*'
+ '@napi-rs/image': '*'
+ '@swc/core': '*'
+ '@swc/css': '*'
+ '@swc/html': '*'
+ clean-css: '*'
+ cssnano: '*'
+ csso: '*'
+ esbuild: '*'
+ html-minifier-terser: '*'
+ imagemin: '*'
+ lightningcss: '*'
+ postcss: '*'
+ sharp: '*'
+ svgo: '*'
+ uglify-js: '*'
+ webpack: ^5.1.0
+ peerDependenciesMeta:
+ '@minify-html/node':
+ optional: true
+ '@napi-rs/image':
+ optional: true
+ '@swc/core':
+ optional: true
+ '@swc/css':
+ optional: true
+ '@swc/html':
+ optional: true
+ clean-css:
+ optional: true
+ cssnano:
+ optional: true
+ csso:
+ optional: true
+ esbuild:
+ optional: true
+ html-minifier-terser:
+ optional: true
+ imagemin:
+ optional: true
+ lightningcss:
+ optional: true
+ postcss:
+ optional: true
+ sharp:
+ optional: true
+ svgo:
+ optional: true
+ uglify-js:
+ optional: true
+
+ mlly@1.8.2:
+ resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
+
+ motion-dom@14.6.0:
+ resolution: {integrity: sha512-lIojTl9aYSPIkeOOSzBliy1nNvpdO3JtVzW2WgTXQlOP4ZMuJhtWO3fP7OD4TVFwlRucdvxlDSMkL+fEQnQ52A==}
+
+ motion-utils@14.6.0:
+ resolution: {integrity: sha512-bZJo2AmQ2aOFkaato6VXrTbkPG0XhMzivWUWSaI59pxyllj8QMQUFZ84MYRQnPkK+7dr4KldyJwF2+RM0sdq/w==}
+
+ motion@14.6.0:
+ resolution: {integrity: sha512-qqaZbyubgk7x3zxjPgP1l3Br/KQXol/IIV1uqb358SoN4ApcqNuV7+wyDPg/XLErmuyQL5lL8JVI/fOmDsmBKQ==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
+ ms@2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mute-stream@2.0.0:
+ resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ mysql2@3.24.4:
+ resolution: {integrity: sha512-A2olluVlj0mvgyIRRISMEzXc51m+21mRtcMVjJyIpt2GG98+XrC9m9HzsqcMsX2LcnfccJvY5NB22g8fENBnOA==}
+ engines: {node: '>= 8.0'}
+ peerDependencies:
+ '@types/node': '>= 8'
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ named-placeholders@1.1.6:
+ resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==}
+ engines: {node: '>=8.0.0'}
+
+ nanoid@3.3.20:
+ resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ nanostores@1.5.5:
+ resolution: {integrity: sha512-FixtE239Gl6Gz0ZGCK0WzvNwObNCIwVT+L7zQcf1QgcA6AzBxblzqe9OT88qiucNkhsjSOqiogSaF5jVbJiqSA==}
+ engines: {node: ^20.0.0 || >=22.0.0}
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ negotiator@0.6.4:
+ resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==}
+ engines: {node: '>= 0.6'}
+
+ neo-async@2.6.2:
+ resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+
+ next-themes@0.4.6:
+ resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
+ peerDependencies:
+ react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+
+ next@14.2.35:
+ resolution: {integrity: sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==}
+ engines: {node: '>=18.17.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.41.2
+ '@types/react': '*'
+ react: ^18.2.0
+ react-dom: ^18.2.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ sass:
+ optional: true
+
+ next@16.4.2:
+ resolution: {integrity: sha512-r+oBJojfefUjOiWkBhXgLS+igxX/7BWyK59uHnyOyplMSLtBZ+QLP3okrdYTbrfrbrmNTVWLBPaHDX9KRaIt3w==}
+ engines: {node: '>=20.9.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
+ node-addon-api@8.9.2:
+ resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==}
+ engines: {node: ^18 || ^20 || >= 21}
+
+ node-releases@2.0.60:
+ resolution: {integrity: sha512-OmO8+GM1JUZqXET720VrJCwkjUCXmCMQm0Z3UDDRbfNLHS4NEAvY60j5jiFv0tkKw2PNNlqOLhahVmwJIOLDIQ==}
+ engines: {node: '>=18'}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ normalize-range@0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+
+ npm-run-path@4.0.1:
+ resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
+ engines: {node: '>=8'}
+
+ npm-to-yarn@3.2.0:
+ resolution: {integrity: sha512-K1HmQeZT2HrjpsR6KgqbN2FAXL2NrJJmNUSD9ck7HGTVu1JKXox8n9SB+tjbU8m8JGLF4OscrroPepew/L7/Xw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
+ obug@3.0.0:
+ resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==}
+ engines: {node: '>=12.20.0'}
+
+ on-headers@1.1.0:
+ resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==}
+ engines: {node: '>= 0.8'}
+
+ onetime@5.1.2:
+ resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+ engines: {node: '>=6'}
+
+ oniguruma-parser@0.12.2:
+ resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==}
+
+ oniguruma-to-es@4.3.6:
+ resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ pako@0.2.9:
+ resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
+
+ parse-css-color@0.2.1:
+ resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==}
+
+ parse-entities@4.0.2:
+ resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-is-inside@1.0.2:
+ resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-to-regexp@3.3.0:
+ resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==}
+
+ path-to-regexp@6.3.0:
+ resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ pathval@2.0.1:
+ resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
+ engines: {node: '>= 14.16'}
+
+ pg-cloudflare@1.4.1:
+ resolution: {integrity: sha512-6PQbsFWZcp9EmJEwy5cGQ2La+AMWpP46lgbb8X+U/XsHIUweYDNCpeuKck5RxL2MdVFi7krbbEi5nX4Zh7JhrQ==}
+
+ pg-connection-string@2.14.1:
+ resolution: {integrity: sha512-qR3kGNPBLpCNtz0evbKA0Y/MRFXwSSdT+pTJvYp/bXTcReZbvX1kzF0IyTc1QnxqF7AZbOeBhNL8R5mYQZV/MA==}
+
+ pg-cursor@2.22.0:
+ resolution: {integrity: sha512-knzXLKqarTjOvb3qDSW0JiGsazmxwEKXrqHfWRte7XUsOYccQRafn3BLnQobWwInkzFJSyOej8y8cQRh2z3kGw==}
+ peerDependencies:
+ pg: ^8
+
+ pg-int8@1.0.1:
+ resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
+ engines: {node: '>=4.0.0'}
+
+ pg-pool@3.14.0:
+ resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==}
+ peerDependencies:
+ pg: '>=8.0'
+
+ pg-protocol@1.16.1:
+ resolution: {integrity: sha512-p9VOFMiHB/ZbJATetbg+99PxssTVSQRnyuPSQ67mN1+1KBOjZaZ83ZQzltnxPhJwSsC3nwVjJ10DVJlerbFzLg==}
+
+ pg-types@2.2.0:
+ resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
+ engines: {node: '>=4'}
+
+ pg@8.23.0:
+ resolution: {integrity: sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==}
+ engines: {node: '>= 16.0.0'}
+ peerDependencies:
+ pg-native: '>=3.0.1'
+ peerDependenciesMeta:
+ pg-native:
+ optional: true
+
+ pgpass@1.0.5:
+ resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.2:
+ resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.7:
+ resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
+ engines: {node: '>=12'}
+
+ pirates@4.0.7:
+ resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
+ engines: {node: '>= 6'}
+
+ pkg-types@1.3.1:
+ resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+
+ playwright-core@1.64.1:
+ resolution: {integrity: sha512-BC4s8y6SEVA6Q1rSxZTto8hI1KUI3xXlHGZgvGqP4IqPdI/a6FX9H29IDNz7vKo9l21b6LfYosScPL6M3xxyDQ==}
+ engines: {node: '>=20'}
+ hasBin: true
+
+ playwright@1.64.1:
+ resolution: {integrity: sha512-HCrVhHr5QQuwYoswEUGTb7gGp522yflbv/ST8nF4sFWGuLjQCt17Q/EubpGGSNKYn1tsTCPZxqHhHCfVURu7UA==}
+ engines: {node: '>=20'}
+ hasBin: true
+
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.1.0:
+ resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
+ postcss-load-config@4.0.2:
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+
+ postcss-load-config@6.0.1:
+ resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ jiti: '>=1.21.0'
+ postcss: '>=8.0.9'
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+ postcss:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.5:
+ resolution: {integrity: sha512-TEHFzb5KRDKaOgJ4TYE+0jyJtFbjLvkdVOu0fZ2b6MTWzoqZd4Le+61aEppWkvTlYePgOX4ATL1wsAIPMLTw6Q==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.4.39:
+ resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.5.23:
+ resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.5.32:
+ resolution: {integrity: sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postgres-array@2.0.0:
+ resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
+ engines: {node: '>=4'}
+
+ postgres-array@3.0.4:
+ resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==}
+ engines: {node: '>=12'}
+
+ postgres-bytea@1.0.1:
+ resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-date@1.0.7:
+ resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-date@2.1.0:
+ resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==}
+ engines: {node: '>=12'}
+
+ postgres-interval@1.2.0:
+ resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-interval@4.1.0:
+ resolution: {integrity: sha512-nJLACcOHi2iyRuMJeW6CuIA0Dc0i1YEpRr26XDyHAfxPjYUJOFxwZjmOc5oFFctTTh/OlRAMlnlXEJvr170fJg==}
+ engines: {node: '>=12'}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ prettier-plugin-tailwindcss@0.6.14:
+ resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==}
+ engines: {node: '>=14.21.3'}
+ peerDependencies:
+ '@ianvs/prettier-plugin-sort-imports': '*'
+ '@prettier/plugin-hermes': '*'
+ '@prettier/plugin-oxc': '*'
+ '@prettier/plugin-pug': '*'
+ '@shopify/prettier-plugin-liquid': '*'
+ '@trivago/prettier-plugin-sort-imports': '*'
+ '@zackad/prettier-plugin-twig': '*'
+ prettier: ^3.0
+ prettier-plugin-astro: '*'
+ prettier-plugin-css-order: '*'
+ prettier-plugin-import-sort: '*'
+ prettier-plugin-jsdoc: '*'
+ prettier-plugin-marko: '*'
+ prettier-plugin-multiline-arrays: '*'
+ prettier-plugin-organize-attributes: '*'
+ prettier-plugin-organize-imports: '*'
+ prettier-plugin-sort-imports: '*'
+ prettier-plugin-style-order: '*'
+ prettier-plugin-svelte: '*'
+ peerDependenciesMeta:
+ '@ianvs/prettier-plugin-sort-imports':
+ optional: true
+ '@prettier/plugin-hermes':
+ optional: true
+ '@prettier/plugin-oxc':
+ optional: true
+ '@prettier/plugin-pug':
+ optional: true
+ '@shopify/prettier-plugin-liquid':
+ optional: true
+ '@trivago/prettier-plugin-sort-imports':
+ optional: true
+ '@zackad/prettier-plugin-twig':
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+ prettier-plugin-css-order:
+ optional: true
+ prettier-plugin-import-sort:
+ optional: true
+ prettier-plugin-jsdoc:
+ optional: true
+ prettier-plugin-marko:
+ optional: true
+ prettier-plugin-multiline-arrays:
+ optional: true
+ prettier-plugin-organize-attributes:
+ optional: true
+ prettier-plugin-organize-imports:
+ optional: true
+ prettier-plugin-sort-imports:
+ optional: true
+ prettier-plugin-style-order:
+ optional: true
+ prettier-plugin-svelte:
+ optional: true
+
+ prettier@3.9.10:
+ resolution: {integrity: sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ promise-limit@2.7.0:
+ resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==}
+
+ property-information@7.2.0:
+ resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ qified@0.10.1:
+ resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==}
+ engines: {node: '>=20'}
+
+ qrcode.react@4.2.0:
+ resolution: {integrity: sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ range-parser@1.2.0:
+ resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==}
+ engines: {node: '>= 0.6'}
+
+ rc@1.2.8:
+ resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
+ hasBin: true
+
+ react-dom@18.3.1:
+ resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
+ peerDependencies:
+ react: ^18.3.1
+
+ react-dom@19.3.1:
+ resolution: {integrity: sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==}
+ peerDependencies:
+ react: ^19.3.1
+
+ react-hook-form@7.52.1:
+ resolution: {integrity: sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==}
+ engines: {node: '>=12.22.0'}
+ peerDependencies:
+ react: ^16.8.0 || ^17 || ^18 || ^19
+
+ react-remove-scroll-bar@2.3.8:
+ resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.5.5:
+ resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.7.2:
+ resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-server-dom-webpack@19.3.1:
+ resolution: {integrity: sha512-I1Smf6Yc+389rFWPwyYjvCQVK1XFWpb2M9gvgYgfpbZ+LPqkZtb0tT9Fwdk0K+wknK2E+ns82lC0DCYLnXCVGA==}
+ engines: {node: '>=0.10.0'}
+ peerDependencies:
+ react: ^19.3.1
+ react-dom: ^19.3.1
+ webpack: ^5.59.0
+
+ react-style-singleton@2.2.3:
+ resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react@18.3.1:
+ resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
+ engines: {node: '>=0.10.0'}
+
+ react@19.3.1:
+ resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==}
+ engines: {node: '>=0.10.0'}
+
+ read-cache@1.0.2:
+ resolution: {integrity: sha512-/peqiBB/n07gQGLsWaHho3WfvUyRscw0gYTsEFMhrIe/nWLkYaf5SbKYjGYqtRV3aPwykJgF2VEMo1ac4bnsGA==}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ readdirp@5.1.1:
+ resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==}
+ engines: {node: '>= 20.19.0'}
+
+ recma-build-jsx@1.0.0:
+ resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==}
+
+ recma-jsx@1.0.1:
+ resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ recma-parse@1.0.0:
+ resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==}
+
+ recma-stringify@1.0.0:
+ resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==}
+
+ regex-recursion@6.0.2:
+ resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
+
+ regex-utilities@2.3.0:
+ resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
+
+ regex@6.1.0:
+ resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
+
+ registry-auth-token@3.3.2:
+ resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==}
+
+ registry-url@3.1.0:
+ resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==}
+ engines: {node: '>=0.10.0'}
+
+ rehype-recma@1.0.0:
+ resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==}
+
+ remark-gfm@4.0.1:
+ resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
+
+ remark-mdx@3.1.1:
+ resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
+ remark@15.0.1:
+ resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ reselect@5.3.0:
+ resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==}
+
+ resolve-from@5.0.0:
+ resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
+ engines: {node: '>=8'}
+
+ resolve@1.22.13:
+ resolution: {integrity: sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rolldown@1.2.15:
+ resolution: {integrity: sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+
+ rollup@4.65.1:
+ resolution: {integrity: sha512-HzD4IdphaPMvuAacnL/vtoq5B8FwqewKvxTtqYibWvP6VDyZ+UsTtlw5F8HIOIIpLQAkN2NOP/0sM3puo9xN/A==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ rou3@0.9.2:
+ resolution: {integrity: sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==}
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ satori@0.33.5:
+ resolution: {integrity: sha512-PNW6ktrQ8SM6kk7u4aOuTkkUewkzyTOrj+QeEzXSsnNMAdff4ire9CAqIz8+4C3rCiBtK8QTELv52AZEd1PbRw==}
+ engines: {node: '>=16'}
+
+ scheduler@0.23.2:
+ resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
+
+ scheduler@0.28.0:
+ resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==}
+
+ schema-utils@4.8.1:
+ resolution: {integrity: sha512-x39pYlJPyH7Uge5QO64B9XGP9zLDc9WNmiQZc+CE3IzZPvMu3lHOuAMGpYNoPixEL7MSWlGhYTg5UlLSL8G6iw==}
+ engines: {node: '>= 10.13.0'}
+ hasBin: true
+ peerDependencies:
+ webpack: ^5.112.0
+ peerDependenciesMeta:
+ webpack:
+ optional: true
+
+ scroll-into-view-if-needed@3.1.0:
+ resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==}
+
+ sdp@3.2.2:
+ resolution: {integrity: sha512-xZocWwfyp4hkbN4hLWxMjmv2Q8aNa9MhmOZ7L9aCZPT+dZsgRr6wZRrSYE3HTdyk/2pZKPSgqI7ns7Een1xMSA==}
+
+ semver@7.8.5:
+ resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ serve-handler@6.1.7:
+ resolution: {integrity: sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==}
+
+ serve@14.2.6:
+ resolution: {integrity: sha512-QEjUSA+sD4Rotm1znR8s50YqA3kYpRGPmtd5GlFxbaL9n/FdUNbqMhxClqdditSk0LlZyA/dhud6XNRTOC9x2Q==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+ set-cookie-parser@3.2.1:
+ resolution: {integrity: sha512-Npd1Pt+4zb3BrSZDPd2qFwRpS6b1EUEasRrO8xS0zMJi0fApXXK5YuzP0minyJnxwnFHoVoJwA55q0A0cu63gQ==}
+
+ sharp@0.35.5:
+ resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==}
+ engines: {node: '>=20.9.0'}
+ peerDependencies:
+ '@types/node': '*'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ shiki@4.5.0:
+ resolution: {integrity: sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==}
+ engines: {node: '>=20'}
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ signal-exit@3.0.7:
+ resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ sonner@1.7.4:
+ resolution: {integrity: sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+
+ source-map-js@1.2.2:
+ resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
+ engines: {node: '>=0.10.0'}
+
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.7.6:
+ resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
+ engines: {node: '>= 12'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ split2@4.2.0:
+ resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
+ engines: {node: '>= 10.x'}
+
+ sql-escaper@1.5.2:
+ resolution: {integrity: sha512-6CKD38c31SENivxOADeMNLdukOnUxUcflKtzVWzace7Riv1v7cAEym5Cx9Q7gYZ3ezIJI7ZpqecQq8cqNeSSFg==}
+ engines: {bun: '>=1.0.0', deno: '>=2.0.0', node: '>=12.0.0'}
+
+ sqlstring@2.3.3:
+ resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==}
+ engines: {node: '>= 0.6'}
+
+ srvx@1.0.7:
+ resolution: {integrity: sha512-8h30Qy2cpYkcXgByHNpV4+jp609bU3ic7MqnfyLQ2Fpa8BgjIaI2zfsDKAIbwm8DcYDrCLqm5izF5KeL2nxdvg==}
+ engines: {node: '>=20.16.0'}
+ hasBin: true
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@3.10.0:
+ resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
+
+ streamsearch@1.1.0:
+ resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
+ engines: {node: '>=10.0.0'}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ string.prototype.codepointat@0.2.1:
+ resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.2.0:
+ resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
+ engines: {node: '>=12'}
+
+ strip-final-newline@2.0.0:
+ resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
+ engines: {node: '>=6'}
+
+ strip-json-comments@2.0.1:
+ resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
+ engines: {node: '>=0.10.0'}
+
+ strip-literal@3.1.0:
+ resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
+
+ strip-literal@4.0.0:
+ resolution: {integrity: sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==}
+
+ style-to-js@1.1.21:
+ resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
+
+ style-to-object@1.0.14:
+ resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
+
+ styled-jsx@5.1.1:
+ resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ sucrase@3.35.1:
+ resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ supports-color@10.2.2:
+ resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
+ engines: {node: '>=18'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ tagged-tag@1.0.0:
+ resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
+ engines: {node: '>=20'}
+
+ tailwind-merge@2.6.1:
+ resolution: {integrity: sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==}
+
+ tailwindcss-animate@1.0.7:
+ resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders'
+
+ tailwindcss@3.4.6:
+ resolution: {integrity: sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ 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'}
+
+ terser@5.51.2:
+ resolution: {integrity: sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ tiny-inflate@1.0.3:
+ resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@0.3.2:
+ resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+ tinyexec@1.3.1:
+ resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ tinypool@1.1.1:
+ resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+
+ tinyrainbow@2.0.0:
+ resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
+ engines: {node: '>=14.0.0'}
+
+ tinyspy@4.0.6:
+ resolution: {integrity: sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==}
+ engines: {node: '>=14.0.0'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
+ hasBin: true
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tsup@8.5.1:
+ resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==}
+ engines: {node: '>=18'}
+ hasBin: true
+ peerDependencies:
+ '@microsoft/api-extractor': ^7.36.0
+ '@swc/core': ^1
+ postcss: ^8.4.12
+ typescript: '>=4.5.0'
+ peerDependenciesMeta:
+ '@microsoft/api-extractor':
+ optional: true
+ '@swc/core':
+ optional: true
+ postcss:
+ optional: true
+ typescript:
+ optional: true
+
+ turbo-stream@3.2.1:
+ resolution: {integrity: sha512-BaX0eWz3IrypOVDFqPv3VGD6uZZW8y3oFAOJqZQ+oopmOyQ8/xNm7IMwAJFvxax2DBa8zSk+/AeqA6D6b1PXGg==}
+
+ turbo@2.11.10:
+ resolution: {integrity: sha512-3GJYwig8ygEI89oaOZdduJX8/aw6O9eRPYHoIt6T3FZl9hkKjiyIspufJoVgqXihPoJu8M5CSV0DlZvzfohBCw==}
+ hasBin: true
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ type-fest@2.19.0:
+ resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
+ engines: {node: '>=12.20'}
+
+ type-fest@5.10.0:
+ resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==}
+ engines: {node: '>=20'}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ typescript@7.0.2:
+ resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==}
+ engines: {node: '>=16.20.0'}
+ hasBin: true
+
+ ufo@1.6.4:
+ resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
+
+ undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+ undici-types@8.9.0:
+ resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==}
+
+ undici@7.29.1:
+ resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==}
+ engines: {node: '>=20.18.1'}
+
+ unenv@2.0.0-rc.24:
+ resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==}
+
+ unicode-trie@2.0.0:
+ resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==}
+
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-position-from-estree@2.0.0:
+ resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-remove-position@5.0.0:
+ resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.1.0:
+ resolution: {integrity: sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w==}
+
+ unist-util-visit@5.2.0:
+ resolution: {integrity: sha512-fpsYs/VVoZxfGY9/j3FQpZmN8wdLJaV1Pt38AaJNZu9uKIHcFU3halCdBveEq1HGKO1OEfJY65w1zvoFV1b3qQ==}
+
+ unpic@4.2.2:
+ resolution: {integrity: sha512-z6T2ScMgRV2y2H8MwwhY5xHZWXhUx/YxtOCGJwfURSl7ypVy4HpLIMWoIZKnnxQa/RKzM0kg8hUh0paIrpLfvw==}
+
+ update-browserslist-db@1.3.4:
+ resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ update-check@1.5.4:
+ resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==}
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ use-callback-ref@1.3.3:
+ resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sidecar@1.1.3:
+ resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sync-external-store@1.7.0:
+ resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ vary@1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vinext@1.2.1:
+ resolution: {integrity: sha512-cB8ViQ4JuxoM2jcsvEB2kdVNSm4zWfNgpYU8Bx6781mRuArlgDsI0Y4w5EqQwkK8e3BzMMHeOreiUbMc8xLLiA==}
+ engines: {node: '>=22'}
+ hasBin: true
+ peerDependencies:
+ '@mdx-js/rollup': ^3.0.0
+ '@vitejs/plugin-react': ^5.1.4 || ^6.0.0
+ '@vitejs/plugin-rsc': ^0.5.37
+ react: ^19.3.1
+ react-dom: ^19.3.1
+ react-server-dom-webpack: ^19.3.1
+ vite: ^8.0.0
+ peerDependenciesMeta:
+ '@mdx-js/rollup':
+ optional: true
+ '@vitejs/plugin-rsc':
+ optional: true
+ react-server-dom-webpack:
+ optional: true
+
+ vite-node@3.2.4:
+ resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+
+ vite-plugin-commonjs@0.10.4:
+ resolution: {integrity: sha512-eWQuvQKCcx0QYB5e5xfxBNjQKyrjEWZIR9UOkOV6JAgxVhtbZvCOF+FNC2ZijBJ3U3Px04ZMMyyMyFBVWIJ5+g==}
+
+ vite-plugin-dynamic-import@1.6.0:
+ resolution: {integrity: sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg==}
+
+ vite@7.3.7:
+ resolution: {integrity: sha512-AHEzTORMbi7/7aXp7w7KZ5+DCUdSeLsJz0grY8xHpc9DHdYb0vQu6DqJfm2tOw3gDExNgPgnJTXxM6syYFHaCA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.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
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vite@8.3.4:
+ resolution: {integrity: sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ '@vitejs/devtools': ^0.7.1
+ 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
+
+ vitest@3.2.7:
+ resolution: {integrity: sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@types/debug': ^4.1.12
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ '@vitest/browser': 3.2.7
+ '@vitest/ui': 3.2.7
+ happy-dom: '*'
+ jsdom: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@types/debug':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ watchpack@2.6.3:
+ resolution: {integrity: sha512-s3NZy0QpTY9qGqzc0wtz4qI28z3+5qKbbAec4MV4G9N3CfgZ9wgvQRr0cl2jh/tqkWG1NWHkmVMHZpCamev5Wg==}
+ engines: {node: '>=10.13.0'}
+
+ web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+
+ web-vitals@4.2.4:
+ resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==}
+
+ webpack-sources@3.6.0:
+ resolution: {integrity: sha512-EIMmPVvNI0CYXyRPp34F2Qk7W37/BZVZIofS6LAUnrNjCVahS+hO4mxwFJDjQjODTGZDtVzLYoN2+1dYkhk9qA==}
+ engines: {node: '>=10.13.0'}
+
+ webpack@5.112.2:
+ resolution: {integrity: sha512-B2tp1LI9D8GVpPDqprdt12ukTkXXahj9MzqSWJq4faSPgOUM7CdZaGAB6HrL/8E6UwbBpdj4vzWDbKoFnVoU6g==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ peerDependencies:
+ webpack-cli: '*'
+ peerDependenciesMeta:
+ webpack-cli:
+ optional: true
+
+ webrtc-adapter@9.0.6:
+ resolution: {integrity: sha512-CHbl2ZQbxx164IgWRgzJno4hWtM4tFbRam1QfI3Yxhs3w/DvqluVxVWeXs3oL5/fbGkSNLKo0Ty5MgUWceNhog==}
+ engines: {node: '>=6.0.0', npm: '>=3.10.0'}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ widest-line@4.0.1:
+ resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==}
+ engines: {node: '>=12'}
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ workerd@1.20261012.1:
+ resolution: {integrity: sha512-tEHoMPsMga0seVjxfsR8Pd3f8IRqYwkq++dTUKI5Gdgj6zuSDluYwisydq+dn90SsIACwBquJUQ1nBpcOqaWTA==}
+ engines: {node: '>=16'}
+ hasBin: true
+
+ workerd@1.20261019.1:
+ resolution: {integrity: sha512-UUYRUq/7DmeCl11YriNbcVbjUZVLtt8uuCXFu+nz77hGFf8d4DEVXoCYtnA+MlBatE4+wxoj47DVqzK3xGBAiw==}
+ engines: {node: '>=16'}
+ hasBin: true
+
+ wrangler@4.151.3:
+ resolution: {integrity: sha512-mzPQLmkAhZUV7CdiAhE+hiIAJlS9xPL6vZe1B8oQFuWxFu7nmQnvHAVjcAcabwSGkXFXH9uspzXwHOFrfbQmqQ==}
+ engines: {node: '>=22.0.0'}
+ hasBin: true
+ peerDependencies:
+ '@cloudflare/workers-types': ^5.20261019.1
+ peerDependenciesMeta:
+ '@cloudflare/workers-types':
+ optional: true
+
+ wrap-ansi@6.2.0:
+ resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
+ engines: {node: '>=8'}
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ ws@8.21.0:
+ resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ ws@8.22.0:
+ resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ xtend@4.0.2:
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+ engines: {node: '>=0.4'}
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yaml@2.9.1:
+ resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ yoctocolors-cjs@2.1.3:
+ resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==}
+ engines: {node: '>=18'}
+
+ yoga-layout@3.2.1:
+ resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==}
+
+ youch-core@0.3.3:
+ resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==}
+
+ youch@4.1.0-beta.10:
+ resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==}
+
+ yuku-analyzer@0.19.0:
+ resolution: {integrity: sha512-Iu7DV5cWOQ3ERSA7oBquz/RT5IEGsUyUeCivYs9lQaZ4nSjM31yD17mH616JKcTyVoVWYivsFZ+twT3UyBosTA==}
+ engines: {node: '>=14.18.0'}
+
+ yuku-ast@0.19.0:
+ resolution: {integrity: sha512-PyCsiScaelhxBGzL8dyeJkLqvRZycoh78R31Vrt/WqYrm0hMFoKwIw/X7Dx5mBKLWAMlV9I9HEyBOHnj2gZVyw==}
+ engines: {node: '>=14.18.0'}
+
+ yuku-core@0.19.0:
+ resolution: {integrity: sha512-kYK9e1XdfirNhkipzW0wmMcSWcVF/CWnuugodfVYRCUwvoBefweL9HzB96OiKEhsx78V5WbUxbJqlizMX869Qg==}
+ engines: {node: '>=14.18.0'}
+
+ zbsearch@4.0.1:
+ resolution: {integrity: sha512-lmnEEnb93QQcNv7qARDr7jBVPxYdZbZ9XdZ0dbZ0qaOvGne4jJMW4fjwPfVaUKQXv3FNWvGbDwRDgyaSb1pc8w==}
+ engines: {node: '>= 20.0.0'}
+
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+ zod@4.6.7:
+ resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==}
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+ zxing-wasm@3.1.6:
+ resolution: {integrity: sha512-mU7UNuvl+hOT+nlSOQTMHZ2tM8lRMsbjDIp5IO/+HmBl/FOq77q0OSZPJ3cm42A9c1MKU6Uve67FiGdkhsrT9g==}
+ peerDependencies:
+ '@types/emscripten': '>=1.39.6'
+
+snapshots:
+
+ '@a77ay/better-auth-mikro-orm@0.1.1(@mikro-orm/core@7.2.1)(better-auth@1.7.6(mysql2@3.24.4(@types/node@20.14.11))(next@16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)))':
+ dependencies:
+ '@mikro-orm/core': 7.2.1
+ better-auth: 1.7.6(mysql2@3.24.4(@types/node@20.14.11))(next@16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1))
+ jiti: 2.7.0
+
+ '@alloc/quick-lru@5.3.0': {}
+
+ '@aws-sdk/checksums@3.1001.6':
+ dependencies:
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/credential-provider-env@3.744.0:
- resolution: {integrity: sha512-hyjC7xqzAeERorYYjhQG1ivcr1XlxgfBpa+r4pG29toFG60mACyVzaR7+og3kgzjRFAB7D1imMxPQyEvQ1QokA==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/client-s3@3.1157.0':
+ dependencies:
+ '@aws-sdk/checksums': 3.1001.6
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/credential-provider-node': 3.972.89
+ '@aws-sdk/middleware-sdk-s3': 3.972.82
+ '@aws-sdk/signature-v4-multi-region': 3.996.49
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/fetch-http-handler': 5.8.0
+ '@smithy/node-http-handler': 4.13.0
+ '@smithy/types': 4.19.0
+ tslib: 2.8.1
+
+ '@aws-sdk/core@3.978.6':
dependencies:
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/property-provider': 4.4.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/types': 3.975.0
+ '@aws-sdk/xml-builder': 3.972.41
+ '@aws/lambda-invoke-store': 0.3.0
+ '@smithy/core': 3.37.0
+ '@smithy/signature-v4': 5.7.4
+ '@smithy/types': 4.19.0
+ bowser: 2.15.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/credential-provider-http@3.744.0:
- resolution: {integrity: sha512-k+P1Tl5ewBvVByR6hB726qFIzANgQVf2cY87hZ/e09pQYlH4bfBcyY16VJhkqYnKmv6HMdWxKHX7D8nwlc8Obg==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/credential-provider-env@3.972.77':
dependencies:
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/fetch-http-handler': 5.6.5
- '@smithy/node-http-handler': 4.9.5
- '@smithy/property-provider': 4.4.8
- '@smithy/protocol-http': 5.5.8
- '@smithy/smithy-client': 4.14.8
- '@smithy/types': 4.16.1
- '@smithy/util-stream': 4.7.8
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/credential-provider-ini@3.744.0:
- resolution: {integrity: sha512-hjEWgkF86tkvg8PIsDiB3KkTj7z8ZFGR0v0OLQYD47o17q1qfoMzZmg9wae3wXp9KzU+lZETo+8oMqX9a+7aVQ==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/credential-provider-http@3.972.79':
dependencies:
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/credential-provider-env': 3.744.0
- '@aws-sdk/credential-provider-http': 3.744.0
- '@aws-sdk/credential-provider-process': 3.744.0
- '@aws-sdk/credential-provider-sso': 3.744.0
- '@aws-sdk/credential-provider-web-identity': 3.744.0
- '@aws-sdk/nested-clients': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/credential-provider-imds': 4.4.8
- '@smithy/property-provider': 4.4.8
- '@smithy/shared-ini-file-loader': 4.6.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/fetch-http-handler': 5.8.0
+ '@smithy/node-http-handler': 4.13.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
- /@aws-sdk/credential-provider-node@3.744.0:
- resolution: {integrity: sha512-4oUfRd6pe/VGmKoav17pPoOO0WP0L6YXmHqtJHSDmFUOAa+Vh0ZRljTj/yBdleRgdO6rOfdWqoGLFSFiAZDrsQ==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/credential-provider-ini@3.973.22':
+ dependencies:
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/credential-provider-env': 3.972.77
+ '@aws-sdk/credential-provider-http': 3.972.79
+ '@aws-sdk/credential-provider-login': 3.972.84
+ '@aws-sdk/credential-provider-process': 3.972.77
+ '@aws-sdk/credential-provider-sso': 3.973.21
+ '@aws-sdk/credential-provider-web-identity': 3.972.83
+ '@aws-sdk/nested-clients': 3.997.51
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/credential-provider-imds': 4.5.2
+ '@smithy/types': 4.19.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-login@3.972.84':
dependencies:
- '@aws-sdk/credential-provider-env': 3.744.0
- '@aws-sdk/credential-provider-http': 3.744.0
- '@aws-sdk/credential-provider-ini': 3.744.0
- '@aws-sdk/credential-provider-process': 3.744.0
- '@aws-sdk/credential-provider-sso': 3.744.0
- '@aws-sdk/credential-provider-web-identity': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/credential-provider-imds': 4.4.8
- '@smithy/property-provider': 4.4.8
- '@smithy/shared-ini-file-loader': 4.6.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/nested-clients': 3.997.51
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
- /@aws-sdk/credential-provider-process@3.744.0:
- resolution: {integrity: sha512-m0d/pDBIaiEAAxWXt/c79RHsKkUkyPOvF2SAMRddVhhOt1GFZI4ml+3f4drmAZfXldIyJmvJTJJqWluVPwTIqQ==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/credential-provider-node@3.972.89':
+ dependencies:
+ '@aws-sdk/credential-provider-env': 3.972.77
+ '@aws-sdk/credential-provider-http': 3.972.79
+ '@aws-sdk/credential-provider-ini': 3.973.22
+ '@aws-sdk/credential-provider-process': 3.972.77
+ '@aws-sdk/credential-provider-sso': 3.973.21
+ '@aws-sdk/credential-provider-web-identity': 3.972.83
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/credential-provider-imds': 4.5.2
+ '@smithy/types': 4.19.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-process@3.972.77':
dependencies:
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/property-provider': 4.4.8
- '@smithy/shared-ini-file-loader': 4.6.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/credential-provider-sso@3.744.0:
- resolution: {integrity: sha512-xdMufTZOvpbDoDPI2XLu0/Rg3qJ/txpS8IJR63NsCGotHJZ/ucLNKwTcGS40hllZB8qSHTlvmlOzElDahTtx/A==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/credential-provider-sso@3.973.21':
dependencies:
- '@aws-sdk/client-sso': 3.744.0
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/token-providers': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/property-provider': 4.4.8
- '@smithy/shared-ini-file-loader': 4.6.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/nested-clients': 3.997.51
+ '@aws-sdk/token-providers': 3.1157.0
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
- /@aws-sdk/credential-provider-web-identity@3.744.0:
- resolution: {integrity: sha512-cNk93GZxORzqEojWfXdrPBF6a7Nu3LpPCWG5mV+lH2tbuGsmw6XhKkwpt7o+OiIP4tKCpHlvqOD8f1nmhe1KDA==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/credential-provider-web-identity@3.972.83':
dependencies:
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/nested-clients': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/property-provider': 4.4.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/nested-clients': 3.997.51
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
- /@aws-sdk/middleware-bucket-endpoint@3.734.0:
- resolution: {integrity: sha512-etC7G18aF7KdZguW27GE/wpbrNmYLVT755EsFc8kXpZj8D6AFKxc7OuveinJmiy0bYXAMspJUWsF6CrGpOw6CQ==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/middleware-sdk-s3@3.972.82':
dependencies:
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-arn-parser': 3.723.0
- '@smithy/node-config-provider': 4.5.8
- '@smithy/protocol-http': 5.5.8
- '@smithy/types': 4.16.1
- '@smithy/util-config-provider': 4.4.8
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/signature-v4-multi-region': 3.996.49
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/middleware-expect-continue@3.734.0:
- resolution: {integrity: sha512-P38/v1l6HjuB2aFUewt7ueAW5IvKkFcv5dalPtbMGRhLeyivBOHwbCyuRKgVs7z7ClTpu9EaViEGki2jEQqEsQ==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/nested-clients@3.997.51':
dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/protocol-http': 5.5.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/signature-v4-multi-region': 3.996.49
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/fetch-http-handler': 5.8.0
+ '@smithy/node-http-handler': 4.13.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/middleware-flexible-checksums@3.744.0:
- resolution: {integrity: sha512-4AuBdvkwfwagZQt3kt1b0x2dtC54cOrN5gt96V2b4wIjHBRxB/IfAyynahOgx3fd7Zjf74xwmxasjs7iJ8yglg==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/s3-request-presigner@3.1157.0':
dependencies:
- '@aws-crypto/crc32': 5.2.0
- '@aws-crypto/crc32c': 5.2.0
- '@aws-crypto/util': 5.2.0
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/is-array-buffer': 4.4.8
- '@smithy/node-config-provider': 4.5.8
- '@smithy/protocol-http': 5.5.8
- '@smithy/types': 4.16.1
- '@smithy/util-middleware': 4.4.8
- '@smithy/util-stream': 4.7.8
- '@smithy/util-utf8': 4.4.8
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/signature-v4-multi-region': 3.996.49
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/middleware-host-header@3.734.0:
- resolution: {integrity: sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/signature-v4-multi-region@3.996.49':
dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/protocol-http': 5.5.8
- '@smithy/types': 4.16.1
+ '@aws-sdk/types': 3.975.0
+ '@smithy/signature-v4': 5.7.4
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@aws-sdk/middleware-location-constraint@3.734.0:
- resolution: {integrity: sha512-EJEIXwCQhto/cBfHdm3ZOeLxd2NlJD+X2F+ZTOxzokuhBtY0IONfC/91hOo5tWQweerojwshSMHRCKzRv1tlwg==}
- engines: {node: '>=18.0.0'}
+ '@aws-sdk/token-providers@3.1157.0':
+ dependencies:
+ '@aws-sdk/core': 3.978.6
+ '@aws-sdk/nested-clients': 3.997.51
+ '@aws-sdk/types': 3.975.0
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
+ tslib: 2.8.1
+
+ '@aws-sdk/types@3.975.0':
+ dependencies:
+ '@smithy/types': 4.19.0
+ tslib: 2.8.1
+
+ '@aws-sdk/xml-builder@3.972.41':
+ dependencies:
+ '@smithy/types': 4.19.0
+ tslib: 2.8.1
+
+ '@aws/lambda-invoke-store@0.3.0': {}
+
+ '@babel/runtime@7.29.10': {}
+
+ '@babel/runtime@8.0.8': {}
+
+ '@base-ui/react@1.9.0(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
+ dependencies:
+ '@babel/runtime': 8.0.8
+ '@base-ui/utils': 0.5.0(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ '@floating-ui/react-dom': 2.1.9(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ '@floating-ui/utils': 0.2.12
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ use-sync-external-store: 1.7.0(react@19.3.1)
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ '@base-ui/utils@0.5.0(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
+ dependencies:
+ '@babel/runtime': 8.0.8
+ '@floating-ui/utils': 0.2.12
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ reselect: 5.3.0
+ use-sync-external-store: 1.7.0(react@19.3.1)
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ '@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@3.25.76))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)':
+ dependencies:
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+ '@opentelemetry/semantic-conventions': 1.43.0
+ '@standard-schema/spec': 1.1.0
+ better-call: 1.4.0(zod@3.25.76)
+ jose: 6.2.13
+ kysely: 0.29.6
+ nanostores: 1.5.5
+ zod: 4.6.7
+
+ '@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)':
+ dependencies:
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+ '@opentelemetry/semantic-conventions': 1.43.0
+ '@standard-schema/spec': 1.1.0
+ better-call: 1.4.0(zod@4.6.7)
+ jose: 6.2.13
+ kysely: 0.29.6
+ nanostores: 1.5.5
+ zod: 4.6.7
+
+ '@better-auth/drizzle-adapter@1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)':
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/utils': 0.4.2
+
+ '@better-auth/kysely-adapter@1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(kysely@0.29.6)':
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/utils': 0.4.2
+ optionalDependencies:
+ kysely: 0.29.6
+
+ '@better-auth/memory-adapter@1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)':
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/utils': 0.4.2
+
+ '@better-auth/mongo-adapter@1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)':
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/utils': 0.4.2
+
+ '@better-auth/prisma-adapter@1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)':
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/utils': 0.4.2
+
+ '@better-auth/telemetry@1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)':
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+
+ '@better-auth/utils@0.4.2':
+ dependencies:
+ '@noble/hashes': 2.4.0
+
+ '@better-auth/utils@0.5.1':
+ dependencies:
+ '@noble/hashes': 2.4.0
+
+ '@better-fetch/fetch@1.3.2': {}
+
+ '@cacheable/memory@2.2.0':
+ dependencies:
+ '@cacheable/utils': 2.5.0
+ '@keyv/bigmap': 1.3.1(keyv@5.6.0)
+ hookified: 1.15.1
+ keyv: 5.6.0
+
+ '@cacheable/utils@2.5.0':
+ dependencies:
+ hashery: 1.5.1
+ keyv: 5.6.0
+
+ '@cloudflare/kv-asset-handler@0.5.0': {}
+
+ '@cloudflare/unenv-preset@2.16.2(unenv@2.0.0-rc.24)(workerd@1.20261012.1)':
+ dependencies:
+ unenv: 2.0.0-rc.24
+ optionalDependencies:
+ workerd: 1.20261012.1
+
+ '@cloudflare/unenv-preset@2.16.2(unenv@2.0.0-rc.24)(workerd@1.20261019.1)':
+ dependencies:
+ unenv: 2.0.0-rc.24
+ optionalDependencies:
+ workerd: 1.20261019.1
+
+ '@cloudflare/vite-plugin@1.64.0(@types/node@22.18.6)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))(wrangler@4.151.3(@cloudflare/workers-types@5.20261019.1)(@types/node@22.18.6))':
+ dependencies:
+ '@cloudflare/unenv-preset': 2.16.2(unenv@2.0.0-rc.24)(workerd@1.20261012.1)
+ miniflare: 5.20261012.0-beta(@types/node@22.18.6)
+ unenv: 2.0.0-rc.24
+ vite: 8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)
+ workerd: 1.20261012.1
+ wrangler: 4.151.3(@cloudflare/workers-types@5.20261019.1)(@types/node@22.18.6)
+ ws: 8.21.0
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
+
+ '@cloudflare/workerd-darwin-64@1.20261012.1':
+ optional: true
+
+ '@cloudflare/workerd-darwin-64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-darwin-arm64@1.20261012.1':
+ optional: true
+
+ '@cloudflare/workerd-darwin-arm64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-linux-64@1.20261012.1':
+ optional: true
+
+ '@cloudflare/workerd-linux-64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-linux-arm64@1.20261012.1':
+ optional: true
+
+ '@cloudflare/workerd-linux-arm64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-windows-64@1.20261012.1':
+ optional: true
+
+ '@cloudflare/workerd-windows-64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workers-types@5.20261019.1': {}
+
+ '@cspotcode/source-map-support@0.8.1':
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.9
+
+ '@emnapi/runtime@1.11.3':
dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/types': 4.16.1
tslib: 2.8.1
- dev: false
+ optional: true
+
+ '@esbuild/aix-ppc64@0.25.12':
+ optional: true
+
+ '@esbuild/aix-ppc64@0.27.7':
+ optional: true
+
+ '@esbuild/aix-ppc64@0.28.2':
+ optional: true
+
+ '@esbuild/android-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/android-arm@0.25.12':
+ optional: true
+
+ '@esbuild/android-arm@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm@0.28.2':
+ optional: true
+
+ '@esbuild/android-x64@0.25.12':
+ optional: true
+
+ '@esbuild/android-x64@0.27.7':
+ optional: true
+
+ '@esbuild/android-x64@0.28.2':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/darwin-x64@0.25.12':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-x64@0.28.2':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.28.2':
+ optional: true
+
+ '@esbuild/linux-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/linux-arm@0.25.12':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm@0.28.2':
+ optional: true
+
+ '@esbuild/linux-ia32@0.25.12':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.7':
+ optional: true
+
+ '@esbuild/linux-ia32@0.28.2':
+ optional: true
- /@aws-sdk/middleware-logger@3.734.0:
- resolution: {integrity: sha512-mUMFITpJUW3LcKvFok176eI5zXAUomVtahb9IQBwLzkqFYOrMJvWAvoV4yuxrJ8TlQBG8gyEnkb9SnhZvjg67w==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-loong64@0.25.12':
+ optional: true
- /@aws-sdk/middleware-recursion-detection@3.734.0:
- resolution: {integrity: sha512-CUat2d9ITsFc2XsmeiRQO96iWpxSKYFjxvj27Hc7vo87YUHRnfMfnc8jw1EpxEwMcvBD7LsRa6vDNky6AjcrFA==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/protocol-http': 5.5.8
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-loong64@0.27.7':
+ optional: true
- /@aws-sdk/middleware-sdk-s3@3.744.0:
- resolution: {integrity: sha512-zE0kNjMV7B8pC2ClhrV2gCj/gWLiinRkfPeiUevfjl+Hdke9zcAWVNHLeGV54FJjXQEdwIAjeE7WJdHo7hio7g==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-arn-parser': 3.723.0
- '@smithy/core': 3.29.3
- '@smithy/node-config-provider': 4.5.8
- '@smithy/protocol-http': 5.5.8
- '@smithy/signature-v4': 5.6.4
- '@smithy/smithy-client': 4.14.8
- '@smithy/types': 4.16.1
- '@smithy/util-config-provider': 4.4.8
- '@smithy/util-middleware': 4.4.8
- '@smithy/util-stream': 4.7.8
- '@smithy/util-utf8': 4.4.8
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-loong64@0.28.2':
+ optional: true
- /@aws-sdk/middleware-ssec@3.734.0:
- resolution: {integrity: sha512-d4yd1RrPW/sspEXizq2NSOUivnheac6LPeLSLnaeTbBG9g1KqIqvCzP1TfXEqv2CrWfHEsWtJpX7oyjySSPvDQ==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-mips64el@0.25.12':
+ optional: true
- /@aws-sdk/middleware-user-agent@3.744.0:
- resolution: {integrity: sha512-ROUbDQHfVWiBHXd4m9E9mKj1Azby8XCs8RC8OCf9GVH339GSE6aMrPJSzMlsV1LmzPdPIypgp5qqh5NfSrKztg==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-endpoints': 3.743.0
- '@smithy/core': 3.29.3
- '@smithy/protocol-http': 5.5.8
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-mips64el@0.27.7':
+ optional: true
- /@aws-sdk/nested-clients@3.744.0:
- resolution: {integrity: sha512-Mnrlh4lRY1gZQnKvN2Lh/5WXcGkzC41NM93mtn2uaqOh+DZLCXCttNCfbUesUvYJLOo3lYaOpiDsjTkPVB1yjw==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-crypto/sha256-browser': 5.2.0
- '@aws-crypto/sha256-js': 5.2.0
- '@aws-sdk/core': 3.744.0
- '@aws-sdk/middleware-host-header': 3.734.0
- '@aws-sdk/middleware-logger': 3.734.0
- '@aws-sdk/middleware-recursion-detection': 3.734.0
- '@aws-sdk/middleware-user-agent': 3.744.0
- '@aws-sdk/region-config-resolver': 3.734.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-endpoints': 3.743.0
- '@aws-sdk/util-user-agent-browser': 3.734.0
- '@aws-sdk/util-user-agent-node': 3.744.0
- '@smithy/config-resolver': 4.6.8
- '@smithy/core': 3.29.3
- '@smithy/fetch-http-handler': 5.6.5
- '@smithy/hash-node': 4.4.8
- '@smithy/invalid-dependency': 4.4.8
- '@smithy/middleware-content-length': 4.4.8
- '@smithy/middleware-endpoint': 4.6.8
- '@smithy/middleware-retry': 4.7.8
- '@smithy/middleware-serde': 4.4.8
- '@smithy/middleware-stack': 4.4.8
- '@smithy/node-config-provider': 4.5.8
- '@smithy/node-http-handler': 4.9.5
- '@smithy/protocol-http': 5.5.8
- '@smithy/smithy-client': 4.14.8
- '@smithy/types': 4.16.1
- '@smithy/url-parser': 4.4.8
- '@smithy/util-base64': 4.5.8
- '@smithy/util-body-length-browser': 4.4.8
- '@smithy/util-body-length-node': 4.4.8
- '@smithy/util-defaults-mode-browser': 4.5.8
- '@smithy/util-defaults-mode-node': 4.4.8
- '@smithy/util-endpoints': 3.6.8
- '@smithy/util-middleware': 4.4.8
- '@smithy/util-retry': 4.5.8
- '@smithy/util-utf8': 4.4.8
- tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
+ '@esbuild/linux-mips64el@0.28.2':
+ optional: true
- /@aws-sdk/region-config-resolver@3.734.0:
- resolution: {integrity: sha512-Lvj1kPRC5IuJBr9DyJ9T9/plkh+EfKLy+12s/mykOy1JaKHDpvj+XGy2YO6YgYVOb8JFtaqloid+5COtje4JTQ==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/node-config-provider': 4.5.8
- '@smithy/types': 4.16.1
- '@smithy/util-config-provider': 4.4.8
- '@smithy/util-middleware': 4.4.8
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-ppc64@0.25.12':
+ optional: true
- /@aws-sdk/s3-request-presigner@3.744.0:
- resolution: {integrity: sha512-RDMiGOr9HOb+JE5yaidNObY5hG/ZXZRYOhphvOekW5nCiIof03BIArQwF7w1eYbDErJinLpLU+SbUx3Ln/9KIw==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/signature-v4-multi-region': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@aws-sdk/util-format-url': 3.734.0
- '@smithy/middleware-endpoint': 4.6.8
- '@smithy/protocol-http': 5.5.8
- '@smithy/smithy-client': 4.14.8
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-ppc64@0.27.7':
+ optional: true
- /@aws-sdk/signature-v4-multi-region@3.744.0:
- resolution: {integrity: sha512-QyrAevGGwceM+knGfV5r2NvSAjI94PETu6u+Fxalf8F/ybpK7qn1va0w3cGDU68oRqC0JHfo53JXjm9yQokj9Q==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/middleware-sdk-s3': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/protocol-http': 5.5.8
- '@smithy/signature-v4': 5.6.4
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-ppc64@0.28.2':
+ optional: true
- /@aws-sdk/token-providers@3.744.0:
- resolution: {integrity: sha512-v/1+lWkDCd60Ei6oyhJqli6mTsPEVepLoSMB50vHUVlJP0fzXu/3FMje90/RzeUoh/VugZQJCEv/NNpuC6wztg==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/nested-clients': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/property-provider': 4.4.8
- '@smithy/shared-ini-file-loader': 4.6.8
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- transitivePeerDependencies:
- - aws-crt
- dev: false
+ '@esbuild/linux-riscv64@0.25.12':
+ optional: true
- /@aws-sdk/types@3.734.0:
- resolution: {integrity: sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-riscv64@0.27.7':
+ optional: true
- /@aws-sdk/util-arn-parser@3.723.0:
- resolution: {integrity: sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w==}
- engines: {node: '>=18.0.0'}
- dependencies:
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-riscv64@0.28.2':
+ optional: true
- /@aws-sdk/util-endpoints@3.743.0:
- resolution: {integrity: sha512-sN1l559zrixeh5x+pttrnd0A3+r34r0tmPkJ/eaaMaAzXqsmKU/xYre9K3FNnsSS1J1k4PEfk/nHDTVUgFYjnw==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/types': 4.16.1
- '@smithy/util-endpoints': 3.6.8
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-s390x@0.25.12':
+ optional: true
- /@aws-sdk/util-format-url@3.734.0:
- resolution: {integrity: sha512-TxZMVm8V4aR/QkW9/NhujvYpPZjUYqzLwSge5imKZbWFR806NP7RMwc5ilVuHF/bMOln/cVHkl42kATElWBvNw==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/querystring-builder': 4.4.8
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-s390x@0.27.7':
+ optional: true
- /@aws-sdk/util-locate-window@3.965.8:
- resolution: {integrity: sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==}
- engines: {node: '>=20.0.0'}
- dependencies:
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-s390x@0.28.2':
+ optional: true
- /@aws-sdk/util-user-agent-browser@3.734.0:
- resolution: {integrity: sha512-xQTCus6Q9LwUuALW+S76OL0jcWtMOVu14q+GoLnWPUM7QeUw963oQcLhF7oq0CtaLLKyl4GOUfcwc773Zmwwng==}
- dependencies:
- '@aws-sdk/types': 3.734.0
- '@smithy/types': 4.16.1
- bowser: 2.14.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-x64@0.25.12':
+ optional: true
- /@aws-sdk/util-user-agent-node@3.744.0:
- resolution: {integrity: sha512-BJURjwIXhNa4heXkLC0+GcL+8wVXaU7JoyW6ckdvp93LL+sVHeR1d5FxXZHQW/pMI4E3gNlKyBqjKaT75tObNQ==}
- engines: {node: '>=18.0.0'}
- peerDependencies:
- aws-crt: '>=1.0.0'
- peerDependenciesMeta:
- aws-crt:
- optional: true
- dependencies:
- '@aws-sdk/middleware-user-agent': 3.744.0
- '@aws-sdk/types': 3.734.0
- '@smithy/node-config-provider': 4.5.8
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-x64@0.27.7':
+ optional: true
- /@aws-sdk/xml-builder@3.734.0:
- resolution: {integrity: sha512-Zrjxi5qwGEcUsJ0ru7fRtW74WcTS0rbLcehoFB+rN1GRi2hbLcFaYs4PwVA5diLeAJH0gszv3x4Hr/S87MfbKQ==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@esbuild/linux-x64@0.28.2':
+ optional: true
- /@babel/runtime-corejs3@7.29.7:
- resolution: {integrity: sha512-ppj9ouYku+RX0ljtgZd+KMO5mkM2bCqg8H2PYAFWnLsHEIKIdRojqbJ2i3eVHrisuxy7nOFCmngTDdWtUCdXUQ==}
- engines: {node: '>=6.9.0'}
- dependencies:
- core-js-pure: 3.49.0
- dev: true
+ '@esbuild/netbsd-arm64@0.25.12':
+ optional: true
- /@babel/runtime@7.29.7:
- resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
- engines: {node: '>=6.9.0'}
- dev: false
+ '@esbuild/netbsd-arm64@0.27.7':
+ optional: true
- /@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0):
- resolution: {integrity: sha512-yBDDO0J4VCHT1qEZtzj6aMexX4etyLesitoxehcWHzPrzYqrFHwe/hgskye+imlGhQVOysuljMg8M8BA6GrtIg==}
- peerDependencies:
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
- '@opentelemetry/api': ^1.9.0
- better-call: 1.4.0
- jose: ^6.1.0
- kysely: ^0.28.5 || ^0.29.0
- nanostores: ^1.0.1
- peerDependenciesMeta:
- '@opentelemetry/api':
- optional: true
- dependencies:
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
- '@opentelemetry/semantic-conventions': 1.43.0
- '@standard-schema/spec': 1.1.0
- better-call: 1.4.0(zod@3.25.67)
- jose: 6.2.3
- kysely: 0.29.6
- nanostores: 1.4.0
- zod: 4.6.5
- dev: false
+ '@esbuild/netbsd-arm64@0.28.2':
+ optional: true
- /@better-auth/drizzle-adapter@1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2):
- resolution: {integrity: sha512-ENlhwC7kkTjquuiel3Efggik0hC4vtD7ppJ8FhsiHhRJA8K6RT4hbhzkfm6keNvjdnAeWwCejm7FmMO4GoSGpA==}
- peerDependencies:
- '@better-auth/core': ^1.7.6
- '@better-auth/utils': 0.4.2
- drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
- peerDependenciesMeta:
- drizzle-orm:
- optional: true
- dependencies:
- '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0)
- '@better-auth/utils': 0.4.2
- dev: false
+ '@esbuild/netbsd-x64@0.25.12':
+ optional: true
- /@better-auth/kysely-adapter@1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)(kysely@0.29.6):
- resolution: {integrity: sha512-BV+DX2/z/6ozNC9DYSge78wjLerq6Bxd/lSPjzzuq9eEutkQDAJTuiaETzgGYqNV5LlEWi8TZFAQTEq/wavOEQ==}
- peerDependencies:
- '@better-auth/core': ^1.7.6
- '@better-auth/utils': 0.4.2
- kysely: ^0.28.17 || ^0.29.0
- peerDependenciesMeta:
- kysely:
- optional: true
- dependencies:
- '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0)
- '@better-auth/utils': 0.4.2
- kysely: 0.29.6
- dev: false
+ '@esbuild/netbsd-x64@0.27.7':
+ optional: true
- /@better-auth/memory-adapter@1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2):
- resolution: {integrity: sha512-ng1xv8k2JsEIjnqzJzdoVOQrnoCLRuk4EiQL9yYAThyg6zYzV00LynlhH+O9OMUZ+yGVpGqGZmr5xcTiUSV2uA==}
- peerDependencies:
- '@better-auth/core': ^1.7.6
- '@better-auth/utils': 0.4.2
- dependencies:
- '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0)
- '@better-auth/utils': 0.4.2
- dev: false
+ '@esbuild/netbsd-x64@0.28.2':
+ optional: true
- /@better-auth/mongo-adapter@1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2):
- resolution: {integrity: sha512-GvBwZli8i4XINMAj9tlW7eV9E8Dr+JWqavXjUs2o81GZt/Vh8wiX+31KK1jQ4iOuejfjpLoXcoFtlIPgf/pVog==}
- peerDependencies:
- '@better-auth/core': ^1.7.6
- '@better-auth/utils': 0.4.2
- mongodb: ^6.0.0 || ^7.0.0
- peerDependenciesMeta:
- mongodb:
- optional: true
- dependencies:
- '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0)
- '@better-auth/utils': 0.4.2
- dev: false
+ '@esbuild/openbsd-arm64@0.25.12':
+ optional: true
- /@better-auth/prisma-adapter@1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2):
- resolution: {integrity: sha512-31rz2OXIx2Q1L4Jhd5F71dafIWqder/Bo6vJ+eCgO5iZ0gvnv7fUmM95DvbVUoPC69XYpcIM/6PJmQ3M6RydWg==}
- peerDependencies:
- '@better-auth/core': ^1.7.6
- '@better-auth/utils': 0.4.2
- '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
- prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
- peerDependenciesMeta:
- '@prisma/client':
- optional: true
- prisma:
- optional: true
- dependencies:
- '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0)
- '@better-auth/utils': 0.4.2
- dev: false
+ '@esbuild/openbsd-arm64@0.27.7':
+ optional: true
- /@better-auth/telemetry@1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2):
- resolution: {integrity: sha512-xgRwPja2wTJtcu+OQZR2IiNpAmviddnW3n5Do5umXRugJFW3v9KlSmYjYm580mVsPnU4upvZkvSRl9v8DgSDtA==}
- peerDependencies:
- '@better-auth/core': ^1.7.6
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
- dependencies:
- '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0)
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
- dev: false
+ '@esbuild/openbsd-arm64@0.28.2':
+ optional: true
- /@better-auth/utils@0.4.2:
- resolution: {integrity: sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==}
- dependencies:
- '@noble/hashes': 2.2.0
- dev: false
+ '@esbuild/openbsd-x64@0.25.12':
+ optional: true
- /@better-auth/utils@0.5.0:
- resolution: {integrity: sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA==}
- dependencies:
- '@noble/hashes': 2.2.0
- dev: false
+ '@esbuild/openbsd-x64@0.27.7':
+ optional: true
- /@better-fetch/fetch@1.3.2:
- resolution: {integrity: sha512-Gs7n99b5tqUC6cQAPbV0uED3IraHB6xQbHLQ/C3l7ZFafHScOx9pQ+DYmP5blbLFShVWLqxNUlI9wi4xU/X+ow==}
- dev: false
+ '@esbuild/openbsd-x64@0.28.2':
+ optional: true
- /@cspotcode/source-map-support@0.8.1:
- resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
- engines: {node: '>=12'}
- dependencies:
- '@jridgewell/trace-mapping': 0.3.9
- dev: true
+ '@esbuild/openharmony-arm64@0.25.12':
+ optional: true
- /@esbuild/aix-ppc64@0.27.7:
- resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [aix]
- requiresBuild: true
- dev: true
+ '@esbuild/openharmony-arm64@0.27.7':
optional: true
- /@esbuild/aix-ppc64@0.28.1:
- resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [aix]
- requiresBuild: true
+ '@esbuild/openharmony-arm64@0.28.2':
optional: true
- /@esbuild/android-arm64@0.27.7:
- resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
- dev: true
+ '@esbuild/sunos-x64@0.25.12':
optional: true
- /@esbuild/android-arm64@0.28.1:
- resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
+ '@esbuild/sunos-x64@0.27.7':
optional: true
- /@esbuild/android-arm@0.27.7:
- resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [android]
- requiresBuild: true
- dev: true
+ '@esbuild/sunos-x64@0.28.2':
optional: true
- /@esbuild/android-arm@0.28.1:
- resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [android]
- requiresBuild: true
+ '@esbuild/win32-arm64@0.25.12':
optional: true
- /@esbuild/android-x64@0.27.7:
- resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [android]
- requiresBuild: true
- dev: true
+ '@esbuild/win32-arm64@0.27.7':
optional: true
- /@esbuild/android-x64@0.28.1:
- resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [android]
- requiresBuild: true
+ '@esbuild/win32-arm64@0.28.2':
optional: true
- /@esbuild/darwin-arm64@0.27.7:
- resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: true
+ '@esbuild/win32-ia32@0.25.12':
optional: true
- /@esbuild/darwin-arm64@0.28.1:
- resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
+ '@esbuild/win32-ia32@0.27.7':
optional: true
- /@esbuild/darwin-x64@0.27.7:
- resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: true
+ '@esbuild/win32-ia32@0.28.2':
optional: true
- /@esbuild/darwin-x64@0.28.1:
- resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
+ '@esbuild/win32-x64@0.25.12':
optional: true
- /@esbuild/freebsd-arm64@0.27.7:
- resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [freebsd]
- requiresBuild: true
- dev: true
+ '@esbuild/win32-x64@0.27.7':
optional: true
- /@esbuild/freebsd-arm64@0.28.1:
- resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [freebsd]
- requiresBuild: true
+ '@esbuild/win32-x64@0.28.2':
optional: true
- /@esbuild/freebsd-x64@0.27.7:
- resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
+ '@eslint-community/eslint-utils@4.10.1(eslint@10.13.0(jiti@2.7.0)(supports-color@10.2.2))':
+ dependencies:
+ eslint: 10.13.0(jiti@2.7.0)(supports-color@10.2.2)
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/regexpp@4.12.2': {}
+
+ '@eslint/config-array@0.23.5(supports-color@10.2.2)':
+ dependencies:
+ '@eslint/object-schema': 3.0.5
+ debug: 4.4.3(supports-color@10.2.2)
+ minimatch: 10.2.6
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/config-helpers@0.7.0':
+ dependencies:
+ '@eslint/core': 1.2.1
+
+ '@eslint/core@1.2.1':
+ dependencies:
+ '@types/json-schema': 7.0.15
+
+ '@eslint/object-schema@3.0.5': {}
+
+ '@eslint/plugin-kit@0.7.3':
+ dependencies:
+ '@eslint/core': 1.2.1
+ levn: 0.4.1
+
+ '@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/react-dom@2.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@floating-ui/dom': 1.8.0
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
+ '@floating-ui/react-dom@2.1.9(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
+ dependencies:
+ '@floating-ui/dom': 1.8.0
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+
+ '@floating-ui/utils@0.2.12': {}
+
+ '@fuma-translate/react@1.0.2(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
+ dependencies:
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ '@fumadocs/base-ui@16.17.7(@types/mdx@2.0.14)(@types/react@19.3.0)(fumadocs-core@16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(tailwindcss@4.3.3)':
+ dependencies:
+ '@base-ui/react': 1.9.0(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ '@fuma-translate/react': 1.0.2(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ '@fumadocs/tailwind': 0.1.4(tailwindcss@4.3.3)
+ class-variance-authority: 0.7.1
+ cn: 0.4.0
+ fumadocs-core: 16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7)
+ hast-util-to-jsx-runtime: 2.3.6(supports-color@10.2.2)
+ lucide-react: 1.61.0(@types/react@19.3.0)(react@19.3.1)
+ motion: 14.6.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ next-themes: 0.4.6(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ react-remove-scroll: 2.7.2(@types/react@19.3.0)(react@19.3.1)
+ scroll-into-view-if-needed: 3.1.0
+ shiki: 4.5.0
+ optionalDependencies:
+ '@types/mdx': 2.0.14
+ '@types/react': 19.3.0
+ next: 16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ transitivePeerDependencies:
+ - '@date-fns/tz'
+ - date-fns
+ - supports-color
+ - tailwindcss
+
+ '@fumadocs/tailwind@0.1.4(tailwindcss@4.3.3)':
+ optionalDependencies:
+ tailwindcss: 4.3.3
- /@esbuild/freebsd-x64@0.28.1:
- resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [freebsd]
- requiresBuild: true
- optional: true
+ '@fumari/image-size@0.1.1': {}
- /@esbuild/linux-arm64@0.27.7:
- resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ '@hookform/resolvers@3.10.0(react-hook-form@7.52.1(react@18.3.1))':
+ dependencies:
+ react-hook-form: 7.52.1(react@18.3.1)
- /@esbuild/linux-arm64@0.28.1:
- resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- optional: true
+ '@humanfs/core@0.19.2':
+ dependencies:
+ '@humanfs/types': 0.15.0
- /@esbuild/linux-arm@0.27.7:
- resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ '@humanfs/node@0.16.8':
+ dependencies:
+ '@humanfs/core': 0.19.2
+ '@humanfs/types': 0.15.0
+ '@humanwhocodes/retry': 0.4.3
- /@esbuild/linux-arm@0.28.1:
- resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- optional: true
+ '@humanfs/types@0.15.0': {}
- /@esbuild/linux-ia32@0.27.7:
- resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ '@humanwhocodes/module-importer@1.0.1': {}
- /@esbuild/linux-ia32@0.28.1:
- resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [linux]
- requiresBuild: true
- optional: true
+ '@humanwhocodes/retry@0.4.3': {}
- /@esbuild/linux-loong64@0.27.7:
- resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
- engines: {node: '>=18'}
- cpu: [loong64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ '@img/colour@1.1.0': {}
- /@esbuild/linux-loong64@0.28.1:
- resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==}
- engines: {node: '>=18'}
- cpu: [loong64]
- os: [linux]
- requiresBuild: true
+ '@img/sharp-darwin-arm64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.3.4
optional: true
- /@esbuild/linux-mips64el@0.27.7:
- resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
- engines: {node: '>=18'}
- cpu: [mips64el]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@img/sharp-darwin-x64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.3.4
optional: true
- /@esbuild/linux-mips64el@0.28.1:
- resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==}
- engines: {node: '>=18'}
- cpu: [mips64el]
- os: [linux]
- requiresBuild: true
+ '@img/sharp-freebsd-wasm32@0.35.5':
+ dependencies:
+ '@img/sharp-wasm32': 0.35.5
optional: true
- /@esbuild/linux-ppc64@0.27.7:
- resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@img/sharp-libvips-darwin-arm64@1.3.4':
optional: true
- /@esbuild/linux-ppc64@0.28.1:
- resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
+ '@img/sharp-libvips-darwin-x64@1.3.4':
optional: true
- /@esbuild/linux-riscv64@0.27.7:
- resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
- engines: {node: '>=18'}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@img/sharp-libvips-linux-arm64@1.3.4':
optional: true
- /@esbuild/linux-riscv64@0.28.1:
- resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==}
- engines: {node: '>=18'}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
+ '@img/sharp-libvips-linux-arm@1.3.4':
optional: true
- /@esbuild/linux-s390x@0.27.7:
- resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
- engines: {node: '>=18'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@img/sharp-libvips-linux-ppc64@1.3.4':
optional: true
- /@esbuild/linux-s390x@0.28.1:
- resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==}
- engines: {node: '>=18'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
+ '@img/sharp-libvips-linux-riscv64@1.3.4':
optional: true
- /@esbuild/linux-x64@0.27.7:
- resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@img/sharp-libvips-linux-s390x@1.3.4':
optional: true
- /@esbuild/linux-x64@0.28.1:
- resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
+ '@img/sharp-libvips-linux-x64@1.3.4':
optional: true
- /@esbuild/netbsd-arm64@0.27.7:
- resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [netbsd]
- requiresBuild: true
- dev: true
+ '@img/sharp-libvips-linuxmusl-arm64@1.3.4':
optional: true
- /@esbuild/netbsd-arm64@0.28.1:
- resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [netbsd]
- requiresBuild: true
+ '@img/sharp-libvips-linuxmusl-x64@1.3.4':
optional: true
- /@esbuild/netbsd-x64@0.27.7:
- resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [netbsd]
- requiresBuild: true
- dev: true
+ '@img/sharp-linux-arm64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.3.4
optional: true
- /@esbuild/netbsd-x64@0.28.1:
- resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [netbsd]
- requiresBuild: true
+ '@img/sharp-linux-arm@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.3.4
optional: true
- /@esbuild/openbsd-arm64@0.27.7:
- resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openbsd]
- requiresBuild: true
- dev: true
+ '@img/sharp-linux-ppc64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.3.4
optional: true
- /@esbuild/openbsd-arm64@0.28.1:
- resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openbsd]
- requiresBuild: true
+ '@img/sharp-linux-riscv64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.3.4
optional: true
- /@esbuild/openbsd-x64@0.27.7:
- resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [openbsd]
- requiresBuild: true
- dev: true
+ '@img/sharp-linux-s390x@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.3.4
optional: true
- /@esbuild/openbsd-x64@0.28.1:
- resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [openbsd]
- requiresBuild: true
+ '@img/sharp-linux-x64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.3.4
optional: true
- /@esbuild/openharmony-arm64@0.27.7:
- resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openharmony]
- requiresBuild: true
- dev: true
+ '@img/sharp-linuxmusl-arm64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.3.4
optional: true
- /@esbuild/openharmony-arm64@0.28.1:
- resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openharmony]
- requiresBuild: true
+ '@img/sharp-linuxmusl-x64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.3.4
optional: true
- /@esbuild/sunos-x64@0.27.7:
- resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [sunos]
- requiresBuild: true
- dev: true
+ '@img/sharp-wasm32@0.35.5':
+ dependencies:
+ '@emnapi/runtime': 1.11.3
optional: true
- /@esbuild/sunos-x64@0.28.1:
- resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [sunos]
- requiresBuild: true
+ '@img/sharp-webcontainers-wasm32@0.35.5':
+ dependencies:
+ '@img/sharp-wasm32': 0.35.5
optional: true
- /@esbuild/win32-arm64@0.27.7:
- resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
+ '@img/sharp-win32-arm64@0.35.5':
optional: true
- /@esbuild/win32-arm64@0.28.1:
- resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
+ '@img/sharp-win32-ia32@0.35.5':
optional: true
- /@esbuild/win32-ia32@0.27.7:
- resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: true
+ '@img/sharp-win32-x64@0.35.5':
optional: true
- /@esbuild/win32-ia32@0.28.1:
- resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- optional: true
+ '@inquirer/ansi@1.0.2': {}
- /@esbuild/win32-x64@0.27.7:
- resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@inquirer/checkbox@4.3.2(@types/node@20.14.11)':
+ dependencies:
+ '@inquirer/ansi': 1.0.2
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/figures': 1.0.15
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ yoctocolors-cjs: 2.1.3
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@esbuild/win32-x64@0.28.1:
- resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- optional: true
+ '@inquirer/confirm@5.1.21(@types/node@20.14.11)':
+ dependencies:
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@eslint-community/eslint-utils@4.9.1(eslint@9.7.0):
- resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- peerDependencies:
- eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ '@inquirer/core@10.3.2(@types/node@20.14.11)':
dependencies:
- eslint: 9.7.0
- eslint-visitor-keys: 3.4.3
- dev: true
+ '@inquirer/ansi': 1.0.2
+ '@inquirer/figures': 1.0.15
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ cli-width: 4.1.0
+ mute-stream: 2.0.0
+ signal-exit: 4.1.0
+ wrap-ansi: 6.2.0
+ yoctocolors-cjs: 2.1.3
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@eslint-community/regexpp@4.12.2:
- resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
- engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- dev: true
+ '@inquirer/editor@4.2.23(@types/node@20.14.11)':
+ dependencies:
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/external-editor': 1.0.3(@types/node@20.14.11)
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@eslint/config-array@0.17.1:
- resolution: {integrity: sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@inquirer/expand@4.0.23(@types/node@20.14.11)':
dependencies:
- '@eslint/object-schema': 2.1.7
- debug: 4.4.3
- minimatch: 3.1.5
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ yoctocolors-cjs: 2.1.3
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@eslint/eslintrc@3.3.5:
- resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@inquirer/external-editor@1.0.3(@types/node@20.14.11)':
dependencies:
- ajv: 6.15.0
- debug: 4.4.3
- espree: 10.4.0
- globals: 14.0.0
- ignore: 5.3.2
- import-fresh: 3.3.1
- js-yaml: 4.3.0
- minimatch: 3.1.5
- strip-json-comments: 3.1.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ chardet: 2.2.0
+ iconv-lite: 0.7.3
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@eslint/js@9.7.0:
- resolution: {integrity: sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- dev: true
+ '@inquirer/figures@1.0.15': {}
- /@eslint/object-schema@2.1.7:
- resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- dev: true
+ '@inquirer/input@4.3.1(@types/node@20.14.11)':
+ dependencies:
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@floating-ui/core@1.7.5:
- resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==}
+ '@inquirer/number@3.0.23(@types/node@20.14.11)':
dependencies:
- '@floating-ui/utils': 0.2.11
- dev: false
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@floating-ui/dom@1.7.6:
- resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==}
+ '@inquirer/password@4.0.23(@types/node@20.14.11)':
dependencies:
- '@floating-ui/core': 1.7.5
- '@floating-ui/utils': 0.2.11
- dev: false
+ '@inquirer/ansi': 1.0.2
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@floating-ui/react-dom@2.1.8(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==}
- peerDependencies:
- react: '>=16.8.0'
- react-dom: '>=16.8.0'
+ '@inquirer/prompts@7.10.1(@types/node@20.14.11)':
+ dependencies:
+ '@inquirer/checkbox': 4.3.2(@types/node@20.14.11)
+ '@inquirer/confirm': 5.1.21(@types/node@20.14.11)
+ '@inquirer/editor': 4.2.23(@types/node@20.14.11)
+ '@inquirer/expand': 4.0.23(@types/node@20.14.11)
+ '@inquirer/input': 4.3.1(@types/node@20.14.11)
+ '@inquirer/number': 3.0.23(@types/node@20.14.11)
+ '@inquirer/password': 4.0.23(@types/node@20.14.11)
+ '@inquirer/rawlist': 4.1.11(@types/node@20.14.11)
+ '@inquirer/search': 3.2.2(@types/node@20.14.11)
+ '@inquirer/select': 4.4.2(@types/node@20.14.11)
+ optionalDependencies:
+ '@types/node': 20.14.11
+
+ '@inquirer/rawlist@4.1.11(@types/node@20.14.11)':
dependencies:
- '@floating-ui/dom': 1.7.6
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- dev: false
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ yoctocolors-cjs: 2.1.3
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@floating-ui/utils@0.2.11:
- resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==}
- dev: false
+ '@inquirer/search@3.2.2(@types/node@20.14.11)':
+ dependencies:
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/figures': 1.0.15
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ yoctocolors-cjs: 2.1.3
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@hookform/resolvers@3.9.0(react-hook-form@7.52.1):
- resolution: {integrity: sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==}
- peerDependencies:
- react-hook-form: ^7.0.0
+ '@inquirer/select@4.4.2(@types/node@20.14.11)':
dependencies:
- react-hook-form: 7.52.1(react@18.3.1)
- dev: false
+ '@inquirer/ansi': 1.0.2
+ '@inquirer/core': 10.3.2(@types/node@20.14.11)
+ '@inquirer/figures': 1.0.15
+ '@inquirer/type': 3.0.10(@types/node@20.14.11)
+ yoctocolors-cjs: 2.1.3
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@humanwhocodes/module-importer@1.0.1:
- resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
- engines: {node: '>=12.22'}
- dev: true
+ '@inquirer/type@3.0.10(@types/node@20.14.11)':
+ optionalDependencies:
+ '@types/node': 20.14.11
- /@humanwhocodes/retry@0.3.1:
- resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
- engines: {node: '>=18.18'}
- dev: true
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.6.0
+ '@jridgewell/trace-mapping': 0.3.31
- /@inquirer/external-editor@1.0.3(@types/node@20.14.11):
- resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==}
- engines: {node: '>=18'}
- peerDependencies:
- '@types/node': '>=18'
- peerDependenciesMeta:
- '@types/node':
- optional: true
+ '@jridgewell/remapping@2.3.5':
dependencies:
- '@types/node': 20.14.11
- chardet: 2.2.0
- iconv-lite: 0.7.3
- dev: true
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
- /@jridgewell/gen-mapping@0.3.13:
- resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/source-map@0.3.11':
dependencies:
- '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
- dev: true
- /@jridgewell/resolve-uri@3.1.2:
- resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
- engines: {node: '>=6.0.0'}
- dev: true
+ '@jridgewell/sourcemap-codec@1.6.0': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.6.0
+
+ '@jridgewell/trace-mapping@0.3.9':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.6.0
+
+ '@keyv/bigmap@1.3.1(keyv@5.6.0)':
+ dependencies:
+ hashery: 1.5.1
+ hookified: 1.15.1
+ keyv: 5.6.0
- /@jridgewell/sourcemap-codec@1.5.5:
- resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+ '@keyv/serialize@1.1.1': {}
- /@jridgewell/trace-mapping@0.3.31:
- resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+ '@libsql/client@0.17.4':
dependencies:
- '@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.5.5
- dev: true
+ '@libsql/core': 0.17.4
+ '@libsql/hrana-client': 0.10.0
+ js-base64: 3.9.5
+ libsql: 0.5.29
+ promise-limit: 2.7.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
- /@jridgewell/trace-mapping@0.3.9:
- resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+ '@libsql/core@0.17.4':
dependencies:
- '@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.5.5
- dev: true
+ js-base64: 3.9.5
- /@libsql/darwin-arm64@0.5.29:
- resolution: {integrity: sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: false
+ '@libsql/darwin-arm64@0.5.29':
optional: true
- /@libsql/darwin-x64@0.5.29:
- resolution: {integrity: sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: false
+ '@libsql/darwin-x64@0.5.29':
optional: true
- /@libsql/linux-arm-gnueabihf@0.5.29:
- resolution: {integrity: sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: false
+ '@libsql/hrana-client@0.10.0':
+ dependencies:
+ '@libsql/isomorphic-ws': 0.1.5
+ js-base64: 3.9.5
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
+ '@libsql/isomorphic-ws@0.1.5':
+ dependencies:
+ '@types/ws': 8.18.2
+ ws: 8.22.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
+ '@libsql/kysely-libsql@0.4.1(kysely@0.29.6)':
+ dependencies:
+ '@libsql/client': 0.17.4
+ kysely: 0.29.6
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
+ '@libsql/linux-arm-gnueabihf@0.5.29':
optional: true
- /@libsql/linux-arm-musleabihf@0.5.29:
- resolution: {integrity: sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: false
+ '@libsql/linux-arm-musleabihf@0.5.29':
optional: true
- /@libsql/linux-arm64-gnu@0.5.29:
- resolution: {integrity: sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: false
+ '@libsql/linux-arm64-gnu@0.5.29':
optional: true
- /@libsql/linux-arm64-musl@0.5.29:
- resolution: {integrity: sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: false
+ '@libsql/linux-arm64-musl@0.5.29':
optional: true
- /@libsql/linux-x64-gnu@0.5.29:
- resolution: {integrity: sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: false
+ '@libsql/linux-x64-gnu@0.5.29':
optional: true
- /@libsql/linux-x64-musl@0.5.29:
- resolution: {integrity: sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: false
+ '@libsql/linux-x64-musl@0.5.29':
optional: true
- /@libsql/win32-x64-msvc@0.5.29:
- resolution: {integrity: sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: false
+ '@libsql/win32-x64-msvc@0.5.29':
optional: true
- /@mikro-orm/core@7.2.1:
- resolution: {integrity: sha512-+gtJoScbin/C3wPItSZkj5vlMTq/LphBLIxHyi5brCbeA6VDcYuoMopiqoFUMQxdhXXrZlKNIHXGrhb8r3biVg==}
- engines: {node: '>= 22.17.0'}
- peerDependencies:
- dataloader: 2.2.3
- peerDependenciesMeta:
- dataloader:
- optional: true
+ '@mdx-js/mdx@3.1.1(supports-color@10.2.2)':
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdx': 2.0.14
+ acorn: 8.19.0
+ collapse-white-space: 2.1.0
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ estree-util-scope: 1.0.1
+ estree-walker: 3.0.3
+ hast-util-to-jsx-runtime: 2.3.6(supports-color@10.2.2)
+ markdown-extensions: 2.0.0
+ recma-build-jsx: 1.0.0
+ recma-jsx: 1.0.1(acorn@8.19.0)
+ recma-stringify: 1.0.0
+ rehype-recma: 1.0.0(supports-color@10.2.2)
+ remark-mdx: 3.1.1(supports-color@10.2.2)
+ remark-parse: 11.0.0(supports-color@10.2.2)
+ remark-rehype: 11.1.2
+ source-map: 0.7.6
+ unified: 11.0.5
+ unist-util-position-from-estree: 2.0.0
+ unist-util-stringify-position: 4.0.0
+ unist-util-visit: 5.2.0
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
- /@mikro-orm/libsql@7.2.1(@mikro-orm/core@7.2.1):
- resolution: {integrity: sha512-jXvptoHpbzfj8XUy5V5BvVee2LOsxgI/GnITfmh6Jl42tpIEDJx6Talqbv+z1PNGkHhw8OU5GoHXDJqYpNqo5w==}
- engines: {node: '>= 22.17.0'}
- peerDependencies:
+ '@mikro-orm/cli@7.2.1':
+ dependencies:
'@mikro-orm/core': 7.2.1
+ mikro-orm: 7.2.1
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - dataloader
+
+ '@mikro-orm/core@7.2.1': {}
+
+ '@mikro-orm/libsql@7.2.1(@mikro-orm/core@7.2.1)':
dependencies:
'@mikro-orm/core': 7.2.1
'@mikro-orm/sql': 7.2.1(@mikro-orm/core@7.2.1)
kysely: 0.29.6
libsql: 0.5.29
- dev: false
- /@mikro-orm/migrations@7.2.1(@mikro-orm/core@7.2.1):
- resolution: {integrity: sha512-sxGcB7na0AkcREsD5U3xP+Psb/nhQFkx7/eY1Nsqq9MBs67O5RoCL97bn3lmgq6GwKZFbktMuuOGozq42+GaNg==}
- engines: {node: '>= 22.17.0'}
- peerDependencies:
- '@mikro-orm/core': 7.2.1
+ '@mikro-orm/migrations@7.2.1(@mikro-orm/core@7.2.1)':
dependencies:
'@mikro-orm/core': 7.2.1
'@mikro-orm/sql': 7.2.1(@mikro-orm/core@7.2.1)
- dev: false
- /@mikro-orm/mysql@7.2.1(@mikro-orm/core@7.2.1)(@types/node@22.18.6):
- resolution: {integrity: sha512-IxCEnfHUzFcxVkRCVaC0KtGoHRRLogxxgeI+J4Pk7oxtDf/jtvYQuFL4tSbmlrH3qzmLQeYYPyJPuDr+a2F7ag==}
- engines: {node: '>= 22.17.0'}
- peerDependencies:
+ '@mikro-orm/mysql@7.2.1(@mikro-orm/core@7.2.1)(@types/node@20.14.11)':
+ dependencies:
'@mikro-orm/core': 7.2.1
+ '@mikro-orm/sql': 7.2.1(@mikro-orm/core@7.2.1)
+ kysely: 0.29.6
+ mysql2: 3.24.4(@types/node@20.14.11)
+ sqlstring: 2.3.3
+ transitivePeerDependencies:
+ - '@types/node'
+
+ '@mikro-orm/mysql@7.2.1(@mikro-orm/core@7.2.1)(@types/node@22.18.6)':
dependencies:
'@mikro-orm/core': 7.2.1
'@mikro-orm/sql': 7.2.1(@mikro-orm/core@7.2.1)
@@ -1952,13 +7730,8 @@ packages:
sqlstring: 2.3.3
transitivePeerDependencies:
- '@types/node'
- dev: false
- /@mikro-orm/postgresql@7.2.1(@mikro-orm/core@7.2.1):
- resolution: {integrity: sha512-PQ1qe4Bj/hQSHYJjR02l06FfEDwniAvncduwZSCLSKuaCUddHc5AN2Utj3yo4xRIVRY8pOa7DFitEQPBozTMJA==}
- engines: {node: '>= 22.17.0'}
- peerDependencies:
- '@mikro-orm/core': 7.2.1
+ '@mikro-orm/postgresql@7.2.1(@mikro-orm/core@7.2.1)':
dependencies:
'@mikro-orm/core': 7.2.1
'@mikro-orm/sql': 7.2.1(@mikro-orm/core@7.2.1)
@@ -1970,1763 +7743,1441 @@ packages:
postgres-interval: 4.1.0
transitivePeerDependencies:
- pg-native
- dev: false
- /@mikro-orm/sql@7.2.1(@mikro-orm/core@7.2.1):
- resolution: {integrity: sha512-3M9dQeUDLlvAT5VJr/KBGAk9C7xez+psVCnvNkAO4hRhwx2Wm7N1HkuyP4Bwj0MjkHVB6LYvhTw/V6pYsVM8lA==}
- engines: {node: '>= 22.17.0'}
- peerDependencies:
- '@mikro-orm/core': 7.2.1
+ '@mikro-orm/sql@7.2.1(@mikro-orm/core@7.2.1)':
dependencies:
'@mikro-orm/core': 7.2.1
kysely: 0.29.6
- /@mikro-orm/sqlite@7.2.1(@mikro-orm/core@7.2.1):
- resolution: {integrity: sha512-+iAPGORAqLl+TcBF+JSLOfRq+PwTQG1NLts+AvN9D8C2czlbDpyjyeaAFSR+5wJlMEZ4wv2rdzt4jSS5T7x3XQ==}
- engines: {node: '>= 22.17.0'}
- peerDependencies:
- '@mikro-orm/core': 7.2.1
+ '@mikro-orm/sqlite@7.2.1(@mikro-orm/core@7.2.1)':
dependencies:
'@mikro-orm/core': 7.2.1
'@mikro-orm/sql': 7.2.1(@mikro-orm/core@7.2.1)
better-sqlite3: 13.0.3
kysely: 0.29.6
- /@neon-rs/load@0.0.4:
- resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==}
- dev: false
+ '@napi-rs/lzma-linux-x64-gnu@1.5.1':
+ optional: true
- /@next/env@14.2.35:
- resolution: {integrity: sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==}
+ '@neon-rs/load@0.0.4': {}
- /@next/swc-darwin-arm64@14.2.33:
- resolution: {integrity: sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==}
- engines: {node: '>= 10'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
+ '@next/env@14.2.35': {}
+
+ '@next/env@16.4.2': {}
+
+ '@next/swc-darwin-arm64@14.2.33':
optional: true
- /@next/swc-darwin-x64@14.2.33:
- resolution: {integrity: sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==}
- engines: {node: '>= 10'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
+ '@next/swc-darwin-arm64@16.4.2':
optional: true
- /@next/swc-linux-arm64-gnu@14.2.33:
- resolution: {integrity: sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==}
- engines: {node: '>= 10'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
+ '@next/swc-darwin-x64@14.2.33':
optional: true
- /@next/swc-linux-arm64-musl@14.2.33:
- resolution: {integrity: sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==}
- engines: {node: '>= 10'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
+ '@next/swc-darwin-x64@16.4.2':
optional: true
- /@next/swc-linux-x64-gnu@14.2.33:
- resolution: {integrity: sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==}
- engines: {node: '>= 10'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
+ '@next/swc-linux-arm64-gnu@14.2.33':
optional: true
- /@next/swc-linux-x64-musl@14.2.33:
- resolution: {integrity: sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==}
- engines: {node: '>= 10'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
+ '@next/swc-linux-arm64-gnu@16.4.2':
optional: true
- /@next/swc-win32-arm64-msvc@14.2.33:
- resolution: {integrity: sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==}
- engines: {node: '>= 10'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
+ '@next/swc-linux-arm64-musl@14.2.33':
optional: true
- /@next/swc-win32-ia32-msvc@14.2.33:
- resolution: {integrity: sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==}
- engines: {node: '>= 10'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
+ '@next/swc-linux-arm64-musl@16.4.2':
optional: true
- /@next/swc-win32-x64-msvc@14.2.33:
- resolution: {integrity: sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==}
- engines: {node: '>= 10'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
+ '@next/swc-linux-x64-gnu@14.2.33':
optional: true
- /@noble/ciphers@2.2.0:
- resolution: {integrity: sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA==}
- engines: {node: '>= 20.19.0'}
- dev: false
+ '@next/swc-linux-x64-gnu@16.4.2':
+ optional: true
- /@noble/hashes@2.2.0:
- resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==}
- engines: {node: '>= 20.19.0'}
- dev: false
+ '@next/swc-linux-x64-musl@14.2.33':
+ optional: true
- /@nodelib/fs.scandir@2.1.5:
- resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
- engines: {node: '>= 8'}
+ '@next/swc-linux-x64-musl@16.4.2':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@14.2.33':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@16.4.2':
+ optional: true
+
+ '@next/swc-win32-ia32-msvc@14.2.33':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@14.2.33':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@16.4.2':
+ optional: true
+
+ '@noble/ciphers@2.4.0': {}
+
+ '@noble/hashes@2.4.0': {}
+
+ '@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
run-parallel: 1.2.0
- dev: true
- /@nodelib/fs.stat@2.0.5:
- resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
- engines: {node: '>= 8'}
- dev: true
+ '@nodelib/fs.stat@2.0.5': {}
- /@nodelib/fs.walk@1.2.8:
- resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
- engines: {node: '>= 8'}
+ '@nodelib/fs.walk@1.2.8':
dependencies:
'@nodelib/fs.scandir': 2.1.5
- fastq: 1.20.1
- dev: true
+ fastq: 1.20.3
- /@opentelemetry/semantic-conventions@1.43.0:
- resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==}
- engines: {node: '>=14'}
- dev: false
+ '@opentelemetry/semantic-conventions@1.43.0': {}
- /@radix-ui/number@1.0.1:
- resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==}
+ '@oxc-project/types@0.155.0': {}
+
+ '@playwright/test@1.64.1':
dependencies:
- '@babel/runtime': 7.29.7
- dev: false
+ playwright: 1.64.1
- /@radix-ui/primitive@1.0.1:
- resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==}
+ '@poppinss/colors@4.1.6':
dependencies:
- '@babel/runtime': 7.29.7
- dev: false
+ kleur: 4.1.5
- /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@poppinss/dumper@0.6.5':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
- '@types/react': 18.3.3
- '@types/react-dom': 18.3.0
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- dev: false
+ '@poppinss/colors': 4.1.6
+ '@sindresorhus/is': 7.2.0
+ supports-color: 10.2.2
- /@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@poppinss/exception@1.2.3': {}
+
+ '@radix-ui/number@1.0.1':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/primitive': 1.0.1
- '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
- '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-use-previous': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-use-size': 1.0.1(@types/react@18.3.3)(react@18.3.1)
+ '@babel/runtime': 7.29.10
+
+ '@radix-ui/primitive@1.0.1':
+ dependencies:
+ '@babel/runtime': 7.29.10
+
+ '@radix-ui/primitive@1.2.0': {}
+
+ '@radix-ui/react-arrow@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.29.10
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
+
+ '@radix-ui/react-checkbox@1.4.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/primitive': 1.2.0
+ '@radix-ui/react-compose-refs': 1.1.5(@types/react@18.3.3)(react@18.3.1)
+ '@radix-ui/react-context': 1.3.0(@types/react@18.3.3)(react@18.3.1)
+ '@radix-ui/react-presence': 1.1.11(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-primitive': 2.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-controllable-state': 1.3.0(@types/react@18.3.3)(react@18.3.1)
+ '@radix-ui/react-use-size': 1.1.5(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-collection@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-collection@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1)
- '@types/react': 18.3.3
- '@types/react-dom': 18.3.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@types/react': 18.3.3
+ '@babel/runtime': 7.29.10
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-context@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-compose-refs@1.1.5(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ react: 18.3.1
+ optionalDependencies:
'@types/react': 18.3.3
+
+ '@radix-ui/react-context@1.0.1(@types/react@18.3.3)(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.29.10
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-direction@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-context@1.3.0(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ react: 18.3.1
+ optionalDependencies:
'@types/react': 18.3.3
+
+ '@radix-ui/react-direction@1.0.1(@types/react@18.3.3)(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.29.10
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-dismissable-layer@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-dismissable-layer@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/primitive': 1.0.1
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.3.3)(react@18.3.1)
- '@types/react': 18.3.3
- '@types/react-dom': 18.3.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@types/react': 18.3.3
+ '@babel/runtime': 7.29.10
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-focus-scope@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-focus-scope@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@types/react': 18.3.3
- '@types/react-dom': 18.3.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-id@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-id@1.0.1(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@types/react': 18.3.3
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-label@2.0.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-label@2.1.17(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
- '@types/react': 18.3.3
- '@types/react-dom': 18.3.0
+ '@radix-ui/react-primitive': 2.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-popper@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-popper@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1)(react@18.3.1)
- '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@babel/runtime': 7.29.10
+ '@floating-ui/react-dom': 2.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-rect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-size': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/rect': 1.0.1
- '@types/react': 18.3.3
- '@types/react-dom': 18.3.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
-
- /@radix-ui/react-portal@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
- dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ optionalDependencies:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- dev: false
- /@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-portal@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
+ '@babel/runtime': 7.29.10
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
+
+ '@radix-ui/react-presence@1.1.11(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
+
+ '@radix-ui/react-primitive@2.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/react-slot': 1.5.0(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-select@1.2.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-select@1.2.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/number': 1.0.1
'@radix-ui/primitive': 1.0.1
- '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-direction': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-focus-scope': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-focus-scope': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-id': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
- '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-previous': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
- '@types/react': 18.3.3
- '@types/react-dom': 18.3.0
+ '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
aria-hidden: 1.2.6
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-remove-scroll: 2.5.5(@types/react@18.3.3)(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/react-slot@1.0.2(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-slot@1.0.2(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@types/react': 18.3.3
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-slot@1.5.0(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@types/react': 18.3.3
+ '@radix-ui/react-compose-refs': 1.1.5(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@types/react': 18.3.3
+ '@babel/runtime': 7.29.10
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
+ '@babel/runtime': 7.29.10
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1)
- '@types/react': 18.3.3
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-use-controllable-state@1.3.0(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@types/react': 18.3.3
+ '@radix-ui/primitive': 1.2.0
+ '@radix-ui/react-use-effect-event': 0.0.5(@types/react@18.3.3)(react@18.3.1)
+ '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-use-previous@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-use-effect-event@0.0.5(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@types/react': 18.3.3
+ '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-use-rect@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/rect': 1.0.1
+ '@babel/runtime': 7.29.10
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
'@types/react': 18.3.3
+
+ '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.3)(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.29.10
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-use-size@1.0.1(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@radix-ui/react-use-layout-effect@1.1.4(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
'@types/react': 18.3.3
+
+ '@radix-ui/react-use-previous@1.0.1(@types/react@18.3.3)(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.29.10
react: 18.3.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0
- react-dom: ^16.8 || ^17.0 || ^18.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
+ '@radix-ui/react-use-rect@1.0.1(@types/react@18.3.3)(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.29.10
+ '@radix-ui/rect': 1.0.1
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ '@radix-ui/react-use-size@1.0.1(@types/react@18.3.3)(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.29.7
- '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
+ '@babel/runtime': 7.29.10
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
'@types/react': 18.3.3
- '@types/react-dom': 18.3.0
+
+ '@radix-ui/react-use-size@1.1.5(@types/react@18.3.3)(react@18.3.1)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@18.3.3)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ '@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.29.10
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
+ '@types/react-dom': 18.3.0
- /@radix-ui/rect@1.0.1:
- resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
+ '@radix-ui/rect@1.0.1':
dependencies:
- '@babel/runtime': 7.29.7
- dev: false
+ '@babel/runtime': 7.29.10
- /@rollup/rollup-android-arm-eabi@4.62.2:
- resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==}
- cpu: [arm]
- os: [android]
- requiresBuild: true
+ '@resvg/resvg-wasm@2.4.1': {}
+
+ '@rolldown/binding-android-arm-eabi@1.2.15':
optional: true
- /@rollup/rollup-android-arm64@4.62.2:
- resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
+ '@rolldown/binding-android-arm64@1.2.15':
optional: true
- /@rollup/rollup-darwin-arm64@4.62.2:
- resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
+ '@rolldown/binding-darwin-arm64@1.2.15':
optional: true
- /@rollup/rollup-darwin-x64@4.62.2:
- resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
+ '@rolldown/binding-darwin-x64@1.2.15':
optional: true
- /@rollup/rollup-freebsd-arm64@4.62.2:
- resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==}
- cpu: [arm64]
- os: [freebsd]
- requiresBuild: true
+ '@rolldown/binding-freebsd-x64@1.2.15':
optional: true
- /@rollup/rollup-freebsd-x64@4.62.2:
- resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==}
- cpu: [x64]
- os: [freebsd]
- requiresBuild: true
+ '@rolldown/binding-linux-arm-gnueabihf@1.2.15':
optional: true
- /@rollup/rollup-linux-arm-gnueabihf@4.62.2:
- resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-linux-arm64-gnu@1.2.15':
optional: true
- /@rollup/rollup-linux-arm-musleabihf@4.62.2:
- resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-linux-arm64-musl@1.2.15':
optional: true
- /@rollup/rollup-linux-arm64-gnu@4.62.2:
- resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-linux-ppc64-gnu@1.2.15':
optional: true
- /@rollup/rollup-linux-arm64-musl@4.62.2:
- resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-linux-s390x-gnu@1.2.15':
optional: true
- /@rollup/rollup-linux-loong64-gnu@4.62.2:
- resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==}
- cpu: [loong64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-linux-x64-gnu@1.2.15':
optional: true
- /@rollup/rollup-linux-loong64-musl@4.62.2:
- resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==}
- cpu: [loong64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-linux-x64-musl@1.2.15':
optional: true
- /@rollup/rollup-linux-ppc64-gnu@4.62.2:
- resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-openharmony-arm64@1.2.15':
optional: true
- /@rollup/rollup-linux-ppc64-musl@4.62.2:
- resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-win32-arm64-msvc@1.2.15':
optional: true
- /@rollup/rollup-linux-riscv64-gnu@4.62.2:
- resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/binding-win32-x64-msvc@1.2.15':
optional: true
- /@rollup/rollup-linux-riscv64-musl@4.62.2:
- resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
+ '@rolldown/pluginutils@1.0.0-rc.7': {}
+
+ '@rolldown/pluginutils@1.0.1': {}
+
+ '@rollup/rollup-android-arm-eabi@4.65.1':
optional: true
- /@rollup/rollup-linux-s390x-gnu@4.62.2:
- resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
+ '@rollup/rollup-android-arm64@4.65.1':
optional: true
- /@rollup/rollup-linux-x64-gnu@4.62.2:
- resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
+ '@rollup/rollup-darwin-arm64@4.65.1':
optional: true
- /@rollup/rollup-linux-x64-musl@4.62.2:
- resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
+ '@rollup/rollup-darwin-x64@4.65.1':
optional: true
- /@rollup/rollup-openbsd-x64@4.62.2:
- resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==}
- cpu: [x64]
- os: [openbsd]
- requiresBuild: true
+ '@rollup/rollup-freebsd-arm64@4.65.1':
optional: true
- /@rollup/rollup-openharmony-arm64@4.62.2:
- resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==}
- cpu: [arm64]
- os: [openharmony]
- requiresBuild: true
+ '@rollup/rollup-freebsd-x64@4.65.1':
optional: true
- /@rollup/rollup-win32-arm64-msvc@4.62.2:
- resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
+ '@rollup/rollup-linux-arm-gnueabihf@4.65.1':
optional: true
- /@rollup/rollup-win32-ia32-msvc@4.62.2:
- resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
+ '@rollup/rollup-linux-arm-musleabihf@4.65.1':
optional: true
- /@rollup/rollup-win32-x64-gnu@4.62.2:
- resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
+ '@rollup/rollup-linux-arm64-gnu@4.65.1':
optional: true
- /@rollup/rollup-win32-x64-msvc@4.62.2:
- resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
+ '@rollup/rollup-linux-arm64-musl@4.65.1':
optional: true
- /@smithy/config-resolver@4.6.8:
- resolution: {integrity: sha512-jNAgbTd8u1bHkAu9fvIpq2rMVXTVm8DylDM59kUS9J94zBZLcdA7j+Vhc+RYg/8PVlNAPAQTGMjpgPqeYmRzcg==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-loong64-gnu@4.65.1':
+ optional: true
- /@smithy/core@3.29.3:
- resolution: {integrity: sha512-L+Ys6ecjk5vwPMAKHBpPKlJ3DkqwNcnfEISXBZIsVvWG/XKXfsAP8mwIYlTeLcd2ElHdesPI8OuOmJSFAPhm6A==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-loong64-musl@4.65.1':
+ optional: true
- /@smithy/credential-provider-imds@4.4.8:
- resolution: {integrity: sha512-q9J7JTiXrAhB8sDp4px97uEPT7CwKH61Co78grdNQvU8QZAdiuaSRhP0tUVf2ogy36RZTrlMU1rBmDEH+cnkiA==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-ppc64-gnu@4.65.1':
+ optional: true
- /@smithy/eventstream-serde-browser@4.4.8:
- resolution: {integrity: sha512-2ZZe4NSupcDg2UKLpnsuBEOA9yLbZ9ZmYc64HCYPYbvBHg62P8+FUmzkhvwtXm9uLKM3MoUxHw2WID/QzNOe1Q==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-ppc64-musl@4.65.1':
+ optional: true
- /@smithy/eventstream-serde-config-resolver@4.5.8:
- resolution: {integrity: sha512-y08FJiync2Z2r5/srXEjo7GJVVpBHB8iNb5x3nYTaVqbQ9AjnUvU3C/0U00IEE+6g77JQJ66gC6XS+ZrAVLWnQ==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-riscv64-gnu@4.65.1':
+ optional: true
- /@smithy/eventstream-serde-node@4.4.8:
- resolution: {integrity: sha512-wm8iDHlXpjmJVL8bcmjsW3mfgn4RVZKh2Wai6Ta1Vp/e+H7n1ZLobeBjFTqcJikbwx9prXz1QJzB5Z1h8YUZWg==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-riscv64-musl@4.65.1':
+ optional: true
- /@smithy/fetch-http-handler@5.6.5:
- resolution: {integrity: sha512-SuqeisTyPoiIPtIYru/sGxGyXzmZ+8nnFOhC+qRPglt06Ebd1yH//CDltZB2J/3WBNVhwfUaZ0EtHB3cm2X32g==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- '@smithy/types': 4.16.1
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-s390x-gnu@4.65.1':
+ optional: true
- /@smithy/hash-blob-browser@4.4.8:
- resolution: {integrity: sha512-2CpwBLTKiO+SDXRET2aCQF4BTA+X7DY9fCk3LE2Vm2HUaRxcIRjfMJWZaUwvPEtPamMQ/ypXZNgSKQhE/geEew==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-x64-gnu@4.65.1':
+ optional: true
- /@smithy/hash-node@4.4.8:
- resolution: {integrity: sha512-vJDrMFt3Q02naTTveiv1WFJpI1z6fEs+TH2UdcxNoJhqTFR1YNAz+rhwEDzgKGkqPF/0fhWl6SG6jePB1EgydQ==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-linux-x64-musl@4.65.1':
+ optional: true
- /@smithy/hash-stream-node@4.4.8:
- resolution: {integrity: sha512-Ep1oWvzaUI1AcL4uY9WDbCUMhvcuMINIYV/5J1A0LWZyMaitQ/8zX5GD1fAEsEZcX+YSSkEcqhyfYjz394r9Qw==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-openbsd-x64@4.65.1':
+ optional: true
- /@smithy/invalid-dependency@4.4.8:
- resolution: {integrity: sha512-xqzcxU2pMl17yQ5bvJbsiiTua/wgt5VluguIOW9kCGCBhBazkwceLj9BlH883K0ASxZAhftvRmp7wTRg1ZbpKg==}
- engines: {node: '>=18.0.0'}
- dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-openharmony-arm64@4.65.1':
+ optional: true
- /@smithy/is-array-buffer@2.2.0:
- resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==}
- engines: {node: '>=14.0.0'}
- dependencies:
- tslib: 2.8.1
- dev: false
+ '@rollup/rollup-win32-arm64-msvc@4.65.1':
+ optional: true
- /@smithy/is-array-buffer@4.4.8:
- resolution: {integrity: sha512-RoxyFKZVk+UVz51s1PIyjtVUhwTYlAaT78Xpzix7w5gflovJoJO7eqFxWK0Vg3BM3EbPh8NPLlwLPXsiYdBXoA==}
- engines: {node: '>=18.0.0'}
+ '@rollup/rollup-win32-ia32-msvc@4.65.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.65.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.65.1':
+ optional: true
+
+ '@shikijs/core@4.5.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@shikijs/primitive': 4.5.0
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
+ hast-util-to-html: 9.0.5
- /@smithy/md5-js@4.4.8:
- resolution: {integrity: sha512-fT0Sdjr7cMyb0l13lRr32ItpDiHgMig2w/JFzYqyo7n7MsvXTpCmtCaNXEinm6+xK3Jn9gwiXUVLOkI66xJ9gQ==}
- engines: {node: '>=18.0.0'}
+ '@shikijs/engine-javascript@4.5.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ oniguruma-to-es: 4.3.6
- /@smithy/middleware-content-length@4.4.8:
- resolution: {integrity: sha512-qLNmtCNnB6kdZu5AiC9p7MrPJS9lFOjOKazpuDPkEqAPSAlAKq7ipgoyMLb1CBxi3rzNUcrvjvqo/B0lpsTxIw==}
- engines: {node: '>=18.0.0'}
+ '@shikijs/engine-oniguruma@4.5.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
- /@smithy/middleware-endpoint@4.6.8:
- resolution: {integrity: sha512-9tOPEQz4g8Xv1t5UEwL0KmQ6Z4U4WS5Q1EXOSUePGt2pgqOWli7zLxmCFkZtEutZLSsIWtDHwbHyhVfclkMs1Q==}
- engines: {node: '>=18.0.0'}
+ '@shikijs/langs@4.5.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@shikijs/types': 4.5.0
- /@smithy/middleware-retry@4.7.8:
- resolution: {integrity: sha512-oEPZ4i9E7h5GgtASPr6QoZdt8XCkjcjgj7lhEkWEHnMwUftz9FQ9FGOztek4wnoOuB1LxA6eO+gO1ORAGUeL6A==}
- engines: {node: '>=18.0.0'}
+ '@shikijs/primitive@4.5.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
- /@smithy/middleware-serde@4.4.8:
- resolution: {integrity: sha512-qAH6hKorKtjV2lPiEOEB58edF/NvY29twTu1aGOwSQx8lGjhomF+Z7xpBhJH8v4IGUMSP0aUA+N9N4IpE9xpkg==}
- engines: {node: '>=18.0.0'}
+ '@shikijs/themes@4.5.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@shikijs/types': 4.5.0
- /@smithy/middleware-stack@4.4.8:
- resolution: {integrity: sha512-I8NOxdzliRUdniI4/QTEfXj5jonF2aILJOIGkcV4ZWeqMMP98ySKg4SeiIN1WAnLJUxjHNr7UnMUcPegxFtxMw==}
- engines: {node: '>=18.0.0'}
+ '@shikijs/types@4.5.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
- /@smithy/node-config-provider@4.5.8:
- resolution: {integrity: sha512-Kran9kcysdZdoiVZQ3EXfHTbZ48kJ6Er2sZ4eHaL2LSsqVlucn/8xrgxj36/z9qlrToNGNf+na4u6xp1Nz08KQ==}
- engines: {node: '>=18.0.0'}
+ '@shikijs/vscode-textmate@10.1.0': {}
+
+ '@shuding/opentype.js@1.4.0-beta.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ fflate: 0.7.3
+ string.prototype.codepointat: 0.2.1
- /@smithy/node-http-handler@4.9.5:
- resolution: {integrity: sha512-bNqdxTQTxmLbomSmlkZFz8L6B/feQ2HHzw4L2zY7Ecp2XffYAZq2uzdWDdxJHJFbEvqd+SRuluJso0P8+xPdbw==}
- engines: {node: '>=18.0.0'}
+ '@sindresorhus/is@7.2.0': {}
+
+ '@smithy/core@3.37.0':
dependencies:
- '@smithy/core': 3.29.3
- '@smithy/types': 4.16.1
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@smithy/property-provider@4.4.8:
- resolution: {integrity: sha512-1K3cVMiSnjiy4ht6+WmmevAOuYVwbrfSvKtIaoaK4brpERrv9B4dediHo1N1upvx2brt+s84e1SmAeCQm8hMqQ==}
- engines: {node: '>=18.0.0'}
+ '@smithy/credential-provider-imds@4.5.2':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@smithy/protocol-http@5.5.8:
- resolution: {integrity: sha512-SyFyL/ajuzJ79W+BpseFFbSz8/Rwj+QGqUlayeZE0jS2aCcjzV5tJBcbHgfypvSHpe7s2JmUHZmfpICaxwEs5g==}
- engines: {node: '>=18.0.0'}
+ '@smithy/fetch-http-handler@5.8.0':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@smithy/querystring-builder@4.4.8:
- resolution: {integrity: sha512-BF7L8ELX66L6g/WGWz0eAocp4i7xx51WbyDEnVffYP/s8q/+uFSCBpcOQlZGIQxpSrrhJnlBbS/xkIxYJKj+hg==}
- engines: {node: '>=18.0.0'}
+ '@smithy/node-http-handler@4.13.0':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@smithy/shared-ini-file-loader@4.6.8:
- resolution: {integrity: sha512-zsd1RYVrnWcByRhYrSYcDKCV9MfU5o33uSaksVkVgaeS6QMm6PMEa1AhKX0zrQrwsFVfpwhIbA3nxnFOLf61CA==}
- engines: {node: '>=18.0.0'}
+ '@smithy/signature-v4@5.7.4':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.37.0
+ '@smithy/types': 4.19.0
tslib: 2.8.1
- dev: false
- /@smithy/signature-v4@5.6.4:
- resolution: {integrity: sha512-B89bpf2t/y/wia6LZ+4JfHXYQT9PnVftsH05rgJKKIStS7r/4XSs9HOjtPoLtgcA6HCW9jVqX5DBbq7E0PAkiQ==}
- engines: {node: '>=18.0.0'}
+ '@smithy/types@4.19.0':
dependencies:
- '@smithy/core': 3.29.3
- '@smithy/types': 4.16.1
tslib: 2.8.1
- dev: false
- /@smithy/smithy-client@4.14.8:
- resolution: {integrity: sha512-hnZ6wFwLHQYL/+wdvT6qD1Fkiclobv7Y3iBB2fyfr+osJcD5n4IMAOPaIFUj7WgxOwU/e13FubyebUigzMLXCQ==}
- engines: {node: '>=18.0.0'}
+ '@speed-highlight/core@1.2.24': {}
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@swc/counter@0.1.3': {}
+
+ '@swc/helpers@0.5.23':
dependencies:
- '@smithy/core': 3.29.3
- '@smithy/types': 4.16.1
tslib: 2.8.1
- dev: false
- /@smithy/types@4.16.1:
- resolution: {integrity: sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==}
- engines: {node: '>=18.0.0'}
+ '@swc/helpers@0.5.5':
dependencies:
+ '@swc/counter': 0.1.3
tslib: 2.8.1
- dev: false
- /@smithy/url-parser@4.4.8:
- resolution: {integrity: sha512-BcniaGClLgBsy5Jf7dfkoId8B4n/8oL3xBzVeF1/I252yZvyrxyKG7ZvcfCGTGEahSigsz40ujf6R/3G1U0kig==}
- engines: {node: '>=18.0.0'}
+ '@tailwindcss/node@4.3.3':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@jridgewell/remapping': 2.3.5
+ enhanced-resolve: 5.26.0
+ jiti: 2.7.0
+ lightningcss: 1.32.0
+ magic-string: 0.30.21
+ source-map-js: 1.2.2
+ tailwindcss: 4.3.3
- /@smithy/util-base64@4.5.8:
- resolution: {integrity: sha512-vJ3w2vD2BzEGbnMfaBcrtPXi37IUtG9qQgVasMRiF+Ef+0S5fMgaEFcwBGYg7RkN7wKBAcg2r+ulF/4aj3+VYw==}
- engines: {node: '>=18.0.0'}
+ '@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/postcss@4.3.3':
+ dependencies:
+ '@alloc/quick-lru': 5.3.0
+ '@tailwindcss/node': 4.3.3
+ '@tailwindcss/oxide': 4.3.3
+ postcss: 8.5.32
+ tailwindcss: 4.3.3
+
+ '@turbo/darwin-64@2.11.10':
+ optional: true
+
+ '@turbo/darwin-arm64@2.11.10':
+ optional: true
+
+ '@turbo/gen@2.11.10(@types/node@20.14.11)':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@inquirer/prompts': 7.10.1(@types/node@20.14.11)
+ esbuild: 0.28.2
+ transitivePeerDependencies:
+ - '@types/node'
- /@smithy/util-body-length-browser@4.4.8:
- resolution: {integrity: sha512-o6rhfnt15hwj2/1KjQ0PsvdEpxG9TYzR8pk6K0XnrtUDCJcWREq6uCSVHboRsOdghdp3zaVY5CfYV+wUvDUdrg==}
- engines: {node: '>=18.0.0'}
+ '@turbo/linux-64@2.11.10':
+ optional: true
+
+ '@turbo/linux-arm64@2.11.10':
+ optional: true
+
+ '@turbo/windows-64@2.11.10':
+ optional: true
+
+ '@turbo/windows-arm64@2.11.10':
+ optional: true
+
+ '@types/chai@5.2.3':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
- /@smithy/util-body-length-node@4.4.8:
- resolution: {integrity: sha512-HoShD7ykB2wBA98UyyKGLUUKmsHovubDzGmCmpMemrTCICKHdfMsUyngJFEPEiJ2ujtRDEgpQD04cDOYY9u9rQ==}
- engines: {node: '>=18.0.0'}
+ '@types/debug@4.1.13':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@types/ms': 2.1.0
- /@smithy/util-buffer-from@2.2.0:
- resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==}
- engines: {node: '>=14.0.0'}
+ '@types/deep-eql@4.0.2': {}
+
+ '@types/emscripten@1.41.6': {}
+
+ '@types/esrecurse@4.3.1': {}
+
+ '@types/estree-jsx@1.0.5':
dependencies:
- '@smithy/is-array-buffer': 2.2.0
- tslib: 2.8.1
- dev: false
+ '@types/estree': 1.0.9
- /@smithy/util-config-provider@4.4.8:
- resolution: {integrity: sha512-OjkEu21jGJ5dI0PUoiSRjhmQJwXxnQbk3GDUoNkAADYsJFjx24PahQtIXYZuG+1tE/Y6Qpiqhz3xCz/yhpA4TA==}
- engines: {node: '>=18.0.0'}
+ '@types/estree@1.0.9': {}
+
+ '@types/hast@3.0.5':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@types/unist': 3.0.3
- /@smithy/util-defaults-mode-browser@4.5.8:
- resolution: {integrity: sha512-QjnRq1unlnaEq+z8ksNzg8Q6+IozO6z9QxyZXCKcarJquEfbqq4NZ2XQgYlCgQWK8f6GOyCdw84ju9E6GJDj9Q==}
- engines: {node: '>=18.0.0'}
+ '@types/json-schema@7.0.15': {}
+
+ '@types/mdast@4.0.4':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@types/unist': 3.0.3
- /@smithy/util-defaults-mode-node@4.4.8:
- resolution: {integrity: sha512-xNA1Wfkpq8yQmICs1RyXze+ZUKrRP1YlTqDXFE9YAMUeDy+rTuTx/Id5NRzWpkTYqW7205VAHcy6lu/13JAEbg==}
- engines: {node: '>=18.0.0'}
+ '@types/mdx@2.0.14': {}
+
+ '@types/ms@2.1.0': {}
+
+ '@types/node@20.14.11':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ undici-types: 5.26.5
- /@smithy/util-endpoints@3.6.8:
- resolution: {integrity: sha512-KbkiYv00N9RbQVMm/k9ftoC9jWqCf+h9NBVN+ekbRKs5B+Dtzzkwhgfe1a+bn6ftaIkTF0V0d5IqGLb2ZL6Cvg==}
- engines: {node: '>=18.0.0'}
+ '@types/node@22.18.6':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ undici-types: 6.21.0
- /@smithy/util-middleware@4.4.8:
- resolution: {integrity: sha512-+N4NUzQgfqSwj9weJMcdnTXc9qEKOm/3XgRApX2G0eLU/fWt22GXdVxEBobZXU20OglTAOMuiUiiyEQoJ693bw==}
- engines: {node: '>=18.0.0'}
+ '@types/node@26.6.5':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ undici-types: 8.9.0
- /@smithy/util-retry@4.5.8:
- resolution: {integrity: sha512-fPHkNhF3rt3mJHarO7aKfBmGLMnu2NNfGlfCPm/EUNHPGkrdzsdIsPXEgjd+RSEt6FpI93wlMH1XdtaG/XdWWQ==}
- engines: {node: '>=18.0.0'}
+ '@types/prop-types@15.7.15': {}
+
+ '@types/react-dom@18.3.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@types/react': 19.3.0
- /@smithy/util-stream@4.7.8:
- resolution: {integrity: sha512-YmIDkEKLkHEqqYK5AnaBtyS3jCSEIyRaAm9u7sPrYQHUGGQUjfpWT+KdyEBQnKeVpXQnIlG3GKIY2sdpv4xVpA==}
- engines: {node: '>=18.0.0'}
+ '@types/react-dom@19.3.0(@types/react@19.3.0)':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@types/react': 19.3.0
- /@smithy/util-utf8@2.3.0:
- resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==}
- engines: {node: '>=14.0.0'}
+ '@types/react@18.3.3':
dependencies:
- '@smithy/util-buffer-from': 2.2.0
- tslib: 2.8.1
- dev: false
+ '@types/prop-types': 15.7.15
+ csstype: 3.2.3
- /@smithy/util-utf8@4.4.8:
- resolution: {integrity: sha512-hwVELJTTRUqwrEvMI73PwsP27cO1HgkAKDoKelhMS3biTd8z5iXj76UF7oemuDba3X5eHZqjedeyBUhJLns+Kg==}
- engines: {node: '>=18.0.0'}
+ '@types/react@19.3.0':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ csstype: 3.2.3
- /@smithy/util-waiter@4.5.8:
- resolution: {integrity: sha512-NIDD7WY1PrRDNvI80N1dBTDZQ4vAiYln8zfbJ5dfZmtlqyP7aJNJqtuaZQXWd5mqy+NZKUvp+FgnEq2Hm4ebXA==}
- engines: {node: '>=18.0.0'}
+ '@types/unist@2.0.11': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@types/ws@8.18.2':
dependencies:
- '@smithy/core': 3.29.3
- tslib: 2.8.1
- dev: false
+ '@types/node': 22.18.6
- /@standard-schema/spec@1.1.0:
- resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
- dev: false
+ '@typescript/typescript-aix-ppc64@7.0.2':
+ optional: true
- /@swc/counter@0.1.3:
- resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+ '@typescript/typescript-darwin-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-darwin-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-freebsd-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-freebsd-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-arm64@7.0.2':
+ optional: true
- /@swc/helpers@0.5.5:
- resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
- dependencies:
- '@swc/counter': 0.1.3
- tslib: 2.8.1
+ '@typescript/typescript-linux-arm@7.0.2':
+ optional: true
- /@tootallnate/quickjs-emscripten@0.23.0:
- resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
- dev: true
+ '@typescript/typescript-linux-loong64@7.0.2':
+ optional: true
- /@tsconfig/node10@1.0.12:
- resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==}
- dev: true
+ '@typescript/typescript-linux-mips64el@7.0.2':
+ optional: true
- /@tsconfig/node12@1.0.11:
- resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
- dev: true
+ '@typescript/typescript-linux-ppc64@7.0.2':
+ optional: true
- /@tsconfig/node14@1.0.3:
- resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
- dev: true
+ '@typescript/typescript-linux-riscv64@7.0.2':
+ optional: true
- /@tsconfig/node16@1.0.4:
- resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
- dev: true
+ '@typescript/typescript-linux-s390x@7.0.2':
+ optional: true
- /@turbo/gen@2.0.9(@types/node@20.14.11)(typescript@5.9.3):
- resolution: {integrity: sha512-IVCBa/+qxsO7srAvFpto0AF09Zei+zpDoosUsHSEwgn/22rVuZ6hdcJdxcQ9kHeMafJpxqLK9iHNSdXUctJ0Vw==}
- hasBin: true
- dependencies:
- '@turbo/workspaces': 2.0.9(@types/node@20.14.11)
- commander: 10.0.1
- fs-extra: 10.1.0
- inquirer: 8.2.7(@types/node@20.14.11)
- minimatch: 9.0.9
- node-plop: 0.26.3
- picocolors: 1.0.1
- proxy-agent: 6.5.0
- ts-node: 10.9.2(@types/node@20.14.11)(typescript@5.9.3)
- update-check: 1.5.4
- validate-npm-package-name: 5.0.1
- transitivePeerDependencies:
- - '@swc/core'
- - '@swc/wasm'
- - '@types/node'
- - supports-color
- - typescript
- dev: true
+ '@typescript/typescript-linux-x64@7.0.2':
+ optional: true
- /@turbo/workspaces@2.0.9(@types/node@20.14.11):
- resolution: {integrity: sha512-+OTrQULhuv1qOKE+0DC360sSDB6ad7opEKLGFcLlmLgM7D75qv6UThfnw1Rjh8inIlBSSCCu/co2BaJjgkkpAw==}
- hasBin: true
- dependencies:
- commander: 10.0.1
- execa: 5.1.1
- fast-glob: 3.3.3
- fs-extra: 10.1.0
- gradient-string: 2.0.2
- inquirer: 8.2.7(@types/node@20.14.11)
- js-yaml: 4.3.0
- ora: 4.1.1
- picocolors: 1.0.1
- rimraf: 3.0.2
- semver: 7.8.5
- update-check: 1.5.4
- transitivePeerDependencies:
- - '@types/node'
- dev: true
+ '@typescript/typescript-netbsd-arm64@7.0.2':
+ optional: true
- /@types/chai@5.2.3:
- resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
- dependencies:
- '@types/deep-eql': 4.0.2
- assertion-error: 2.0.1
+ '@typescript/typescript-netbsd-x64@7.0.2':
+ optional: true
- /@types/deep-eql@4.0.2:
- resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+ '@typescript/typescript-openbsd-arm64@7.0.2':
+ optional: true
- /@types/dom-webcodecs@0.1.11:
- resolution: {integrity: sha512-yPEZ3z7EohrmOxbk/QTAa0yonMFkNkjnVXqbGb7D4rMr+F1dGQ8ZUFxXkyLLJuiICPejZ0AZE9Rrk9wUCczx4A==}
- dev: false
+ '@typescript/typescript-openbsd-x64@7.0.2':
+ optional: true
- /@types/emscripten@1.41.5:
- resolution: {integrity: sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==}
- dev: false
+ '@typescript/typescript-sunos-x64@7.0.2':
+ optional: true
- /@types/estree@1.0.9:
- resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+ '@typescript/typescript-win32-arm64@7.0.2':
+ optional: true
- /@types/glob@7.2.0:
- resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==}
- dependencies:
- '@types/minimatch': 6.0.0
- '@types/node': 22.18.6
- dev: true
+ '@typescript/typescript-win32-x64@7.0.2':
+ optional: true
- /@types/inquirer@6.5.0:
- resolution: {integrity: sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==}
- dependencies:
- '@types/through': 0.0.33
- rxjs: 6.6.7
- dev: true
+ '@ungap/structured-clone@1.4.0': {}
- /@types/minimatch@6.0.0:
- resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==}
- deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed.
+ '@unpic/core@1.0.3':
dependencies:
- minimatch: 9.0.9
- dev: true
+ unpic: 4.2.2
- /@types/node@20.14.11:
- resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==}
+ '@unpic/react@1.0.2(next@14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
dependencies:
- undici-types: 5.26.5
- dev: true
+ '@unpic/core': 1.0.3
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ optionalDependencies:
+ next: 14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
- /@types/node@22.18.6:
- resolution: {integrity: sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==}
+ '@vercel/og@1.0.3(@types/node@22.18.6)':
dependencies:
- undici-types: 6.21.0
-
- /@types/prop-types@15.7.15:
- resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
+ '@resvg/resvg-wasm': 2.4.1
+ satori: 0.33.5
+ optionalDependencies:
+ sharp: 0.35.5(@types/node@22.18.6)
+ transitivePeerDependencies:
+ - '@types/node'
- /@types/react-dom@18.3.0:
- resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
- dependencies:
- '@types/react': 18.3.3
+ '@vinext/types@1.0.2': {}
- /@types/react@18.3.3:
- resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==}
+ '@vitejs/plugin-react@6.0.1(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))':
dependencies:
- '@types/prop-types': 15.7.15
- csstype: 3.2.3
+ '@rolldown/pluginutils': 1.0.0-rc.7
+ vite: 8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)
- /@types/through@0.0.33:
- resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==}
+ '@vitejs/plugin-rsc@0.5.38(react-dom@19.3.1(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))))(react@19.3.1)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))':
dependencies:
- '@types/node': 22.18.6
- dev: true
-
- /@types/tinycolor2@1.4.6:
- resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==}
- dev: true
+ '@rolldown/pluginutils': 1.0.1
+ es-module-lexer: 3.0.4
+ estree-walker: 3.0.3
+ magic-string: 1.4.4
+ obug: 3.0.0
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ srvx: 1.0.7
+ strip-literal: 4.0.0
+ turbo-stream: 3.2.1
+ vite: 8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)
+ vitefu: 1.1.3(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))
+ optionalDependencies:
+ react-server-dom-webpack: 19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6)))
- /@vitest/expect@3.2.4:
- resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==}
+ '@vitest/expect@3.2.7':
dependencies:
'@types/chai': 5.2.3
- '@vitest/spy': 3.2.4
- '@vitest/utils': 3.2.4
+ '@vitest/spy': 3.2.7
+ '@vitest/utils': 3.2.7
chai: 5.3.3
tinyrainbow: 2.0.0
- /@vitest/mocker@3.2.4(vite@7.3.6):
- resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==}
- peerDependencies:
- msw: ^2.4.9
- vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0
- peerDependenciesMeta:
- msw:
- optional: true
- vite:
- optional: true
+ '@vitest/mocker@3.2.7(vite@7.3.7(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))':
dependencies:
- '@vitest/spy': 3.2.4
+ '@vitest/spy': 3.2.7
estree-walker: 3.0.3
magic-string: 0.30.21
- vite: 7.3.6(@types/node@22.18.6)(jiti@2.4.2)
+ optionalDependencies:
+ vite: 7.3.7(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
- /@vitest/pretty-format@3.2.4:
- resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==}
+ '@vitest/mocker@3.2.7(vite@7.3.7(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))':
dependencies:
- tinyrainbow: 2.0.0
+ '@vitest/spy': 3.2.7
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 7.3.7(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
- /@vitest/pretty-format@3.2.7:
- resolution: {integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==}
+ '@vitest/mocker@3.2.7(vite@7.3.7(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))':
+ dependencies:
+ '@vitest/spy': 3.2.7
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 7.3.7(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
+
+ '@vitest/pretty-format@3.2.7':
dependencies:
tinyrainbow: 2.0.0
- /@vitest/runner@3.2.4:
- resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==}
+ '@vitest/runner@3.2.7':
dependencies:
- '@vitest/utils': 3.2.4
+ '@vitest/utils': 3.2.7
pathe: 2.0.3
strip-literal: 3.1.0
- /@vitest/snapshot@3.2.4:
- resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==}
+ '@vitest/snapshot@3.2.7':
dependencies:
- '@vitest/pretty-format': 3.2.4
+ '@vitest/pretty-format': 3.2.7
magic-string: 0.30.21
pathe: 2.0.3
- /@vitest/spy@3.2.4:
- resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==}
+ '@vitest/spy@3.2.7':
dependencies:
- tinyspy: 4.0.4
+ tinyspy: 4.0.6
- /@vitest/utils@3.2.4:
- resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==}
+ '@vitest/utils@3.2.7':
dependencies:
- '@vitest/pretty-format': 3.2.4
+ '@vitest/pretty-format': 3.2.7
loupe: 3.2.1
tinyrainbow: 2.0.0
- /@yudiel/react-qr-scanner@2.1.0(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-O3832Qk8YU+vnLO+tsJalfQcXRZ1pOB9l6WrI3OdwpxkQEzukpT48M6Hc2vUUe1rFE6qapQnV3RGRFNM0S7CHw==}
- peerDependencies:
- react: ^17 || ^18 || ^19
- react-dom: ^17 || ^18 || ^19
+ '@webassemblyjs/ast@1.14.1':
dependencies:
- barcode-detector: 2.3.1
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- webrtc-adapter: 9.0.1
- dev: false
+ '@webassemblyjs/helper-numbers': 1.13.2
+ '@webassemblyjs/helper-wasm-bytecode': 1.13.2
- /acorn-jsx@5.3.2(acorn@8.17.0):
- resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
- peerDependencies:
- acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ '@webassemblyjs/floating-point-hex-parser@1.13.2': {}
+
+ '@webassemblyjs/helper-api-error@1.13.2': {}
+
+ '@webassemblyjs/helper-buffer@1.14.1': {}
+
+ '@webassemblyjs/helper-numbers@1.13.2':
dependencies:
- acorn: 8.17.0
- dev: true
+ '@webassemblyjs/floating-point-hex-parser': 1.13.2
+ '@webassemblyjs/helper-api-error': 1.13.2
+ '@xtuc/long': 4.2.2
- /acorn-walk@8.3.5:
- resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==}
- engines: {node: '>=0.4.0'}
+ '@webassemblyjs/helper-wasm-bytecode@1.13.2': {}
+
+ '@webassemblyjs/helper-wasm-section@1.14.1':
dependencies:
- acorn: 8.17.0
- dev: true
+ '@webassemblyjs/ast': 1.14.1
+ '@webassemblyjs/helper-buffer': 1.14.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.13.2
+ '@webassemblyjs/wasm-gen': 1.14.1
- /acorn@8.17.0:
- resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==}
- engines: {node: '>=0.4.0'}
- hasBin: true
- dev: true
+ '@webassemblyjs/ieee754@1.13.2':
+ dependencies:
+ '@xtuc/ieee754': 1.2.0
- /agent-base@7.1.4:
- resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
- engines: {node: '>= 14'}
- dev: true
+ '@webassemblyjs/leb128@1.13.2':
+ dependencies:
+ '@xtuc/long': 4.2.2
- /aggregate-error@3.1.0:
- resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
- engines: {node: '>=8'}
+ '@webassemblyjs/utf8@1.13.2': {}
+
+ '@webassemblyjs/wasm-edit@1.14.1':
dependencies:
- clean-stack: 2.2.0
- indent-string: 4.0.0
- dev: true
+ '@webassemblyjs/ast': 1.14.1
+ '@webassemblyjs/helper-buffer': 1.14.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.13.2
+ '@webassemblyjs/helper-wasm-section': 1.14.1
+ '@webassemblyjs/wasm-gen': 1.14.1
+ '@webassemblyjs/wasm-opt': 1.14.1
+ '@webassemblyjs/wasm-parser': 1.14.1
+ '@webassemblyjs/wast-printer': 1.14.1
- /ajv@6.15.0:
- resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
+ '@webassemblyjs/wasm-gen@1.14.1':
dependencies:
- fast-deep-equal: 3.1.3
- fast-json-stable-stringify: 2.1.0
- json-schema-traverse: 0.4.1
- uri-js: 4.4.1
- dev: true
+ '@webassemblyjs/ast': 1.14.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.13.2
+ '@webassemblyjs/ieee754': 1.13.2
+ '@webassemblyjs/leb128': 1.13.2
+ '@webassemblyjs/utf8': 1.13.2
- /ansi-escapes@4.3.2:
- resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
- engines: {node: '>=8'}
+ '@webassemblyjs/wasm-opt@1.14.1':
dependencies:
- type-fest: 0.21.3
- dev: true
+ '@webassemblyjs/ast': 1.14.1
+ '@webassemblyjs/helper-buffer': 1.14.1
+ '@webassemblyjs/wasm-gen': 1.14.1
+ '@webassemblyjs/wasm-parser': 1.14.1
- /ansi-regex@5.0.1:
- resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
- engines: {node: '>=8'}
- dev: true
+ '@webassemblyjs/wasm-parser@1.14.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.14.1
+ '@webassemblyjs/helper-api-error': 1.13.2
+ '@webassemblyjs/helper-wasm-bytecode': 1.13.2
+ '@webassemblyjs/ieee754': 1.13.2
+ '@webassemblyjs/leb128': 1.13.2
+ '@webassemblyjs/utf8': 1.13.2
- /ansi-styles@3.2.1:
- resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
- engines: {node: '>=4'}
+ '@webassemblyjs/wast-printer@1.14.1':
dependencies:
- color-convert: 1.9.3
- dev: true
+ '@webassemblyjs/ast': 1.14.1
+ '@xtuc/long': 4.2.2
- /ansi-styles@4.3.0:
- resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
- engines: {node: '>=8'}
+ '@xtuc/ieee754@1.2.0': {}
+
+ '@xtuc/long@4.2.2': {}
+
+ '@yudiel/react-qr-scanner@2.6.0(@types/emscripten@1.41.6)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- color-convert: 2.0.1
- dev: true
+ '@types/react': 18.3.3
+ barcode-detector: 3.2.3(@types/emscripten@1.41.6)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ webrtc-adapter: 9.0.6
+ transitivePeerDependencies:
+ - '@types/emscripten'
- /any-promise@1.3.0:
- resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
- dev: true
+ '@yuku-core/binding-android-arm64@0.19.0':
+ optional: true
- /anymatch@3.1.3:
- resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
- engines: {node: '>= 8'}
+ '@yuku-core/binding-darwin-arm64@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-darwin-x64@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-freebsd-x64@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-linux-arm-gnu@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-linux-arm-musl@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-linux-arm64-gnu@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-linux-arm64-musl@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-linux-x64-gnu@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-linux-x64-musl@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-win32-arm64@0.19.0':
+ optional: true
+
+ '@yuku-core/binding-win32-x64@0.19.0':
+ optional: true
+
+ '@yuku-toolchain/types@0.19.0': {}
+
+ '@zeit/schemas@2.36.0': {}
+
+ acorn-jsx@5.3.2(acorn@8.19.0):
dependencies:
- normalize-path: 3.0.0
- picomatch: 2.3.2
- dev: true
+ acorn: 8.19.0
- /arg@4.1.3:
- resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
- dev: true
+ acorn-loose@8.5.2:
+ dependencies:
+ acorn: 8.19.0
- /arg@5.0.2:
- resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
- dev: true
+ acorn@8.19.0: {}
- /argparse@2.0.1:
- resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
- dev: true
+ ajv-formats@3.0.1:
+ dependencies:
+ ajv: 8.20.0
- /aria-hidden@1.2.6:
- resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
- engines: {node: '>=10'}
+ ajv-keywords@5.1.0(ajv@8.20.0):
dependencies:
- tslib: 2.8.1
- dev: false
+ ajv: 8.20.0
+ fast-deep-equal: 3.1.3
- /array-union@2.1.0:
- resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
- engines: {node: '>=8'}
- dev: true
+ ajv@6.15.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
- /assertion-error@2.0.1:
- resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
- engines: {node: '>=12'}
+ ajv@8.18.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.9
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
- /ast-types@0.13.4:
- resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
- engines: {node: '>=4'}
+ ajv@8.20.0:
dependencies:
- tslib: 2.8.1
- dev: true
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.9
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
- /autoprefixer@10.4.19(postcss@8.4.39):
- resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
- engines: {node: ^10 || ^12 || >=14}
- hasBin: true
- peerDependencies:
- postcss: ^8.1.0
+ ansi-align@3.0.1:
dependencies:
- browserslist: 4.28.5
- caniuse-lite: 1.0.30001803
- fraction.js: 4.3.7
- normalize-range: 0.1.2
- picocolors: 1.1.1
- postcss: 8.4.39
- postcss-value-parser: 4.2.0
- dev: true
+ string-width: 4.2.3
- /aws-ssl-profiles@1.1.2:
- resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==}
- engines: {node: '>= 6.0.0'}
- dev: false
+ ansi-regex@5.0.1: {}
- /balanced-match@1.0.2:
- resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
- dev: true
+ ansi-regex@6.4.0: {}
- /barcode-detector@2.3.1:
- resolution: {integrity: sha512-D9KEtrquS1tmBZduxBZl8qublIKnRrFqD8TAHDYcLCyrHQBo+vitIxmjMJ61LvXjXyAMalOlO7q0Oh/9Rl2PbQ==}
+ ansi-styles@4.3.0:
dependencies:
- '@types/dom-webcodecs': 0.1.11
- zxing-wasm: 1.3.4
- dev: false
+ color-convert: 2.0.1
- /base64-js@1.5.1:
- resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
- dev: true
+ ansi-styles@6.2.3: {}
- /baseline-browser-mapping@2.10.42:
- resolution: {integrity: sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==}
- engines: {node: '>=6.0.0'}
- hasBin: true
- dev: true
+ any-promise@1.3.0: {}
- /basic-ftp@5.3.1:
- resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==}
- engines: {node: '>=10.0.0'}
- dev: true
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.2
- /better-auth@1.7.6(next@14.2.35)(pg@8.23.0)(react-dom@18.3.1)(react@18.3.1)(vitest@3.2.4):
- resolution: {integrity: sha512-WTMqOpmTTj+oBoX7zzPOzL85342Upyf+/v0IkH1kvGRA85lV4JGRFIYMIRKqvjZ6ShsuL5VX/c9C13jtoZXcKA==}
- peerDependencies:
- '@lynx-js/react': '*'
- '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
- '@sveltejs/kit': ^2.0.0
- '@tanstack/react-start': ^1.0.0
- '@tanstack/solid-start': ^1.0.0
- drizzle-kit: '>=0.31.4 || >=1.0.0-beta.1'
- drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
- mongodb: ^6.0.0 || ^7.0.0
- mysql2: ^3.0.0
- next: ^14.0.0 || ^15.0.0 || ^16.0.0
- pg: ^8.0.0
- prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
- react: ^18.0.0 || ^19.0.0
- react-dom: ^18.0.0 || ^19.0.0
- solid-js: ^1.0.0
- svelte: ^4.0.0 || ^5.0.0
- vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
- vue: ^3.0.0
- peerDependenciesMeta:
- '@lynx-js/react':
- optional: true
- '@prisma/client':
- optional: true
- '@sveltejs/kit':
- optional: true
- '@tanstack/react-start':
- optional: true
- '@tanstack/solid-start':
- optional: true
- drizzle-kit:
- optional: true
- drizzle-orm:
- optional: true
- mongodb:
- optional: true
- mysql2:
- optional: true
- next:
- optional: true
- pg:
- optional: true
- prisma:
- optional: true
- react:
- optional: true
- react-dom:
- optional: true
- solid-js:
- optional: true
- svelte:
- optional: true
- vitest:
- optional: true
- vue:
- optional: true
+ arch@2.2.0: {}
+
+ arg@5.0.2: {}
+
+ aria-hidden@1.2.6:
+ dependencies:
+ tslib: 2.8.1
+
+ assertion-error@2.0.1: {}
+
+ astring@1.9.0: {}
+
+ autoprefixer@10.4.19(postcss@8.4.39):
+ dependencies:
+ browserslist: 4.29.5
+ caniuse-lite: 1.0.30001819
+ fraction.js: 4.3.7
+ normalize-range: 0.1.2
+ picocolors: 1.1.1
+ postcss: 8.4.39
+ postcss-value-parser: 4.2.0
+
+ aws-ssl-profiles@1.1.2: {}
+
+ bail@2.0.2: {}
+
+ balanced-match@1.0.2: {}
+
+ balanced-match@4.0.4: {}
+
+ barcode-detector@3.2.3(@types/emscripten@1.41.6):
+ dependencies:
+ zxing-wasm: 3.1.6(@types/emscripten@1.41.6)
+ transitivePeerDependencies:
+ - '@types/emscripten'
+
+ base64-js@0.0.8: {}
+
+ baseline-browser-mapping@2.11.33: {}
+
+ better-auth@1.7.6(mysql2@3.24.4(@types/node@20.14.11))(next@16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)):
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@3.25.76))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/drizzle-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/kysely-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(kysely@0.29.6)
+ '@better-auth/memory-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/mongo-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/prisma-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/telemetry': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+ '@noble/ciphers': 2.4.0
+ '@noble/hashes': 2.4.0
+ better-call: 1.4.0(zod@4.6.7)
+ defu: 6.1.7
+ jose: 6.2.13
+ kysely: 0.29.6
+ nanostores: 1.5.5
+ zod: 4.6.7
+ optionalDependencies:
+ mysql2: 3.24.4(@types/node@20.14.11)
+ next: 16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ pg: 8.23.0
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ vitest: 3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
+ transitivePeerDependencies:
+ - '@opentelemetry/api'
+
+ better-auth@1.7.6(mysql2@3.24.4(@types/node@22.18.6))(next@14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(pg@8.23.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)):
dependencies:
- '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0)(jose@6.2.3)(kysely@0.29.6)(nanostores@1.4.0)
- '@better-auth/drizzle-adapter': 1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)
- '@better-auth/kysely-adapter': 1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)(kysely@0.29.6)
- '@better-auth/memory-adapter': 1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)
- '@better-auth/mongo-adapter': 1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)
- '@better-auth/prisma-adapter': 1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)
- '@better-auth/telemetry': 1.7.6(@better-auth/core@1.7.6)(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/drizzle-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/kysely-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(kysely@0.29.6)
+ '@better-auth/memory-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/mongo-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/prisma-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/telemetry': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)
'@better-auth/utils': 0.4.2
'@better-fetch/fetch': 1.3.2
- '@noble/ciphers': 2.2.0
- '@noble/hashes': 2.2.0
- better-call: 1.4.0(zod@3.25.67)
+ '@noble/ciphers': 2.4.0
+ '@noble/hashes': 2.4.0
+ better-call: 1.4.0(zod@4.6.7)
defu: 6.1.7
- jose: 6.2.3
+ jose: 6.2.13
kysely: 0.29.6
- nanostores: 1.4.0
- next: 14.2.35(react-dom@18.3.1)(react@18.3.1)
+ nanostores: 1.5.5
+ zod: 4.6.7
+ optionalDependencies:
+ mysql2: 3.24.4(@types/node@22.18.6)
+ next: 14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
pg: 8.23.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- vitest: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
- zod: 4.6.5
+ vitest: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
transitivePeerDependencies:
- '@opentelemetry/api'
- dev: false
- /better-call@1.4.0(zod@3.25.67):
- resolution: {integrity: sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA==}
- peerDependencies:
- zod: ^4.0.0
- peerDependenciesMeta:
- zod:
- optional: true
+ better-auth@1.7.6(mysql2@3.24.4(@types/node@22.18.6))(next@14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@18.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)):
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/drizzle-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/kysely-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(kysely@0.29.6)
+ '@better-auth/memory-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/mongo-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/prisma-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/telemetry': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+ '@noble/ciphers': 2.4.0
+ '@noble/hashes': 2.4.0
+ better-call: 1.4.0(zod@4.6.7)
+ defu: 6.1.7
+ jose: 6.2.13
+ kysely: 0.29.6
+ nanostores: 1.5.5
+ zod: 4.6.7
+ optionalDependencies:
+ mysql2: 3.24.4(@types/node@22.18.6)
+ next: 14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@19.3.1))(react@19.3.1)
+ pg: 8.23.0
+ react: 19.3.1
+ react-dom: 18.3.1(react@19.3.1)
+ vitest: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
+ transitivePeerDependencies:
+ - '@opentelemetry/api'
+
+ better-auth@1.7.6(mysql2@3.24.4(@types/node@22.18.6))(next@14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.23.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)):
+ dependencies:
+ '@better-auth/core': 1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5)
+ '@better-auth/drizzle-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/kysely-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(kysely@0.29.6)
+ '@better-auth/memory-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/mongo-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/prisma-adapter': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)
+ '@better-auth/telemetry': 1.7.6(@better-auth/core@1.7.6(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.13)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.2
+ '@noble/ciphers': 2.4.0
+ '@noble/hashes': 2.4.0
+ better-call: 1.4.0(zod@4.6.7)
+ defu: 6.1.7
+ jose: 6.2.13
+ kysely: 0.29.6
+ nanostores: 1.5.5
+ zod: 4.6.7
+ optionalDependencies:
+ mysql2: 3.24.4(@types/node@22.18.6)
+ next: 14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ pg: 8.23.0
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ vitest: 3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
+ transitivePeerDependencies:
+ - '@opentelemetry/api'
+
+ better-call@1.4.0(zod@3.25.76):
dependencies:
- '@better-auth/utils': 0.5.0
+ '@better-auth/utils': 0.5.1
'@better-fetch/fetch': 1.3.2
rou3: 0.9.2
- set-cookie-parser: 3.1.2
- zod: 3.25.67
- dev: false
+ set-cookie-parser: 3.2.1
+ optionalDependencies:
+ zod: 3.25.76
- /better-sqlite3@13.0.3:
- resolution: {integrity: sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==}
- engines: {node: '>=22'}
- requiresBuild: true
+ better-call@1.4.0(zod@4.6.7):
+ dependencies:
+ '@better-auth/utils': 0.5.1
+ '@better-fetch/fetch': 1.3.2
+ rou3: 0.9.2
+ set-cookie-parser: 3.2.1
+ optionalDependencies:
+ zod: 4.6.7
+
+ better-sqlite3@13.0.3:
dependencies:
node-addon-api: 8.9.2
- /binary-extensions@2.3.0:
- resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
- engines: {node: '>=8'}
- dev: true
+ binary-extensions@2.3.0: {}
- /bl@4.1.0:
- resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
- dependencies:
- buffer: 5.7.1
- inherits: 2.0.4
- readable-stream: 3.6.2
- dev: true
+ blake3-wasm@2.1.5: {}
- /bowser@2.14.1:
- resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==}
- dev: false
+ bowser@2.15.0: {}
- /brace-expansion@1.1.16:
- resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==}
+ boxen@7.0.0:
+ dependencies:
+ ansi-align: 3.0.1
+ camelcase: 7.0.1
+ chalk: 5.0.1
+ cli-boxes: 3.0.0
+ string-width: 5.1.2
+ type-fest: 2.19.0
+ widest-line: 4.0.1
+ wrap-ansi: 8.1.0
+
+ brace-expansion@1.1.21:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
- dev: true
- /brace-expansion@2.1.2:
- resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==}
+ brace-expansion@5.0.12:
dependencies:
- balanced-match: 1.0.2
- dev: true
+ balanced-match: 4.0.4
- /braces@3.0.3:
- resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
- engines: {node: '>=8'}
+ braces@3.0.3:
dependencies:
fill-range: 7.1.1
- dev: true
- /browserslist@4.28.5:
- resolution: {integrity: sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==}
- engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
- hasBin: true
+ browserslist@4.29.5:
dependencies:
- baseline-browser-mapping: 2.10.42
- caniuse-lite: 1.0.30001803
- electron-to-chromium: 1.5.389
- node-releases: 2.0.51
- update-browserslist-db: 1.2.3(browserslist@4.28.5)
- dev: true
+ baseline-browser-mapping: 2.11.33
+ caniuse-lite: 1.0.30001819
+ electron-to-chromium: 1.5.465
+ node-releases: 2.0.60
+ update-browserslist-db: 1.3.4(browserslist@4.29.5)
- /buffer@5.7.1:
- resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
- dependencies:
- base64-js: 1.5.1
- ieee754: 1.2.1
- dev: true
+ buffer-from@1.1.2: {}
- /bundle-require@5.1.0(esbuild@0.27.7):
- resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- peerDependencies:
- esbuild: '>=0.18'
+ bundle-require@5.1.0(esbuild@0.27.7):
dependencies:
esbuild: 0.27.7
load-tsconfig: 0.2.5
- dev: true
- /busboy@1.6.0:
- resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
- engines: {node: '>=10.16.0'}
+ busboy@1.6.0:
dependencies:
streamsearch: 1.1.0
- /cac@6.7.14:
- resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
- engines: {node: '>=8'}
+ bytes@3.0.0: {}
- /callsites@3.1.0:
- resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
- engines: {node: '>=6'}
- dev: true
+ bytes@3.1.2: {}
+
+ cac@6.7.14: {}
- /camel-case@3.0.0:
- resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==}
+ cacheable@2.5.0:
dependencies:
- no-case: 2.3.2
- upper-case: 1.1.3
- dev: true
+ '@cacheable/memory': 2.2.0
+ '@cacheable/utils': 2.5.0
+ hookified: 1.15.1
+ keyv: 5.6.0
+ qified: 0.10.1
- /camelcase-css@2.0.1:
- resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
- engines: {node: '>= 6'}
- dev: true
+ camelcase-css@2.0.1: {}
- /caniuse-lite@1.0.30001803:
- resolution: {integrity: sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==}
+ camelcase@7.0.1: {}
- /chai@5.3.3:
- resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
- engines: {node: '>=18'}
+ camelize@1.0.1: {}
+
+ caniuse-lite@1.0.30001819: {}
+
+ ccount@2.0.1: {}
+
+ chai@5.3.3:
dependencies:
assertion-error: 2.0.1
check-error: 2.1.3
@@ -3734,69 +9185,30 @@ packages:
loupe: 3.2.1
pathval: 2.0.1
- /chalk@2.4.2:
- resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
- engines: {node: '>=4'}
+ chalk-template@0.4.0:
dependencies:
- ansi-styles: 3.2.1
- escape-string-regexp: 1.0.5
- supports-color: 5.5.0
- dev: true
+ chalk: 4.1.2
- /chalk@3.0.0:
- resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
- engines: {node: '>=8'}
+ chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
- dev: true
- /chalk@4.1.2:
- resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
- engines: {node: '>=10'}
- dependencies:
- ansi-styles: 4.3.0
- supports-color: 7.2.0
- dev: true
-
- /change-case@3.1.0:
- resolution: {integrity: sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==}
- dependencies:
- camel-case: 3.0.0
- constant-case: 2.0.0
- dot-case: 2.1.1
- header-case: 1.0.1
- is-lower-case: 1.1.3
- is-upper-case: 1.1.2
- lower-case: 1.1.4
- lower-case-first: 1.0.2
- no-case: 2.3.2
- param-case: 2.1.1
- pascal-case: 2.0.1
- path-case: 2.1.1
- sentence-case: 2.1.1
- snake-case: 2.1.0
- swap-case: 1.1.2
- title-case: 2.1.1
- upper-case: 1.1.3
- upper-case-first: 1.1.2
- dev: true
-
- /chardet@0.7.0:
- resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
- dev: true
-
- /chardet@2.2.0:
- resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==}
- dev: true
+ chalk@5.0.1: {}
- /check-error@2.1.3:
- resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
- engines: {node: '>= 16'}
+ character-entities-html4@2.1.0: {}
- /chokidar@3.6.0:
- resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
- engines: {node: '>= 8.10.0'}
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ character-reference-invalid@2.0.1: {}
+
+ chardet@2.2.0: {}
+
+ check-error@2.1.3: {}
+
+ chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.3
@@ -3807,281 +9219,233 @@ packages:
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
- dev: true
- /chokidar@4.0.3:
- resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
- engines: {node: '>= 14.16.0'}
+ chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
- dev: true
- /class-variance-authority@0.7.0:
- resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==}
+ chokidar@5.0.0:
dependencies:
- clsx: 2.0.0
- dev: false
+ readdirp: 5.1.1
- /clean-stack@2.2.0:
- resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
- engines: {node: '>=6'}
- dev: true
+ chrome-trace-event@1.0.4: {}
- /cli-cursor@3.1.0:
- resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
- engines: {node: '>=8'}
+ class-variance-authority@0.7.1:
dependencies:
- restore-cursor: 3.1.0
- dev: true
+ clsx: 2.1.1
- /cli-spinners@2.9.2:
- resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
- engines: {node: '>=6'}
- dev: true
+ cli-boxes@3.0.0: {}
- /cli-width@3.0.0:
- resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
- engines: {node: '>= 10'}
- dev: true
+ cli-width@4.1.0: {}
- /client-only@0.0.1:
- resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+ client-only@0.0.1: {}
- /clone@1.0.4:
- resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
- engines: {node: '>=0.8'}
- dev: true
+ clipboardy@3.0.0:
+ dependencies:
+ arch: 2.2.0
+ execa: 5.1.1
+ is-wsl: 2.2.0
- /clsx@2.0.0:
- resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
- engines: {node: '>=6'}
- dev: false
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
- /clsx@2.1.1:
- resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
- engines: {node: '>=6'}
- dev: false
+ clsx@2.1.1: {}
- /color-convert@1.9.3:
- resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
- dependencies:
- color-name: 1.1.3
- dev: true
+ cn@0.4.0: {}
- /color-convert@2.0.1:
- resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
- engines: {node: '>=7.0.0'}
+ cn@0.5.0: {}
+
+ collapse-white-space@2.1.0: {}
+
+ color-convert@2.0.1:
dependencies:
color-name: 1.1.4
- dev: true
- /color-name@1.1.3:
- resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
- dev: true
+ color-name@1.1.4: {}
- /color-name@1.1.4:
- resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
- dev: true
+ comma-separated-tokens@2.0.3: {}
- /commander@10.0.1:
- resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
- engines: {node: '>=14'}
- dev: true
+ commander@12.1.0: {}
- /commander@12.1.0:
- resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
- engines: {node: '>=18'}
- dev: false
+ commander@2.20.3: {}
- /commander@4.1.1:
- resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
- engines: {node: '>= 6'}
- dev: true
+ commander@4.1.1: {}
- /concat-map@0.0.1:
- resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
- dev: true
+ compressible@2.0.18:
+ dependencies:
+ mime-db: 1.54.0
- /confbox@0.1.8:
- resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
- dev: true
+ compression@1.8.1(supports-color@10.2.2):
+ dependencies:
+ bytes: 3.1.2
+ compressible: 2.0.18
+ debug: 2.6.9(supports-color@10.2.2)
+ negotiator: 0.6.4
+ on-headers: 1.1.0
+ safe-buffer: 5.2.1
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
- /consola@3.4.2:
- resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
- engines: {node: ^14.18.0 || >=16.10.0}
- dev: true
+ compute-scroll-into-view@3.1.1: {}
- /constant-case@2.0.0:
- resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==}
- dependencies:
- snake-case: 2.1.0
- upper-case: 1.1.3
- dev: true
+ concat-map@0.0.1: {}
- /core-js-pure@3.49.0:
- resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==}
- requiresBuild: true
- dev: true
+ confbox@0.1.8: {}
- /create-require@1.1.1:
- resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
- dev: true
+ consola@3.4.2: {}
- /cross-spawn@7.0.6:
- resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
- engines: {node: '>= 8'}
+ content-disposition@0.5.2: {}
+
+ cookie@1.1.1: {}
+
+ cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
- dev: true
- /cssesc@3.0.0:
- resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
- engines: {node: '>=4'}
- hasBin: true
- dev: true
+ css-background-parser@0.1.0: {}
- /csstype@3.2.3:
- resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+ css-box-shadow@1.0.0-3: {}
- /data-uri-to-buffer@6.0.2:
- resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
- engines: {node: '>= 14'}
- dev: true
+ css-color-keywords@1.0.0: {}
- /debug@4.4.3:
- resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
- engines: {node: '>=6.0'}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
- dependencies:
- ms: 2.1.3
+ css-gradient-parser@0.0.17: {}
- /deep-eql@5.0.2:
- resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
- engines: {node: '>=6'}
+ css-to-react-native@3.2.0:
+ dependencies:
+ camelize: 1.0.1
+ css-color-keywords: 1.0.0
+ postcss-value-parser: 4.2.0
- /deep-extend@0.6.0:
- resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
- engines: {node: '>=4.0.0'}
- dev: true
+ cssesc@3.0.0: {}
- /deep-is@0.1.4:
- resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
- dev: true
+ csstype@3.2.3: {}
- /defaults@1.0.4:
- resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
+ debug@2.6.9(supports-color@10.2.2):
dependencies:
- clone: 1.0.4
- dev: true
-
- /defu@6.1.7:
- resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
- dev: false
+ ms: 2.0.0
+ optionalDependencies:
+ supports-color: 10.2.2
- /degenerator@5.0.1:
- resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
- engines: {node: '>= 14'}
+ debug@4.4.3(supports-color@10.2.2):
dependencies:
- ast-types: 0.13.4
- escodegen: 2.1.0
- esprima: 4.0.1
- dev: true
+ ms: 2.1.3
+ optionalDependencies:
+ supports-color: 10.2.2
- /del@5.1.0:
- resolution: {integrity: sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==}
- engines: {node: '>=8'}
+ decode-named-character-reference@1.3.0:
dependencies:
- globby: 10.0.2
- graceful-fs: 4.2.11
- is-glob: 4.0.3
- is-path-cwd: 2.2.0
- is-path-inside: 3.0.3
- p-map: 3.0.0
- rimraf: 3.0.2
- slash: 3.0.0
- dev: true
-
- /detect-libc@2.0.2:
- resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
- engines: {node: '>=8'}
- dev: false
+ character-entities: 2.0.2
- /detect-node-es@1.1.0:
- resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
- dev: false
+ deep-eql@5.0.2: {}
- /didyoumean@1.2.2:
- resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
- dev: true
+ deep-extend@0.6.0: {}
- /diff@4.0.4:
- resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==}
- engines: {node: '>=0.3.1'}
- dev: true
+ deep-is@0.1.4: {}
- /dir-glob@3.0.1:
- resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
- engines: {node: '>=8'}
- dependencies:
- path-type: 4.0.0
- dev: true
+ defu@6.1.7: {}
- /dlv@1.1.3:
- resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
- dev: true
+ dequal@2.0.3: {}
+
+ detect-libc@2.0.2: {}
+
+ detect-libc@2.1.2: {}
+
+ detect-node-es@1.1.0: {}
- /dot-case@2.1.1:
- resolution: {integrity: sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==}
+ devlop@1.1.0:
dependencies:
- no-case: 2.3.2
- dev: true
+ dequal: 2.0.3
- /dotenv-cli@7.4.2:
- resolution: {integrity: sha512-SbUj8l61zIbzyhIbg0FwPJq6+wjbzdn9oEtozQpZ6kW2ihCcapKVZj49oCT3oPM+mgQm+itgvUQcG5szxVrZTA==}
- hasBin: true
+ didyoumean@1.2.2: {}
+
+ dlv@1.1.3: {}
+
+ dotenv-cli@7.4.4:
dependencies:
cross-spawn: 7.0.6
dotenv: 16.6.1
dotenv-expand: 10.0.0
minimist: 1.2.8
- dev: true
- /dotenv-expand@10.0.0:
- resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==}
- engines: {node: '>=12'}
- dev: true
+ dotenv-expand@10.0.0: {}
- /dotenv@16.6.1:
- resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
- engines: {node: '>=12'}
+ dotenv@16.6.1: {}
- /electron-to-chromium@1.5.389:
- resolution: {integrity: sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==}
- dev: true
+ eastasianwidth@0.2.0: {}
- /emoji-regex@8.0.0:
- resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
- dev: true
+ electron-to-chromium@1.5.465: {}
- /es-errors@1.3.0:
- resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
- engines: {node: '>= 0.4'}
- dev: true
+ emoji-regex-xs@2.0.1: {}
- /es-module-lexer@1.7.0:
- resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
+ emoji-regex@8.0.0: {}
- /esbuild@0.27.7:
- resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
- engines: {node: '>=18'}
- hasBin: true
- requiresBuild: true
+ emoji-regex@9.2.2: {}
+
+ enhanced-resolve@5.26.0:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.3.3
+
+ error-stack-parser-es@1.0.5: {}
+
+ es-errors@1.3.0: {}
+
+ es-module-lexer@1.7.0: {}
+
+ es-module-lexer@2.3.2: {}
+
+ es-module-lexer@3.0.4: {}
+
+ esast-util-from-estree@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ devlop: 1.1.0
+ estree-util-visit: 2.0.0
+ unist-util-position-from-estree: 2.0.0
+
+ esast-util-from-js@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ acorn: 8.19.0
+ esast-util-from-estree: 2.0.0
+ vfile-message: 4.0.3
+
+ esbuild@0.25.12:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.12
+ '@esbuild/android-arm': 0.25.12
+ '@esbuild/android-arm64': 0.25.12
+ '@esbuild/android-x64': 0.25.12
+ '@esbuild/darwin-arm64': 0.25.12
+ '@esbuild/darwin-x64': 0.25.12
+ '@esbuild/freebsd-arm64': 0.25.12
+ '@esbuild/freebsd-x64': 0.25.12
+ '@esbuild/linux-arm': 0.25.12
+ '@esbuild/linux-arm64': 0.25.12
+ '@esbuild/linux-ia32': 0.25.12
+ '@esbuild/linux-loong64': 0.25.12
+ '@esbuild/linux-mips64el': 0.25.12
+ '@esbuild/linux-ppc64': 0.25.12
+ '@esbuild/linux-riscv64': 0.25.12
+ '@esbuild/linux-s390x': 0.25.12
+ '@esbuild/linux-x64': 0.25.12
+ '@esbuild/netbsd-arm64': 0.25.12
+ '@esbuild/netbsd-x64': 0.25.12
+ '@esbuild/openbsd-arm64': 0.25.12
+ '@esbuild/openbsd-x64': 0.25.12
+ '@esbuild/openharmony-arm64': 0.25.12
+ '@esbuild/sunos-x64': 0.25.12
+ '@esbuild/win32-arm64': 0.25.12
+ '@esbuild/win32-ia32': 0.25.12
+ '@esbuild/win32-x64': 0.25.12
+
+ esbuild@0.27.7:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.7
'@esbuild/android-arm': 0.27.7
@@ -4109,176 +9473,150 @@ packages:
'@esbuild/win32-arm64': 0.27.7
'@esbuild/win32-ia32': 0.27.7
'@esbuild/win32-x64': 0.27.7
- dev: true
-
- /esbuild@0.28.1:
- resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==}
- engines: {node: '>=18'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- '@esbuild/aix-ppc64': 0.28.1
- '@esbuild/android-arm': 0.28.1
- '@esbuild/android-arm64': 0.28.1
- '@esbuild/android-x64': 0.28.1
- '@esbuild/darwin-arm64': 0.28.1
- '@esbuild/darwin-x64': 0.28.1
- '@esbuild/freebsd-arm64': 0.28.1
- '@esbuild/freebsd-x64': 0.28.1
- '@esbuild/linux-arm': 0.28.1
- '@esbuild/linux-arm64': 0.28.1
- '@esbuild/linux-ia32': 0.28.1
- '@esbuild/linux-loong64': 0.28.1
- '@esbuild/linux-mips64el': 0.28.1
- '@esbuild/linux-ppc64': 0.28.1
- '@esbuild/linux-riscv64': 0.28.1
- '@esbuild/linux-s390x': 0.28.1
- '@esbuild/linux-x64': 0.28.1
- '@esbuild/netbsd-arm64': 0.28.1
- '@esbuild/netbsd-x64': 0.28.1
- '@esbuild/openbsd-arm64': 0.28.1
- '@esbuild/openbsd-x64': 0.28.1
- '@esbuild/openharmony-arm64': 0.28.1
- '@esbuild/sunos-x64': 0.28.1
- '@esbuild/win32-arm64': 0.28.1
- '@esbuild/win32-ia32': 0.28.1
- '@esbuild/win32-x64': 0.28.1
-
- /escalade@3.2.0:
- resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
- engines: {node: '>=6'}
- dev: true
-
- /escape-string-regexp@1.0.5:
- resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
- engines: {node: '>=0.8.0'}
- dev: true
-
- /escape-string-regexp@4.0.0:
- resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
- engines: {node: '>=10'}
- dev: true
- /escodegen@2.1.0:
- resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
- engines: {node: '>=6.0'}
- hasBin: true
- dependencies:
- esprima: 4.0.1
- estraverse: 5.3.0
- esutils: 2.0.3
+ esbuild@0.28.2:
optionalDependencies:
- source-map: 0.6.1
- dev: true
-
- /eslint-scope@8.4.0:
- resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- dependencies:
+ '@esbuild/aix-ppc64': 0.28.2
+ '@esbuild/android-arm': 0.28.2
+ '@esbuild/android-arm64': 0.28.2
+ '@esbuild/android-x64': 0.28.2
+ '@esbuild/darwin-arm64': 0.28.2
+ '@esbuild/darwin-x64': 0.28.2
+ '@esbuild/freebsd-arm64': 0.28.2
+ '@esbuild/freebsd-x64': 0.28.2
+ '@esbuild/linux-arm': 0.28.2
+ '@esbuild/linux-arm64': 0.28.2
+ '@esbuild/linux-ia32': 0.28.2
+ '@esbuild/linux-loong64': 0.28.2
+ '@esbuild/linux-mips64el': 0.28.2
+ '@esbuild/linux-ppc64': 0.28.2
+ '@esbuild/linux-riscv64': 0.28.2
+ '@esbuild/linux-s390x': 0.28.2
+ '@esbuild/linux-x64': 0.28.2
+ '@esbuild/netbsd-arm64': 0.28.2
+ '@esbuild/netbsd-x64': 0.28.2
+ '@esbuild/openbsd-arm64': 0.28.2
+ '@esbuild/openbsd-x64': 0.28.2
+ '@esbuild/openharmony-arm64': 0.28.2
+ '@esbuild/sunos-x64': 0.28.2
+ '@esbuild/win32-arm64': 0.28.2
+ '@esbuild/win32-ia32': 0.28.2
+ '@esbuild/win32-x64': 0.28.2
+
+ escalade@3.2.0: {}
+
+ escape-html@1.0.3: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ escape-string-regexp@5.0.0: {}
+
+ eslint-scope@9.1.2:
+ dependencies:
+ '@types/esrecurse': 4.3.1
+ '@types/estree': 1.0.9
esrecurse: 4.3.0
estraverse: 5.3.0
- dev: true
- /eslint-visitor-keys@3.4.3:
- resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dev: true
+ eslint-visitor-keys@3.4.3: {}
- /eslint-visitor-keys@4.2.1:
- resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- dev: true
+ eslint-visitor-keys@5.0.1: {}
- /eslint@9.7.0:
- resolution: {integrity: sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- hasBin: true
+ eslint@10.13.0(jiti@2.7.0)(supports-color@10.2.2):
dependencies:
- '@eslint-community/eslint-utils': 4.9.1(eslint@9.7.0)
+ '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)(supports-color@10.2.2))
'@eslint-community/regexpp': 4.12.2
- '@eslint/config-array': 0.17.1
- '@eslint/eslintrc': 3.3.5
- '@eslint/js': 9.7.0
+ '@eslint/config-array': 0.23.5(supports-color@10.2.2)
+ '@eslint/config-helpers': 0.7.0
+ '@eslint/core': 1.2.1
+ '@eslint/plugin-kit': 0.7.3
+ '@humanfs/node': 0.16.8
'@humanwhocodes/module-importer': 1.0.1
- '@humanwhocodes/retry': 0.3.1
- '@nodelib/fs.walk': 1.2.8
+ '@humanwhocodes/retry': 0.4.3
+ '@types/estree': 1.0.9
ajv: 6.15.0
- chalk: 4.1.2
cross-spawn: 7.0.6
- debug: 4.4.3
+ debug: 4.4.3(supports-color@10.2.2)
escape-string-regexp: 4.0.0
- eslint-scope: 8.4.0
- eslint-visitor-keys: 4.2.1
- espree: 10.4.0
+ eslint-scope: 9.1.2
+ eslint-visitor-keys: 5.0.1
+ espree: 11.2.0
esquery: 1.7.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
- file-entry-cache: 8.0.0
+ file-entry-cache: 11.1.5
find-up: 5.0.0
glob-parent: 6.0.2
ignore: 5.3.2
imurmurhash: 0.1.4
is-glob: 4.0.3
- is-path-inside: 3.0.3
json-stable-stringify-without-jsonify: 1.0.1
- levn: 0.4.1
- lodash.merge: 4.6.2
- minimatch: 3.1.5
+ minimatch: 10.2.6
natural-compare: 1.4.0
optionator: 0.9.4
- strip-ansi: 6.0.1
- text-table: 0.2.0
+ optionalDependencies:
+ jiti: 2.7.0
transitivePeerDependencies:
- supports-color
- dev: true
- /espree@10.4.0:
- resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ espree@11.2.0:
+ dependencies:
+ acorn: 8.19.0
+ acorn-jsx: 5.3.2(acorn@8.19.0)
+ eslint-visitor-keys: 5.0.1
+
+ esquery@1.7.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@5.3.0: {}
+
+ estree-util-attach-comments@3.0.0:
dependencies:
- acorn: 8.17.0
- acorn-jsx: 5.3.2(acorn@8.17.0)
- eslint-visitor-keys: 4.2.1
- dev: true
+ '@types/estree': 1.0.9
- /esprima@4.0.1:
- resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
- engines: {node: '>=4'}
- hasBin: true
- dev: true
+ estree-util-build-jsx@3.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ estree-walker: 3.0.3
- /esquery@1.7.0:
- resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
- engines: {node: '>=0.10'}
+ estree-util-is-identifier-name@3.0.0: {}
+
+ estree-util-scope@1.0.1:
dependencies:
- estraverse: 5.3.0
- dev: true
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
- /esrecurse@4.3.0:
- resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
- engines: {node: '>=4.0'}
+ estree-util-to-js@2.0.0:
dependencies:
- estraverse: 5.3.0
- dev: true
+ '@types/estree-jsx': 1.0.5
+ astring: 1.9.0
+ source-map: 0.7.6
- /estraverse@5.3.0:
- resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
- engines: {node: '>=4.0'}
- dev: true
+ estree-util-value-to-estree@3.5.0:
+ dependencies:
+ '@types/estree': 1.0.9
- /estree-walker@3.0.3:
- resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+ estree-util-visit@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/unist': 3.0.3
+
+ estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.9
- /esutils@2.0.3:
- resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
- engines: {node: '>=0.10.0'}
- dev: true
+ esutils@2.0.3: {}
- /execa@5.1.1:
- resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
- engines: {node: '>=10'}
+ events@3.3.0: {}
+
+ execa@5.1.1:
dependencies:
cross-spawn: 7.0.6
get-stream: 6.0.1
@@ -4289,735 +9627,1088 @@ packages:
onetime: 5.1.2
signal-exit: 3.0.7
strip-final-newline: 2.0.0
- dev: true
- /expect-type@1.4.0:
- resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
- engines: {node: '>=12.0.0'}
+ expect-type@1.4.0: {}
- /external-editor@3.1.0:
- resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
- engines: {node: '>=4'}
- dependencies:
- chardet: 0.7.0
- iconv-lite: 0.4.24
- tmp: 0.0.33
- dev: true
+ extend@3.0.2: {}
- /fast-deep-equal@3.1.3:
- resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
- dev: true
+ fast-deep-equal@3.1.3: {}
- /fast-glob@3.3.3:
- resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
- engines: {node: '>=8.6.0'}
+ fast-glob@3.3.3:
dependencies:
'@nodelib/fs.stat': 2.0.5
'@nodelib/fs.walk': 1.2.8
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.8
- dev: true
- /fast-json-stable-stringify@2.1.0:
- resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
- dev: true
+ fast-json-stable-stringify@2.1.0: {}
- /fast-levenshtein@2.0.6:
- resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
- dev: true
+ fast-levenshtein@2.0.6: {}
- /fast-xml-parser@4.4.1:
- resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==}
- hasBin: true
- dependencies:
- strnum: 1.1.2
- dev: false
+ fast-uri@3.1.9: {}
- /fastq@1.20.1:
- resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
+ fastq@1.20.3:
dependencies:
reusify: 1.1.0
- dev: true
- /fdir@6.5.0(picomatch@4.0.5):
- resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
- engines: {node: '>=12.0.0'}
- peerDependencies:
- picomatch: ^3 || ^4
- peerDependenciesMeta:
- picomatch:
- optional: true
- dependencies:
- picomatch: 4.0.5
+ fdir@6.5.0(picomatch@4.0.7):
+ optionalDependencies:
+ picomatch: 4.0.7
- /figures@3.2.0:
- resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
- engines: {node: '>=8'}
- dependencies:
- escape-string-regexp: 1.0.5
- dev: true
+ fflate@0.7.3: {}
- /file-entry-cache@8.0.0:
- resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
- engines: {node: '>=16.0.0'}
+ file-entry-cache@11.1.5:
dependencies:
- flat-cache: 4.0.1
- dev: true
+ flat-cache: 6.1.23
- /fill-range@7.1.1:
- resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
- engines: {node: '>=8'}
+ fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
- dev: true
- /find-up@5.0.0:
- resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
- engines: {node: '>=10'}
+ find-up@5.0.0:
dependencies:
locate-path: 6.0.0
path-exists: 4.0.0
- dev: true
- /fix-dts-default-cjs-exports@1.0.1:
- resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==}
+ fix-dts-default-cjs-exports@1.0.1:
dependencies:
magic-string: 0.30.21
mlly: 1.8.2
- rollup: 4.62.2
- dev: true
+ rollup: 4.65.1
- /flat-cache@4.0.1:
- resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
- engines: {node: '>=16'}
+ flat-cache@6.1.23:
dependencies:
- flatted: 3.4.2
- keyv: 4.5.4
- dev: true
+ cacheable: 2.5.0
+ flatted: 3.4.4
+ hookified: 1.15.1
- /flatted@3.4.2:
- resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
- dev: true
+ flatted@3.4.4: {}
- /fraction.js@4.3.7:
- resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
- dev: true
+ fraction.js@4.3.7: {}
- /fs-extra@10.1.0:
- resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
- engines: {node: '>=12'}
+ framer-motion@14.6.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
dependencies:
- graceful-fs: 4.2.11
- jsonfile: 6.2.1
- universalify: 2.0.1
- dev: true
-
- /fs.realpath@1.0.0:
- resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
- dev: true
+ motion-dom: 14.6.0
+ motion-utils: 14.6.0
+ tslib: 2.8.1
+ optionalDependencies:
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
- /fsevents@2.3.3:
- resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
- requiresBuild: true
+ fsevents@2.3.3:
optional: true
- /function-bind@1.1.2:
- resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
- dev: true
+ fumadocs-core@16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7):
+ dependencies:
+ '@fumari/image-size': 0.1.1
+ estree-util-value-to-estree: 3.5.0
+ github-slugger: 2.0.0
+ hast-util-from-dom: 5.0.1
+ hast-util-to-estree: 3.1.3(supports-color@10.2.2)
+ hast-util-to-jsx-runtime: 2.3.6(supports-color@10.2.2)
+ mdast-util-mdx: 3.0.0(supports-color@10.2.2)
+ micromark: 4.0.3(supports-color@10.2.2)
+ micromark-extension-gfm-table: 2.1.2
+ npm-to-yarn: 3.2.0
+ remark: 15.0.1(supports-color@10.2.2)
+ remark-gfm: 4.0.1(supports-color@10.2.2)
+ remark-rehype: 11.1.2
+ scroll-into-view-if-needed: 3.1.0
+ shiki: 4.5.0
+ tinyglobby: 0.2.17
+ unified: 11.0.5
+ vfile: 6.0.3
+ yaml: 2.9.1
+ zbsearch: 4.0.1
+ optionalDependencies:
+ '@mdx-js/mdx': 3.1.1(supports-color@10.2.2)
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@types/react': 19.3.0
+ lucide-react: 1.61.0(@types/react@19.3.0)(react@19.3.1)
+ next: 16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ zod: 4.6.7
+ transitivePeerDependencies:
+ - supports-color
- /generate-function@2.3.1:
- resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
+ fumadocs-mdx@15.4.9(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.3.0)(fumadocs-core@16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react@19.3.1)(rolldown@1.2.15)(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)):
+ dependencies:
+ '@mdx-js/mdx': 3.1.1(supports-color@10.2.2)
+ '@standard-schema/spec': 1.1.0
+ chokidar: 5.0.0
+ esbuild: 0.28.2
+ estree-util-value-to-estree: 3.5.0
+ fumadocs-core: 16.17.7(@mdx-js/mdx@3.1.1(supports-color@10.2.2))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.3.0)(lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1))(next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(supports-color@10.2.2)(zod@4.6.7)
+ github-slugger: 2.0.0
+ magic-string: 1.4.4
+ mdast-util-mdx: 3.0.0(supports-color@10.2.2)
+ picocolors: 1.1.1
+ picomatch: 4.0.7
+ tinyexec: 1.3.1
+ tinyglobby: 0.2.17
+ unified: 11.0.5
+ unist-util-remove-position: 5.0.0
+ vfile: 6.0.3
+ yaml: 2.9.1
+ yuku-analyzer: 0.19.0
+ zod: 4.6.7
+ optionalDependencies:
+ '@types/mdast': 4.0.4
+ '@types/mdx': 2.0.14
+ '@types/react': 19.3.0
+ next: 16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ react: 19.3.1
+ rolldown: 1.2.15
+ vite: 8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ function-bind@1.1.2: {}
+
+ generate-function@2.3.1:
dependencies:
is-property: 1.0.2
- dev: false
- /get-nonce@1.0.1:
- resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
- engines: {node: '>=6'}
- dev: false
+ get-caller-file@2.0.5: {}
- /get-stream@6.0.1:
- resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
- engines: {node: '>=10'}
- dev: true
+ get-nonce@1.0.1: {}
- /get-uri@6.0.5:
- resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==}
- engines: {node: '>= 14'}
+ get-stream@6.0.1: {}
+
+ github-slugger@2.0.0: {}
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ graceful-fs@4.2.11: {}
+
+ harfbuzzjs@0.10.0: {}
+
+ has-flag@4.0.0: {}
+
+ hashery@1.5.1:
dependencies:
- basic-ftp: 5.3.1
- data-uri-to-buffer: 6.0.2
- debug: 4.4.3
+ hookified: 1.15.1
+
+ hasown@2.0.4:
+ dependencies:
+ function-bind: 1.1.2
+
+ hast-util-from-dom@5.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ hastscript: 9.0.1
+ web-namespaces: 2.0.1
+
+ hast-util-parse-selector@4.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hast-util-to-estree@3.1.3(supports-color@10.2.2):
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-attach-comments: 3.0.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1(supports-color@10.2.2)
+ mdast-util-mdx-jsx: 3.2.0(supports-color@10.2.2)
+ mdast-util-mdxjs-esm: 2.0.1(supports-color@10.2.2)
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.21
+ unist-util-position: 5.0.0
+ zwitch: 2.0.4
transitivePeerDependencies:
- supports-color
- dev: true
- /glob-parent@5.1.2:
- resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
- engines: {node: '>= 6'}
+ hast-util-to-html@9.0.5:
dependencies:
- is-glob: 4.0.3
- dev: true
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
- /glob-parent@6.0.2:
- resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
- engines: {node: '>=10.13.0'}
+ hast-util-to-jsx-runtime@2.3.6(supports-color@10.2.2):
dependencies:
- is-glob: 4.0.3
- dev: true
+ '@types/estree': 1.0.9
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1(supports-color@10.2.2)
+ mdast-util-mdx-jsx: 3.2.0(supports-color@10.2.2)
+ mdast-util-mdxjs-esm: 2.0.1(supports-color@10.2.2)
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.21
+ unist-util-position: 5.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
- /glob@7.2.3:
- resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
- deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+ hast-util-whitespace@3.0.0:
dependencies:
- fs.realpath: 1.0.0
- inflight: 1.0.6
- inherits: 2.0.4
- minimatch: 3.1.5
- once: 1.4.0
- path-is-absolute: 1.0.1
- dev: true
+ '@types/hast': 3.0.5
- /globals@14.0.0:
- resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
- engines: {node: '>=18'}
- dev: true
+ hastscript@9.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
- /globby@10.0.2:
- resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==}
- engines: {node: '>=8'}
+ hex-rgb@4.3.0: {}
+
+ hookified@1.15.1: {}
+
+ hookified@2.2.0: {}
+
+ html-void-elements@3.0.0: {}
+
+ human-signals@2.1.0: {}
+
+ iconv-lite@0.7.3:
dependencies:
- '@types/glob': 7.2.0
- array-union: 2.1.0
- dir-glob: 3.0.1
- fast-glob: 3.3.3
- glob: 7.2.3
- ignore: 5.3.2
- merge2: 1.4.1
- slash: 3.0.0
- dev: true
+ safer-buffer: 2.1.2
- /graceful-fs@4.2.11:
- resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ ignore@5.3.2: {}
- /gradient-string@2.0.2:
- resolution: {integrity: sha512-rEDCuqUQ4tbD78TpzsMtt5OIf0cBCSDWSJtUDaF6JsAh+k0v9r++NzxNEG87oDZx9ZwGhD8DaezR2L/yrw0Jdw==}
- engines: {node: '>=10'}
+ imurmurhash@0.1.4: {}
+
+ ini@1.3.8: {}
+
+ inline-style-parser@0.2.7: {}
+
+ ipaddr.js@2.5.0: {}
+
+ is-alphabetical@2.0.1: {}
+
+ is-alphanumerical@2.0.1:
dependencies:
- chalk: 4.1.2
- tinygradient: 1.1.5
- dev: true
+ is-alphabetical: 2.0.1
+ is-decimal: 2.0.1
- /handlebars@4.7.9:
- resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==}
- engines: {node: '>=0.4.7'}
- hasBin: true
+ is-binary-path@2.1.0:
dependencies:
- minimist: 1.2.8
- neo-async: 2.6.2
- source-map: 0.6.1
- wordwrap: 1.0.0
- optionalDependencies:
- uglify-js: 3.19.3
- dev: true
+ binary-extensions: 2.3.0
- /has-flag@3.0.0:
- resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
- engines: {node: '>=4'}
- dev: true
+ is-core-module@2.17.0:
+ dependencies:
+ hasown: 2.0.4
- /has-flag@4.0.0:
- resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
- engines: {node: '>=8'}
- dev: true
+ is-decimal@2.0.1: {}
- /hasown@2.0.4:
- resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
- engines: {node: '>= 0.4'}
+ is-docker@2.2.1: {}
+
+ is-extglob@2.1.1: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-glob@4.0.3:
dependencies:
- function-bind: 1.1.2
- dev: true
+ is-extglob: 2.1.1
+
+ is-hexadecimal@2.0.1: {}
+
+ is-number@7.0.0: {}
+
+ is-plain-obj@4.1.0: {}
+
+ is-port-reachable@4.0.0: {}
+
+ is-property@1.0.2: {}
+
+ is-stream@2.0.1: {}
- /header-case@1.0.1:
- resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==}
+ is-wsl@2.2.0:
dependencies:
- no-case: 2.3.2
- upper-case: 1.1.3
- dev: true
+ is-docker: 2.2.1
- /http-proxy-agent@7.0.2:
- resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
- engines: {node: '>= 14'}
+ isexe@2.0.0: {}
+
+ jest-worker@27.5.1:
dependencies:
- agent-base: 7.1.4
- debug: 4.4.3
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@types/node': 26.6.5
+ merge-stream: 2.0.0
+ supports-color: 8.1.1
- /https-proxy-agent@7.0.6:
- resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
- engines: {node: '>= 14'}
+ jiti@1.21.7: {}
+
+ jiti@2.4.2: {}
+
+ jiti@2.7.0: {}
+
+ jose@6.2.13: {}
+
+ joycon@3.1.1: {}
+
+ js-base64@3.9.5: {}
+
+ js-tokens@10.0.0: {}
+
+ js-tokens@4.0.0: {}
+
+ js-tokens@9.0.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-schema-traverse@1.0.0: {}
+
+ json-stable-stringify-without-jsonify@1.0.1: {}
+
+ keyv@5.6.0:
dependencies:
- agent-base: 7.1.4
- debug: 4.4.3
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@keyv/serialize': 1.1.1
- /human-signals@2.1.0:
- resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
- engines: {node: '>=10.17.0'}
- dev: true
+ kleur@4.1.5: {}
- /iconv-lite@0.4.24:
- resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
- engines: {node: '>=0.10.0'}
+ kysely@0.29.6: {}
+
+ levn@0.4.1:
dependencies:
- safer-buffer: 2.1.2
- dev: true
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
- /iconv-lite@0.7.3:
- resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==}
- engines: {node: '>=0.10.0'}
+ libsql@0.5.29:
dependencies:
- safer-buffer: 2.1.2
+ '@neon-rs/load': 0.0.4
+ detect-libc: 2.0.2
+ optionalDependencies:
+ '@libsql/darwin-arm64': 0.5.29
+ '@libsql/darwin-x64': 0.5.29
+ '@libsql/linux-arm-gnueabihf': 0.5.29
+ '@libsql/linux-arm-musleabihf': 0.5.29
+ '@libsql/linux-arm64-gnu': 0.5.29
+ '@libsql/linux-arm64-musl': 0.5.29
+ '@libsql/linux-x64-gnu': 0.5.29
+ '@libsql/linux-x64-musl': 0.5.29
+ '@libsql/win32-x64-msvc': 0.5.29
- /ieee754@1.2.1:
- resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
- dev: true
+ lightningcss-android-arm64@1.32.0:
+ optional: true
- /ignore@5.3.2:
- resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
- engines: {node: '>= 4'}
- dev: true
+ lightningcss-android-arm64@1.33.0:
+ optional: true
- /import-fresh@3.3.1:
- resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
- engines: {node: '>=6'}
+ 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
+
+ lilconfig@2.1.0: {}
+
+ lilconfig@3.1.4: {}
+
+ linebreak@1.1.0:
dependencies:
- parent-module: 1.0.1
- resolve-from: 4.0.0
- dev: true
+ base64-js: 0.0.8
+ unicode-trie: 2.0.0
- /imurmurhash@0.1.4:
- resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
- engines: {node: '>=0.8.19'}
- dev: true
+ lines-and-columns@1.2.4: {}
- /indent-string@4.0.0:
- resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
- engines: {node: '>=8'}
- dev: true
+ load-tsconfig@0.2.5: {}
- /inflight@1.0.6:
- resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
- deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+ locate-path@6.0.0:
dependencies:
- once: 1.4.0
- wrappy: 1.0.2
- dev: true
+ p-locate: 5.0.0
- /inherits@2.0.4:
- resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
- dev: true
+ long@5.3.2: {}
- /ini@1.3.8:
- resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
- dev: true
+ longest-streak@3.1.0: {}
- /inquirer@7.3.3:
- resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==}
- engines: {node: '>=8.0.0'}
+ loose-envify@1.4.0:
dependencies:
- ansi-escapes: 4.3.2
- chalk: 4.1.2
- cli-cursor: 3.1.0
- cli-width: 3.0.0
- external-editor: 3.1.0
- figures: 3.2.0
- lodash: 4.18.1
- mute-stream: 0.0.8
- run-async: 2.4.1
- rxjs: 6.6.7
- string-width: 4.2.3
- strip-ansi: 6.0.1
- through: 2.3.8
- dev: true
+ js-tokens: 4.0.0
- /inquirer@8.2.7(@types/node@20.14.11):
- resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==}
- engines: {node: '>=12.0.0'}
- dependencies:
- '@inquirer/external-editor': 1.0.3(@types/node@20.14.11)
- ansi-escapes: 4.3.2
- chalk: 4.1.2
- cli-cursor: 3.1.0
- cli-width: 3.0.0
- figures: 3.2.0
- lodash: 4.18.1
- mute-stream: 0.0.8
- ora: 5.4.1
- run-async: 2.4.1
- rxjs: 7.8.2
- string-width: 4.2.3
- strip-ansi: 6.0.1
- through: 2.3.8
- wrap-ansi: 6.2.0
- transitivePeerDependencies:
- - '@types/node'
- dev: true
+ loupe@3.2.1: {}
- /ip-address@10.2.0:
- resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==}
- engines: {node: '>= 12'}
- dev: true
+ lru.min@1.1.5: {}
- /is-binary-path@2.1.0:
- resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
- engines: {node: '>=8'}
+ lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1):
dependencies:
- binary-extensions: 2.3.0
- dev: true
+ react: 19.3.1
+ optionalDependencies:
+ '@types/react': 19.3.0
- /is-core-module@2.16.2:
- resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
- engines: {node: '>= 0.4'}
+ magic-string@0.30.21:
dependencies:
- hasown: 2.0.4
- dev: true
+ '@jridgewell/sourcemap-codec': 1.6.0
- /is-extglob@2.1.1:
- resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ magic-string@1.4.4:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.6.0
- /is-fullwidth-code-point@3.0.0:
- resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
- engines: {node: '>=8'}
- dev: true
+ markdown-extensions@2.0.0: {}
- /is-glob@4.0.3:
- resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
- engines: {node: '>=0.10.0'}
- dependencies:
- is-extglob: 2.1.1
- dev: true
+ markdown-table@3.0.4: {}
- /is-interactive@1.0.0:
- resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
- engines: {node: '>=8'}
- dev: true
+ mdast-util-find-and-replace@3.0.4:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.1.0
- /is-lower-case@1.1.3:
- resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==}
+ mdast-util-from-markdown@2.1.0(supports-color@10.2.2):
dependencies:
- lower-case: 1.1.4
- dev: true
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.3(supports-color@10.2.2)
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
- /is-number@7.0.0:
- resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
- engines: {node: '>=0.12.0'}
- dev: true
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.4
+ micromark-util-character: 2.1.1
- /is-path-cwd@2.2.0:
- resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==}
- engines: {node: '>=6'}
- dev: true
+ mdast-util-gfm-footnote@2.1.0(supports-color@10.2.2):
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ micromark-util-normalize-identifier: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
- /is-path-inside@3.0.3:
- resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
- engines: {node: '>=8'}
- dev: true
+ mdast-util-gfm-strikethrough@2.0.1(supports-color@10.2.2):
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
- /is-property@1.0.2:
- resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==}
- dev: false
+ mdast-util-gfm-table@2.0.0(supports-color@10.2.2):
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.4
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
- /is-stream@2.0.1:
- resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
- engines: {node: '>=8'}
- dev: true
+ mdast-util-gfm-task-list-item@2.0.0(supports-color@10.2.2):
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
- /is-unicode-supported@0.1.0:
- resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
- engines: {node: '>=10'}
- dev: true
+ mdast-util-gfm@3.1.0(supports-color@10.2.2):
+ dependencies:
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.1.0(supports-color@10.2.2)
+ mdast-util-gfm-strikethrough: 2.0.1(supports-color@10.2.2)
+ mdast-util-gfm-table: 2.0.0(supports-color@10.2.2)
+ mdast-util-gfm-task-list-item: 2.0.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
- /is-upper-case@1.1.2:
- resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==}
+ mdast-util-mdx-expression@2.0.1(supports-color@10.2.2):
dependencies:
- upper-case: 1.1.3
- dev: true
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
- /isbinaryfile@4.0.10:
- resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==}
- engines: {node: '>= 8.0.0'}
- dev: true
+ mdast-util-mdx-jsx@3.2.0(supports-color@10.2.2):
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ parse-entities: 4.0.2
+ stringify-entities: 4.0.4
+ unist-util-stringify-position: 4.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
- /isexe@2.0.0:
- resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
- dev: true
+ mdast-util-mdx@3.0.0(supports-color@10.2.2):
+ dependencies:
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-mdx-expression: 2.0.1(supports-color@10.2.2)
+ mdast-util-mdx-jsx: 3.2.0(supports-color@10.2.2)
+ mdast-util-mdxjs-esm: 2.0.1(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
- /jiti@1.21.7:
- resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
- hasBin: true
- dev: true
+ mdast-util-mdxjs-esm@2.0.1(supports-color@10.2.2):
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
- /jiti@2.4.2:
- resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
- hasBin: true
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.4.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.2.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.2.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-character: 2.1.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ unist-util-visit: 5.2.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ merge-stream@2.0.0: {}
+
+ merge2@1.4.1: {}
+
+ micromark-core-commonmark@2.0.4:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.1.0
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-edit-map: 1.0.0
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.4
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-table@2.1.2:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.2
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-mdx-expression@3.0.1:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ micromark-factory-mdx-expression: 2.0.3
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /jiti@2.7.0:
- resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
- hasBin: true
- dev: false
+ micromark-extension-mdx-jsx@3.0.2:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ micromark-factory-mdx-expression: 2.0.3
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ vfile-message: 4.0.3
- /jose@6.2.3:
- resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==}
- dev: false
+ micromark-extension-mdx-md@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.3
- /joycon@3.1.1:
- resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
- engines: {node: '>=10'}
- dev: true
+ micromark-extension-mdxjs-esm@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.4
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.3
- /js-tokens@4.0.0:
- resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ micromark-extension-mdxjs@3.0.0:
+ dependencies:
+ acorn: 8.19.0
+ acorn-jsx: 5.3.2(acorn@8.19.0)
+ micromark-extension-mdx-expression: 3.0.1
+ micromark-extension-mdx-jsx: 3.0.2
+ micromark-extension-mdx-md: 2.0.0
+ micromark-extension-mdxjs-esm: 3.0.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.3
- /js-tokens@9.0.1:
- resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /js-yaml@4.3.0:
- resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==}
- hasBin: true
+ micromark-factory-label@2.0.1:
dependencies:
- argparse: 2.0.1
- dev: true
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /json-buffer@3.0.1:
- resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
- dev: true
+ micromark-factory-mdx-expression@2.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.3
- /json-schema-traverse@0.4.1:
- resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
- dev: true
+ micromark-factory-space@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.3
- /json-stable-stringify-without-jsonify@1.0.1:
- resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
- dev: true
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /jsonfile@6.2.1:
- resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==}
+ micromark-factory-whitespace@2.0.1:
dependencies:
- universalify: 2.0.1
- optionalDependencies:
- graceful-fs: 4.2.11
- dev: true
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /keyv@4.5.4:
- resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+ micromark-util-character@2.1.1:
dependencies:
- json-buffer: 3.0.1
- dev: true
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /kysely@0.29.6:
- resolution: {integrity: sha512-hHaB8C/rfzDDtr/t8YZwxAuPJTT0zHyaPoVzcXwDYhYNAgH/4sIfVhi/XLLIY+bL/FqaIJnjATDbi8ObSELmxg==}
- engines: {node: '>=22.0.0'}
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
- /levn@0.4.1:
- resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
- engines: {node: '>= 0.8.0'}
+ micromark-util-classify-character@2.0.1:
dependencies:
- prelude-ls: 1.2.1
- type-check: 0.4.0
- dev: true
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /libsql@0.5.29:
- resolution: {integrity: sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==}
- cpu: [x64, arm64, wasm32, arm]
- os: [darwin, linux, win32]
+ micromark-util-combine-extensions@2.0.1:
dependencies:
- '@neon-rs/load': 0.0.4
- detect-libc: 2.0.2
- optionalDependencies:
- '@libsql/darwin-arm64': 0.5.29
- '@libsql/darwin-x64': 0.5.29
- '@libsql/linux-arm-gnueabihf': 0.5.29
- '@libsql/linux-arm-musleabihf': 0.5.29
- '@libsql/linux-arm64-gnu': 0.5.29
- '@libsql/linux-arm64-musl': 0.5.29
- '@libsql/linux-x64-gnu': 0.5.29
- '@libsql/linux-x64-musl': 0.5.29
- '@libsql/win32-x64-msvc': 0.5.29
- dev: false
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.3
- /lilconfig@2.1.0:
- resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
- engines: {node: '>=10'}
- dev: true
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
- /lilconfig@3.1.3:
- resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
- engines: {node: '>=14'}
- dev: true
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
- /lines-and-columns@1.2.4:
- resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
- dev: true
+ micromark-util-edit-map@1.0.0:
+ dependencies:
+ micromark-util-types: 2.0.3
- /load-tsconfig@0.2.5:
- resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- dev: true
+ micromark-util-encode@2.0.1: {}
- /locate-path@6.0.0:
- resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
- engines: {node: '>=10'}
+ micromark-util-events-to-acorn@2.0.3:
dependencies:
- p-locate: 5.0.0
- dev: true
+ '@types/estree': 1.0.9
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ estree-util-visit: 2.0.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ vfile-message: 4.0.3
- /lodash.get@4.4.2:
- resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
- deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
- dev: true
+ micromark-util-html-tag-name@2.0.1: {}
- /lodash.merge@4.6.2:
- resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
- dev: true
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
- /lodash@4.18.1:
- resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
- dev: true
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.3
- /log-symbols@3.0.0:
- resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==}
- engines: {node: '>=8'}
+ micromark-util-sanitize-uri@2.0.1:
dependencies:
- chalk: 2.4.2
- dev: true
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
- /log-symbols@4.1.0:
- resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
- engines: {node: '>=10'}
+ micromark-util-subtokenize@2.1.0:
dependencies:
- chalk: 4.1.2
- is-unicode-supported: 0.1.0
- dev: true
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
- /long@5.3.2:
- resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
- dev: false
+ micromark-util-symbol@2.0.1: {}
- /loose-envify@1.4.0:
- resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
- hasBin: true
- dependencies:
- js-tokens: 4.0.0
+ micromark-util-types@2.0.3: {}
- /loupe@3.2.1:
- resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
+ micromark@4.0.3(supports-color@10.2.2):
+ dependencies:
+ '@types/debug': 4.1.13
+ debug: 4.4.3(supports-color@10.2.2)
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.4
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-edit-map: 1.0.0
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ transitivePeerDependencies:
+ - supports-color
- /lower-case-first@1.0.2:
- resolution: {integrity: sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==}
+ micromatch@4.0.8:
dependencies:
- lower-case: 1.1.4
- dev: true
+ braces: 3.0.3
+ picomatch: 2.3.2
- /lower-case@1.1.4:
- resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==}
- dev: true
+ mikro-orm@7.2.1: {}
- /lru-cache@7.18.3:
- resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
- engines: {node: '>=12'}
- dev: true
+ mime-db@1.33.0: {}
- /lru.min@1.1.5:
- resolution: {integrity: sha512-5J9ysMYUpYIg9RF2vJpy9SinEmSviFSe0GyPpCQ4L5QSkLAgeLXlTAOu2ZwWUU5m+0SBl6gUU1R1ZQB3aKypfA==}
- engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'}
- dev: false
+ mime-db@1.54.0: {}
- /magic-string@0.30.21:
- resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+ mime-types@2.1.18:
dependencies:
- '@jridgewell/sourcemap-codec': 1.5.5
-
- /make-error@1.3.6:
- resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
- dev: true
+ mime-db: 1.33.0
- /merge-stream@2.0.0:
- resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
- dev: true
+ mimic-fn@2.1.0: {}
- /merge2@1.4.1:
- resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
- engines: {node: '>= 8'}
- dev: true
+ miniflare@5.20261012.0-beta(@types/node@22.18.6):
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ sharp: 0.35.5(@types/node@22.18.6)
+ undici: 7.29.1
+ workerd: 1.20261012.1
+ ws: 8.21.0
+ youch: 4.1.0-beta.10
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
- /micromatch@4.0.8:
- resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
- engines: {node: '>=8.6'}
+ miniflare@5.20261019.1-beta(@types/node@22.18.6):
dependencies:
- braces: 3.0.3
- picomatch: 2.3.2
- dev: true
+ '@cspotcode/source-map-support': 0.8.1
+ sharp: 0.35.5(@types/node@22.18.6)
+ undici: 7.29.1
+ workerd: 1.20261019.1
+ ws: 8.21.0
+ youch: 4.1.0-beta.10
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
- /mimic-fn@2.1.0:
- resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
- engines: {node: '>=6'}
- dev: true
+ miniflare@5.20261019.1-beta(@types/node@26.6.5):
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ sharp: 0.35.5(@types/node@26.6.5)
+ undici: 7.29.1
+ workerd: 1.20261019.1
+ ws: 8.21.0
+ youch: 4.1.0-beta.10
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
- /minimatch@3.1.5:
- resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+ minimatch@10.2.6:
dependencies:
- brace-expansion: 1.1.16
- dev: true
+ brace-expansion: 5.0.12
- /minimatch@9.0.9:
- resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
- engines: {node: '>=16 || 14 >=14.17'}
+ minimatch@3.1.5:
dependencies:
- brace-expansion: 2.1.2
- dev: true
+ brace-expansion: 1.1.21
- /minimist@1.2.8:
- resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
- dev: true
+ minimist@1.2.8: {}
- /mkdirp@0.5.6:
- resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
- hasBin: true
+ minimizer-webpack-plugin@5.13.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))):
dependencies:
- minimist: 1.2.8
- dev: true
+ '@jridgewell/trace-mapping': 0.3.31
+ jest-worker: 27.5.1
+ schema-utils: 4.8.1(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6)))
+ terser: 5.51.2
+ webpack: 5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))
+ optionalDependencies:
+ esbuild: 0.28.2
+ lightningcss: 1.33.0
+ postcss: 8.4.39
+ sharp: 0.35.5(@types/node@22.18.6)
- /mlly@1.8.2:
- resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
+ mlly@1.8.2:
dependencies:
- acorn: 8.17.0
+ acorn: 8.19.0
pathe: 2.0.3
pkg-types: 1.3.1
ufo: 1.6.4
- dev: true
- /ms@2.1.3:
- resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ motion-dom@14.6.0:
+ dependencies:
+ motion-utils: 14.6.0
- /mute-stream@0.0.8:
- resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
- dev: true
+ motion-utils@14.6.0: {}
- /mysql2@3.24.4(@types/node@22.18.6):
- resolution: {integrity: sha512-A2olluVlj0mvgyIRRISMEzXc51m+21mRtcMVjJyIpt2GG98+XrC9m9HzsqcMsX2LcnfccJvY5NB22g8fENBnOA==}
- engines: {node: '>= 8.0'}
- peerDependencies:
- '@types/node': '>= 8'
+ motion@14.6.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
+ dependencies:
+ framer-motion: 14.6.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ tslib: 2.8.1
+ optionalDependencies:
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+
+ ms@2.0.0: {}
+
+ ms@2.1.3: {}
+
+ mute-stream@2.0.0: {}
+
+ mysql2@3.24.4(@types/node@20.14.11):
+ dependencies:
+ '@types/node': 20.14.11
+ aws-ssl-profiles: 1.1.2
+ generate-function: 2.3.1
+ iconv-lite: 0.7.3
+ long: 5.3.2
+ lru.min: 1.1.5
+ named-placeholders: 1.1.6
+ sql-escaper: 1.5.2
+
+ mysql2@3.24.4(@types/node@22.18.6):
dependencies:
'@types/node': 22.18.6
aws-ssl-profiles: 1.1.2
@@ -5027,73 +10718,98 @@ packages:
lru.min: 1.1.5
named-placeholders: 1.1.6
sql-escaper: 1.5.2
- dev: false
- /mz@2.7.0:
- resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+ mz@2.7.0:
dependencies:
any-promise: 1.3.0
object-assign: 4.1.1
thenify-all: 1.6.0
- dev: true
- /named-placeholders@1.1.6:
- resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==}
- engines: {node: '>=8.0.0'}
+ named-placeholders@1.1.6:
dependencies:
lru.min: 1.1.5
- dev: false
- /nanoid@3.3.15:
- resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
+ nanoid@3.3.20: {}
- /nanostores@1.4.0:
- resolution: {integrity: sha512-i0tloweeudshAEuddpDxcg9Ik6pkPfVsHIgKyf143JrgG7/MOh0+q7BypdLXZPoOP7fOYt1eTcwGkyiVmhJFkA==}
- engines: {node: ^20.0.0 || >=22.0.0}
- dev: false
+ nanostores@1.5.5: {}
- /natural-compare@1.4.0:
- resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
- dev: true
+ natural-compare@1.4.0: {}
- /neo-async@2.6.2:
- resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
- dev: true
+ negotiator@0.6.4: {}
+
+ neo-async@2.6.2: {}
+
+ next-themes@0.4.6(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
+ dependencies:
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+
+ next@14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ dependencies:
+ '@next/env': 14.2.35
+ '@swc/helpers': 0.5.5
+ '@types/react': 18.3.3
+ busboy: 1.6.0
+ caniuse-lite: 1.0.30001819
+ graceful-fs: 4.2.11
+ postcss: 8.4.31
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ styled-jsx: 5.1.1(react@18.3.1)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 14.2.33
+ '@next/swc-darwin-x64': 14.2.33
+ '@next/swc-linux-arm64-gnu': 14.2.33
+ '@next/swc-linux-arm64-musl': 14.2.33
+ '@next/swc-linux-x64-gnu': 14.2.33
+ '@next/swc-linux-x64-musl': 14.2.33
+ '@next/swc-win32-arm64-msvc': 14.2.33
+ '@next/swc-win32-ia32-msvc': 14.2.33
+ '@next/swc-win32-x64-msvc': 14.2.33
+ '@playwright/test': 1.64.1
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
- /netmask@2.1.1:
- resolution: {integrity: sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==}
- engines: {node: '>= 0.4.0'}
- dev: true
+ next@14.2.35(@playwright/test@1.64.1)(@types/react@18.3.3)(react-dom@18.3.1(react@19.3.1))(react@19.3.1):
+ dependencies:
+ '@next/env': 14.2.35
+ '@swc/helpers': 0.5.5
+ '@types/react': 18.3.3
+ busboy: 1.6.0
+ caniuse-lite: 1.0.30001819
+ graceful-fs: 4.2.11
+ postcss: 8.4.31
+ react: 19.3.1
+ react-dom: 18.3.1(react@19.3.1)
+ styled-jsx: 5.1.1(react@19.3.1)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 14.2.33
+ '@next/swc-darwin-x64': 14.2.33
+ '@next/swc-linux-arm64-gnu': 14.2.33
+ '@next/swc-linux-arm64-musl': 14.2.33
+ '@next/swc-linux-x64-gnu': 14.2.33
+ '@next/swc-linux-x64-musl': 14.2.33
+ '@next/swc-win32-arm64-msvc': 14.2.33
+ '@next/swc-win32-ia32-msvc': 14.2.33
+ '@next/swc-win32-x64-msvc': 14.2.33
+ '@playwright/test': 1.64.1
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
- /next@14.2.35(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==}
- engines: {node: '>=18.17.0'}
- hasBin: true
- peerDependencies:
- '@opentelemetry/api': ^1.1.0
- '@playwright/test': ^1.41.2
- react: ^18.2.0
- react-dom: ^18.2.0
- sass: ^1.3.0
- peerDependenciesMeta:
- '@opentelemetry/api':
- optional: true
- '@playwright/test':
- optional: true
- sass:
- optional: true
+ next@14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
dependencies:
'@next/env': 14.2.35
'@swc/helpers': 0.5.5
+ '@types/react': 19.3.0
busboy: 1.6.0
- caniuse-lite: 1.0.30001803
+ caniuse-lite: 1.0.30001819
graceful-fs: 4.2.11
postcss: 8.4.31
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- styled-jsx: 5.1.1(react@18.3.1)
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ styled-jsx: 5.1.1(react@19.3.1)
optionalDependencies:
'@next/swc-darwin-arm64': 14.2.33
'@next/swc-darwin-x64': 14.2.33
@@ -5104,85 +10820,98 @@ packages:
'@next/swc-win32-arm64-msvc': 14.2.33
'@next/swc-win32-ia32-msvc': 14.2.33
'@next/swc-win32-x64-msvc': 14.2.33
+ '@playwright/test': 1.64.1
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
- /no-case@2.3.2:
- resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==}
+ next@16.4.2(@playwright/test@1.64.1)(@types/node@20.14.11)(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
dependencies:
- lower-case: 1.1.4
- dev: true
+ '@next/env': 16.4.2
+ '@swc/helpers': 0.5.23
+ baseline-browser-mapping: 2.11.33
+ caniuse-lite: 1.0.30001819
+ postcss: 8.5.23
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ styled-jsx: 5.1.6(react@19.3.1)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 16.4.2
+ '@next/swc-darwin-x64': 16.4.2
+ '@next/swc-linux-arm64-gnu': 16.4.2
+ '@next/swc-linux-arm64-musl': 16.4.2
+ '@next/swc-linux-x64-gnu': 16.4.2
+ '@next/swc-linux-x64-musl': 16.4.2
+ '@next/swc-win32-arm64-msvc': 16.4.2
+ '@next/swc-win32-x64-msvc': 16.4.2
+ '@playwright/test': 1.64.1
+ sharp: 0.35.5(@types/node@20.14.11)
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@types/node'
+ - babel-plugin-macros
- /node-addon-api@8.9.2:
- resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==}
- engines: {node: ^18 || ^20 || >= 21}
+ next@16.4.2(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
+ dependencies:
+ '@next/env': 16.4.2
+ '@swc/helpers': 0.5.23
+ baseline-browser-mapping: 2.11.33
+ caniuse-lite: 1.0.30001819
+ postcss: 8.5.23
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ styled-jsx: 5.1.6(react@19.3.1)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 16.4.2
+ '@next/swc-darwin-x64': 16.4.2
+ '@next/swc-linux-arm64-gnu': 16.4.2
+ '@next/swc-linux-arm64-musl': 16.4.2
+ '@next/swc-linux-x64-gnu': 16.4.2
+ '@next/swc-linux-x64-musl': 16.4.2
+ '@next/swc-win32-arm64-msvc': 16.4.2
+ '@next/swc-win32-x64-msvc': 16.4.2
+ '@playwright/test': 1.64.1
+ sharp: 0.35.5(@types/node@26.6.5)
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@types/node'
+ - babel-plugin-macros
- /node-plop@0.26.3:
- resolution: {integrity: sha512-Cov028YhBZ5aB7MdMWJEmwyBig43aGL5WT4vdoB28Oitau1zZAcHUn8Sgfk9HM33TqhtLJ9PlM/O0Mv+QpV/4Q==}
- engines: {node: '>=8.9.4'}
- dependencies:
- '@babel/runtime-corejs3': 7.29.7
- '@types/inquirer': 6.5.0
- change-case: 3.1.0
- del: 5.1.0
- globby: 10.0.2
- handlebars: 4.7.9
- inquirer: 7.3.3
- isbinaryfile: 4.0.10
- lodash.get: 4.4.2
- mkdirp: 0.5.6
- resolve: 1.22.12
- dev: true
-
- /node-releases@2.0.51:
- resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==}
- engines: {node: '>=18'}
- dev: true
+ node-addon-api@8.9.2: {}
- /normalize-path@3.0.0:
- resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
- engines: {node: '>=0.10.0'}
- dev: true
+ node-releases@2.0.60: {}
- /normalize-range@0.1.2:
- resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
- engines: {node: '>=0.10.0'}
- dev: true
+ normalize-path@3.0.0: {}
- /npm-run-path@4.0.1:
- resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
- engines: {node: '>=8'}
+ normalize-range@0.1.2: {}
+
+ npm-run-path@4.0.1:
dependencies:
path-key: 3.1.1
- dev: true
- /object-assign@4.1.1:
- resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ npm-to-yarn@3.2.0: {}
- /object-hash@3.0.0:
- resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
- engines: {node: '>= 6'}
- dev: true
+ object-assign@4.1.1: {}
- /once@1.4.0:
- resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
- dependencies:
- wrappy: 1.0.2
- dev: true
+ object-hash@3.0.0: {}
- /onetime@5.1.2:
- resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
- engines: {node: '>=6'}
+ obug@3.0.0: {}
+
+ on-headers@1.1.0: {}
+
+ onetime@5.1.2:
dependencies:
mimic-fn: 2.1.0
- dev: true
- /optionator@0.9.4:
- resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
- engines: {node: '>= 0.8.0'}
+ oniguruma-parser@0.12.2: {}
+
+ oniguruma-to-es@4.3.6:
+ dependencies:
+ oniguruma-parser: 0.12.2
+ regex: 6.1.0
+ regex-recursion: 6.0.2
+
+ optionator@0.9.4:
dependencies:
deep-is: 0.1.4
fast-levenshtein: 2.0.6
@@ -5190,927 +10919,812 @@ packages:
prelude-ls: 1.2.1
type-check: 0.4.0
word-wrap: 1.2.5
- dev: true
-
- /ora@4.1.1:
- resolution: {integrity: sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==}
- engines: {node: '>=8'}
- dependencies:
- chalk: 3.0.0
- cli-cursor: 3.1.0
- cli-spinners: 2.9.2
- is-interactive: 1.0.0
- log-symbols: 3.0.0
- mute-stream: 0.0.8
- strip-ansi: 6.0.1
- wcwidth: 1.0.1
- dev: true
-
- /ora@5.4.1:
- resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
- engines: {node: '>=10'}
- dependencies:
- bl: 4.1.0
- chalk: 4.1.2
- cli-cursor: 3.1.0
- cli-spinners: 2.9.2
- is-interactive: 1.0.0
- is-unicode-supported: 0.1.0
- log-symbols: 4.1.0
- strip-ansi: 6.0.1
- wcwidth: 1.0.1
- dev: true
-
- /os-tmpdir@1.0.2:
- resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
- engines: {node: '>=0.10.0'}
- dev: true
- /p-limit@3.1.0:
- resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
- engines: {node: '>=10'}
+ p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
- dev: true
- /p-locate@5.0.0:
- resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
- engines: {node: '>=10'}
+ p-locate@5.0.0:
dependencies:
p-limit: 3.1.0
- dev: true
-
- /p-map@3.0.0:
- resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==}
- engines: {node: '>=8'}
- dependencies:
- aggregate-error: 3.1.0
- dev: true
-
- /pac-proxy-agent@7.2.0:
- resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==}
- engines: {node: '>= 14'}
- dependencies:
- '@tootallnate/quickjs-emscripten': 0.23.0
- agent-base: 7.1.4
- debug: 4.4.3
- get-uri: 6.0.5
- http-proxy-agent: 7.0.2
- https-proxy-agent: 7.0.6
- pac-resolver: 7.0.1
- socks-proxy-agent: 8.0.5
- transitivePeerDependencies:
- - supports-color
- dev: true
- /pac-resolver@7.0.1:
- resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==}
- engines: {node: '>= 14'}
- dependencies:
- degenerator: 5.0.1
- netmask: 2.1.1
- dev: true
-
- /param-case@2.1.1:
- resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==}
- dependencies:
- no-case: 2.3.2
- dev: true
+ pako@0.2.9: {}
- /parent-module@1.0.1:
- resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
- engines: {node: '>=6'}
+ parse-css-color@0.2.1:
dependencies:
- callsites: 3.1.0
- dev: true
+ color-name: 1.1.4
+ hex-rgb: 4.3.0
- /pascal-case@2.0.1:
- resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==}
+ parse-entities@4.0.2:
dependencies:
- camel-case: 3.0.0
- upper-case-first: 1.1.2
- dev: true
+ '@types/unist': 2.0.11
+ character-entities-legacy: 3.0.0
+ character-reference-invalid: 2.0.1
+ decode-named-character-reference: 1.3.0
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+ is-hexadecimal: 2.0.1
- /path-case@2.1.1:
- resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==}
- dependencies:
- no-case: 2.3.2
- dev: true
+ path-exists@4.0.0: {}
- /path-exists@4.0.0:
- resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
- engines: {node: '>=8'}
- dev: true
+ path-is-inside@1.0.2: {}
- /path-is-absolute@1.0.1:
- resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ path-key@3.1.1: {}
- /path-key@3.1.1:
- resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
- engines: {node: '>=8'}
- dev: true
+ path-parse@1.0.7: {}
- /path-parse@1.0.7:
- resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
- dev: true
+ path-to-regexp@3.3.0: {}
- /path-type@4.0.0:
- resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
- engines: {node: '>=8'}
- dev: true
+ path-to-regexp@6.3.0: {}
- /pathe@2.0.3:
- resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+ pathe@2.0.3: {}
- /pathval@2.0.1:
- resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
- engines: {node: '>= 14.16'}
+ pathval@2.0.1: {}
- /pg-cloudflare@1.4.0:
- resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==}
- requiresBuild: true
- dev: false
+ pg-cloudflare@1.4.1:
optional: true
- /pg-connection-string@2.14.0:
- resolution: {integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==}
- dev: false
+ pg-connection-string@2.14.1: {}
- /pg-cursor@2.22.0(pg@8.23.0):
- resolution: {integrity: sha512-knzXLKqarTjOvb3qDSW0JiGsazmxwEKXrqHfWRte7XUsOYccQRafn3BLnQobWwInkzFJSyOej8y8cQRh2z3kGw==}
- peerDependencies:
- pg: ^8
+ pg-cursor@2.22.0(pg@8.23.0):
dependencies:
pg: 8.23.0
- dev: false
- /pg-int8@1.0.1:
- resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
- engines: {node: '>=4.0.0'}
- dev: false
+ pg-int8@1.0.1: {}
- /pg-pool@3.14.0(pg@8.23.0):
- resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==}
- peerDependencies:
- pg: '>=8.0'
+ pg-pool@3.14.0(pg@8.23.0):
dependencies:
pg: 8.23.0
- dev: false
- /pg-protocol@1.16.0:
- resolution: {integrity: sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==}
- dev: false
+ pg-protocol@1.16.1: {}
- /pg-types@2.2.0:
- resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
- engines: {node: '>=4'}
+ pg-types@2.2.0:
dependencies:
pg-int8: 1.0.1
postgres-array: 2.0.0
postgres-bytea: 1.0.1
postgres-date: 1.0.7
postgres-interval: 1.2.0
- dev: false
- /pg@8.23.0:
- resolution: {integrity: sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==}
- engines: {node: '>= 16.0.0'}
- peerDependencies:
- pg-native: '>=3.0.1'
- peerDependenciesMeta:
- pg-native:
- optional: true
+ pg@8.23.0:
dependencies:
- pg-connection-string: 2.14.0
+ pg-connection-string: 2.14.1
pg-pool: 3.14.0(pg@8.23.0)
- pg-protocol: 1.16.0
+ pg-protocol: 1.16.1
pg-types: 2.2.0
pgpass: 1.0.5
optionalDependencies:
- pg-cloudflare: 1.4.0
- dev: false
+ pg-cloudflare: 1.4.1
- /pgpass@1.0.5:
- resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
+ pgpass@1.0.5:
dependencies:
split2: 4.2.0
- dev: false
-
- /picocolors@1.0.1:
- resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
- dev: true
- /picocolors@1.1.1:
- resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
-
- /picomatch@2.3.2:
- resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
- engines: {node: '>=8.6'}
- dev: true
+ picocolors@1.1.1: {}
- /picomatch@4.0.5:
- resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
- engines: {node: '>=12'}
+ picomatch@2.3.2: {}
- /pify@2.3.0:
- resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
- engines: {node: '>=0.10.0'}
- dev: true
+ picomatch@4.0.7: {}
- /pirates@4.0.7:
- resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
- engines: {node: '>= 6'}
- dev: true
+ pirates@4.0.7: {}
- /pkg-types@1.3.1:
- resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+ pkg-types@1.3.1:
dependencies:
confbox: 0.1.8
mlly: 1.8.2
pathe: 2.0.3
- dev: true
- /postcss-import@15.1.0(postcss@8.4.39):
- resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
- engines: {node: '>=14.0.0'}
- peerDependencies:
- postcss: ^8.0.0
+ playwright-core@1.64.1: {}
+
+ playwright@1.64.1:
+ dependencies:
+ playwright-core: 1.64.1
+
+ postcss-import@15.1.0(postcss@8.4.39):
dependencies:
postcss: 8.4.39
postcss-value-parser: 4.2.0
- read-cache: 1.0.0
- resolve: 1.22.12
- dev: true
+ read-cache: 1.0.2
+ resolve: 1.22.13
- /postcss-js@4.1.0(postcss@8.4.39):
- resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==}
- engines: {node: ^12 || ^14 || >= 16}
- peerDependencies:
- postcss: ^8.4.21
+ postcss-js@4.1.0(postcss@8.4.39):
dependencies:
camelcase-css: 2.0.1
postcss: 8.4.39
- dev: true
- /postcss-load-config@4.0.2(postcss@8.4.39):
- resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
- engines: {node: '>= 14'}
- peerDependencies:
- postcss: '>=8.0.9'
- ts-node: '>=9.0.0'
- peerDependenciesMeta:
- postcss:
- optional: true
- ts-node:
- optional: true
+ postcss-load-config@4.0.2(postcss@8.4.39):
dependencies:
- lilconfig: 3.1.3
+ lilconfig: 3.1.4
+ yaml: 2.9.1
+ optionalDependencies:
postcss: 8.4.39
- yaml: 2.9.0
- dev: true
- /postcss-load-config@6.0.1(jiti@2.4.2):
- resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
- engines: {node: '>= 18'}
- peerDependencies:
- jiti: '>=1.21.0'
- postcss: '>=8.0.9'
- tsx: ^4.8.1
- yaml: ^2.4.2
- peerDependenciesMeta:
- jiti:
- optional: true
- postcss:
- optional: true
- tsx:
- optional: true
- yaml:
- optional: true
+ postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.5.32)(yaml@2.9.1):
dependencies:
+ lilconfig: 3.1.4
+ optionalDependencies:
jiti: 2.4.2
- lilconfig: 3.1.3
- dev: true
+ postcss: 8.5.32
+ yaml: 2.9.1
- /postcss-nested@6.2.0(postcss@8.4.39):
- resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
- engines: {node: '>=12.0'}
- peerDependencies:
- postcss: ^8.2.14
+ postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.32)(yaml@2.9.1):
+ dependencies:
+ lilconfig: 3.1.4
+ optionalDependencies:
+ jiti: 2.7.0
+ postcss: 8.5.32
+ yaml: 2.9.1
+
+ postcss-nested@6.2.0(postcss@8.4.39):
dependencies:
postcss: 8.4.39
- postcss-selector-parser: 6.1.4
- dev: true
+ postcss-selector-parser: 6.1.5
- /postcss-selector-parser@6.1.4:
- resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==}
- engines: {node: '>=4'}
+ postcss-selector-parser@6.1.5:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
- dev: true
- /postcss-value-parser@4.2.0:
- resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
- dev: true
+ postcss-value-parser@4.2.0: {}
- /postcss@8.4.31:
- resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
- engines: {node: ^10 || ^12 || >=14}
+ postcss@8.4.31:
dependencies:
- nanoid: 3.3.15
+ nanoid: 3.3.20
picocolors: 1.1.1
- source-map-js: 1.2.1
+ source-map-js: 1.2.2
- /postcss@8.4.39:
- resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
- engines: {node: ^10 || ^12 || >=14}
+ postcss@8.4.39:
dependencies:
- nanoid: 3.3.15
+ nanoid: 3.3.20
picocolors: 1.1.1
- source-map-js: 1.2.1
- dev: true
+ source-map-js: 1.2.2
- /postcss@8.5.16:
- resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==}
- engines: {node: ^10 || ^12 || >=14}
+ postcss@8.5.23:
dependencies:
- nanoid: 3.3.15
+ nanoid: 3.3.20
picocolors: 1.1.1
- source-map-js: 1.2.1
-
- /postgres-array@2.0.0:
- resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
- engines: {node: '>=4'}
- dev: false
-
- /postgres-array@3.0.4:
- resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==}
- engines: {node: '>=12'}
- dev: false
-
- /postgres-bytea@1.0.1:
- resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==}
- engines: {node: '>=0.10.0'}
- dev: false
+ source-map-js: 1.2.2
- /postgres-date@1.0.7:
- resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
- engines: {node: '>=0.10.0'}
- dev: false
-
- /postgres-date@2.1.0:
- resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==}
- engines: {node: '>=12'}
- dev: false
-
- /postgres-interval@1.2.0:
- resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
- engines: {node: '>=0.10.0'}
+ postcss@8.5.32:
dependencies:
- xtend: 4.0.2
- dev: false
-
- /postgres-interval@4.1.0:
- resolution: {integrity: sha512-nJLACcOHi2iyRuMJeW6CuIA0Dc0i1YEpRr26XDyHAfxPjYUJOFxwZjmOc5oFFctTTh/OlRAMlnlXEJvr170fJg==}
- engines: {node: '>=12'}
- dev: false
-
- /prelude-ls@1.2.1:
- resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
- engines: {node: '>= 0.8.0'}
- dev: true
-
- /prettier-plugin-tailwindcss@0.6.5(prettier@3.3.3):
- resolution: {integrity: sha512-axfeOArc/RiGHjOIy9HytehlC0ZLeMaqY09mm8YCkMzznKiDkwFzOpBvtuhuv3xG5qB73+Mj7OCe2j/L1ryfuQ==}
- engines: {node: '>=14.21.3'}
- peerDependencies:
- '@ianvs/prettier-plugin-sort-imports': '*'
- '@prettier/plugin-pug': '*'
- '@shopify/prettier-plugin-liquid': '*'
- '@trivago/prettier-plugin-sort-imports': '*'
- '@zackad/prettier-plugin-twig-melody': '*'
- prettier: ^3.0
- prettier-plugin-astro: '*'
- prettier-plugin-css-order: '*'
- prettier-plugin-import-sort: '*'
- prettier-plugin-jsdoc: '*'
- prettier-plugin-marko: '*'
- prettier-plugin-organize-attributes: '*'
- prettier-plugin-organize-imports: '*'
- prettier-plugin-sort-imports: '*'
- prettier-plugin-style-order: '*'
- prettier-plugin-svelte: '*'
- peerDependenciesMeta:
- '@ianvs/prettier-plugin-sort-imports':
- optional: true
- '@prettier/plugin-pug':
- optional: true
- '@shopify/prettier-plugin-liquid':
- optional: true
- '@trivago/prettier-plugin-sort-imports':
- optional: true
- '@zackad/prettier-plugin-twig-melody':
- optional: true
- prettier-plugin-astro:
- optional: true
- prettier-plugin-css-order:
- optional: true
- prettier-plugin-import-sort:
- optional: true
- prettier-plugin-jsdoc:
- optional: true
- prettier-plugin-marko:
- optional: true
- prettier-plugin-organize-attributes:
- optional: true
- prettier-plugin-organize-imports:
- optional: true
- prettier-plugin-sort-imports:
- optional: true
- prettier-plugin-style-order:
- optional: true
- prettier-plugin-svelte:
- optional: true
+ nanoid: 3.3.20
+ picocolors: 1.1.1
+ source-map-js: 1.2.2
+
+ postgres-array@2.0.0: {}
+
+ postgres-array@3.0.4: {}
+
+ postgres-bytea@1.0.1: {}
+
+ postgres-date@1.0.7: {}
+
+ postgres-date@2.1.0: {}
+
+ postgres-interval@1.2.0:
dependencies:
- prettier: 3.3.3
- dev: false
+ xtend: 4.0.2
- /prettier@3.3.3:
- resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
- engines: {node: '>=14'}
- hasBin: true
+ postgres-interval@4.1.0: {}
- /proxy-agent@6.5.0:
- resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==}
- engines: {node: '>= 14'}
+ prelude-ls@1.2.1: {}
+
+ prettier-plugin-tailwindcss@0.6.14(prettier@3.9.10):
dependencies:
- agent-base: 7.1.4
- debug: 4.4.3
- http-proxy-agent: 7.0.2
- https-proxy-agent: 7.0.6
- lru-cache: 7.18.3
- pac-proxy-agent: 7.2.0
- proxy-from-env: 1.1.0
- socks-proxy-agent: 8.0.5
- transitivePeerDependencies:
- - supports-color
- dev: true
+ prettier: 3.9.10
- /proxy-from-env@1.1.0:
- resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
- dev: true
+ prettier@3.9.10: {}
- /punycode@2.3.1:
- resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
- engines: {node: '>=6'}
- dev: true
+ promise-limit@2.7.0: {}
- /qrcode.react@4.2.0(react@18.3.1):
- resolution: {integrity: sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ property-information@7.2.0: {}
+
+ punycode@2.3.1: {}
+
+ qified@0.10.1:
dependencies:
+ hookified: 2.2.0
+
+ qrcode.react@4.2.0(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ '@types/react': 18.3.3
react: 18.3.1
- dev: false
- /queue-microtask@1.2.3:
- resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
- dev: true
+ queue-microtask@1.2.3: {}
- /rc@1.2.8:
- resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
- hasBin: true
+ range-parser@1.2.0: {}
+
+ rc@1.2.8:
dependencies:
deep-extend: 0.6.0
ini: 1.3.8
minimist: 1.2.8
strip-json-comments: 2.0.1
- dev: true
- /react-dom@18.3.1(react@18.3.1):
- resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
- peerDependencies:
- react: ^18.3.1
+ react-dom@18.3.1(react@18.3.1):
dependencies:
loose-envify: 1.4.0
react: 18.3.1
scheduler: 0.23.2
- /react-hook-form@7.52.1(react@18.3.1):
- resolution: {integrity: sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==}
- engines: {node: '>=12.22.0'}
- peerDependencies:
- react: ^16.8.0 || ^17 || ^18 || ^19
+ react-dom@18.3.1(react@19.3.1):
+ dependencies:
+ loose-envify: 1.4.0
+ react: 19.3.1
+ scheduler: 0.23.2
+
+ react-dom@19.3.1(react@19.3.1):
+ dependencies:
+ react: 19.3.1
+ scheduler: 0.28.0
+
+ react-hook-form@7.52.1(react@18.3.1):
dependencies:
react: 18.3.1
- dev: false
- /react-remove-scroll-bar@2.3.8(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ react-remove-scroll-bar@2.3.8(@types/react@18.3.3)(react@18.3.1):
dependencies:
- '@types/react': 18.3.3
react: 18.3.1
react-style-singleton: 2.2.3(@types/react@18.3.3)(react@18.3.1)
tslib: 2.8.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /react-remove-scroll@2.5.5(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
- react: ^16.8.0 || ^17.0.0 || ^18.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ react-remove-scroll-bar@2.3.8(@types/react@19.3.0)(react@19.3.1):
+ dependencies:
+ react: 19.3.1
+ react-style-singleton: 2.2.3(@types/react@19.3.0)(react@19.3.1)
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ react-remove-scroll@2.5.5(@types/react@18.3.3)(react@18.3.1):
dependencies:
- '@types/react': 18.3.3
react: 18.3.1
react-remove-scroll-bar: 2.3.8(@types/react@18.3.3)(react@18.3.1)
react-style-singleton: 2.2.3(@types/react@18.3.3)(react@18.3.1)
tslib: 2.8.1
use-callback-ref: 1.3.3(@types/react@18.3.3)(react@18.3.1)
use-sidecar: 1.1.3(@types/react@18.3.3)(react@18.3.1)
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /react-style-singleton@2.2.3(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ react-remove-scroll@2.7.2(@types/react@19.3.0)(react@19.3.1):
+ dependencies:
+ react: 19.3.1
+ react-remove-scroll-bar: 2.3.8(@types/react@19.3.0)(react@19.3.1)
+ react-style-singleton: 2.2.3(@types/react@19.3.0)(react@19.3.1)
+ tslib: 2.8.1
+ use-callback-ref: 1.3.3(@types/react@19.3.0)(react@19.3.1)
+ use-sidecar: 1.1.3(@types/react@19.3.0)(react@19.3.1)
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))):
+ dependencies:
+ acorn-loose: 8.5.2
+ neo-async: 2.6.2
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ webpack: 5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))
+ webpack-sources: 3.6.0
+
+ react-style-singleton@2.2.3(@types/react@18.3.3)(react@18.3.1):
dependencies:
- '@types/react': 18.3.3
get-nonce: 1.0.1
react: 18.3.1
tslib: 2.8.1
- dev: false
+ optionalDependencies:
+ '@types/react': 18.3.3
- /react@18.3.1:
- resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
- engines: {node: '>=0.10.0'}
+ react-style-singleton@2.2.3(@types/react@19.3.0)(react@19.3.1):
+ dependencies:
+ get-nonce: 1.0.1
+ react: 19.3.1
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ react@18.3.1:
dependencies:
loose-envify: 1.4.0
- /read-cache@1.0.0:
- resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+ react@19.3.1: {}
+
+ read-cache@1.0.2: {}
+
+ readdirp@3.6.0:
dependencies:
- pify: 2.3.0
- dev: true
+ picomatch: 2.3.2
- /readable-stream@3.6.2:
- resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
- engines: {node: '>= 6'}
+ readdirp@4.1.2: {}
+
+ readdirp@5.1.1: {}
+
+ recma-build-jsx@1.0.0:
dependencies:
- inherits: 2.0.4
- string_decoder: 1.3.0
- util-deprecate: 1.0.2
- dev: true
+ '@types/estree': 1.0.9
+ estree-util-build-jsx: 3.0.1
+ vfile: 6.0.3
- /readdirp@3.6.0:
- resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
- engines: {node: '>=8.10.0'}
+ recma-jsx@1.0.1(acorn@8.19.0):
dependencies:
- picomatch: 2.3.2
- dev: true
+ acorn: 8.19.0
+ acorn-jsx: 5.3.2(acorn@8.19.0)
+ estree-util-to-js: 2.0.0
+ recma-parse: 1.0.0
+ recma-stringify: 1.0.0
+ unified: 11.0.5
- /readdirp@4.1.2:
- resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
- engines: {node: '>= 14.18.0'}
- dev: true
+ recma-parse@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ esast-util-from-js: 2.0.1
+ unified: 11.0.5
+ vfile: 6.0.3
- /registry-auth-token@3.3.2:
- resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==}
+ recma-stringify@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ estree-util-to-js: 2.0.0
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ regex-recursion@6.0.2:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ regex-utilities@2.3.0: {}
+
+ regex@6.1.0:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ registry-auth-token@3.3.2:
dependencies:
rc: 1.2.8
safe-buffer: 5.2.1
- dev: true
- /registry-url@3.1.0:
- resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==}
- engines: {node: '>=0.10.0'}
+ registry-url@3.1.0:
dependencies:
rc: 1.2.8
- dev: true
- /resolve-from@4.0.0:
- resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
- engines: {node: '>=4'}
- dev: true
+ rehype-recma@1.0.0(supports-color@10.2.2):
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/hast': 3.0.5
+ hast-util-to-estree: 3.1.3(supports-color@10.2.2)
+ transitivePeerDependencies:
+ - supports-color
- /resolve-from@5.0.0:
- resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
- engines: {node: '>=8'}
- dev: true
+ remark-gfm@4.0.1(supports-color@10.2.2):
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.1.0(supports-color@10.2.2)
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0(supports-color@10.2.2)
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
- /resolve@1.22.12:
- resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==}
- engines: {node: '>= 0.4'}
- hasBin: true
+ remark-mdx@3.1.1(supports-color@10.2.2):
dependencies:
- es-errors: 1.3.0
- is-core-module: 2.16.2
- path-parse: 1.0.7
- supports-preserve-symlinks-flag: 1.0.0
- dev: true
+ mdast-util-mdx: 3.0.0(supports-color@10.2.2)
+ micromark-extension-mdxjs: 3.0.0
+ transitivePeerDependencies:
+ - supports-color
- /restore-cursor@3.1.0:
- resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
- engines: {node: '>=8'}
+ remark-parse@11.0.0(supports-color@10.2.2):
dependencies:
- onetime: 5.1.2
- signal-exit: 3.0.7
- dev: true
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.1.0(supports-color@10.2.2)
+ micromark-util-types: 2.0.3
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
- /reusify@1.1.0:
- resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
- engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
- dev: true
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.1
+ unified: 11.0.5
+ vfile: 6.0.3
- /rimraf@3.0.2:
- resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
- deprecated: Rimraf versions prior to v4 are no longer supported
- hasBin: true
+ remark-stringify@11.0.0:
dependencies:
- glob: 7.2.3
- dev: true
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.2.0
+ unified: 11.0.5
- /rollup@4.62.2:
- resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==}
- engines: {node: '>=18.0.0', npm: '>=8.0.0'}
- hasBin: true
+ remark@15.0.1(supports-color@10.2.2):
+ dependencies:
+ '@types/mdast': 4.0.4
+ remark-parse: 11.0.0(supports-color@10.2.2)
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ require-directory@2.1.1: {}
+
+ require-from-string@2.0.2: {}
+
+ reselect@5.3.0: {}
+
+ resolve-from@5.0.0: {}
+
+ resolve@1.22.13:
+ dependencies:
+ es-errors: 1.3.0
+ is-core-module: 2.17.0
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ reusify@1.1.0: {}
+
+ rolldown@1.2.15:
+ dependencies:
+ '@oxc-project/types': 0.155.0
+ '@rolldown/pluginutils': 1.0.1
+ optionalDependencies:
+ '@rolldown/binding-android-arm-eabi': 1.2.15
+ '@rolldown/binding-android-arm64': 1.2.15
+ '@rolldown/binding-darwin-arm64': 1.2.15
+ '@rolldown/binding-darwin-x64': 1.2.15
+ '@rolldown/binding-freebsd-x64': 1.2.15
+ '@rolldown/binding-linux-arm-gnueabihf': 1.2.15
+ '@rolldown/binding-linux-arm64-gnu': 1.2.15
+ '@rolldown/binding-linux-arm64-musl': 1.2.15
+ '@rolldown/binding-linux-ppc64-gnu': 1.2.15
+ '@rolldown/binding-linux-s390x-gnu': 1.2.15
+ '@rolldown/binding-linux-x64-gnu': 1.2.15
+ '@rolldown/binding-linux-x64-musl': 1.2.15
+ '@rolldown/binding-openharmony-arm64': 1.2.15
+ '@rolldown/binding-win32-arm64-msvc': 1.2.15
+ '@rolldown/binding-win32-x64-msvc': 1.2.15
+
+ rollup@4.65.1:
dependencies:
'@types/estree': 1.0.9
optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.62.2
- '@rollup/rollup-android-arm64': 4.62.2
- '@rollup/rollup-darwin-arm64': 4.62.2
- '@rollup/rollup-darwin-x64': 4.62.2
- '@rollup/rollup-freebsd-arm64': 4.62.2
- '@rollup/rollup-freebsd-x64': 4.62.2
- '@rollup/rollup-linux-arm-gnueabihf': 4.62.2
- '@rollup/rollup-linux-arm-musleabihf': 4.62.2
- '@rollup/rollup-linux-arm64-gnu': 4.62.2
- '@rollup/rollup-linux-arm64-musl': 4.62.2
- '@rollup/rollup-linux-loong64-gnu': 4.62.2
- '@rollup/rollup-linux-loong64-musl': 4.62.2
- '@rollup/rollup-linux-ppc64-gnu': 4.62.2
- '@rollup/rollup-linux-ppc64-musl': 4.62.2
- '@rollup/rollup-linux-riscv64-gnu': 4.62.2
- '@rollup/rollup-linux-riscv64-musl': 4.62.2
- '@rollup/rollup-linux-s390x-gnu': 4.62.2
- '@rollup/rollup-linux-x64-gnu': 4.62.2
- '@rollup/rollup-linux-x64-musl': 4.62.2
- '@rollup/rollup-openbsd-x64': 4.62.2
- '@rollup/rollup-openharmony-arm64': 4.62.2
- '@rollup/rollup-win32-arm64-msvc': 4.62.2
- '@rollup/rollup-win32-ia32-msvc': 4.62.2
- '@rollup/rollup-win32-x64-gnu': 4.62.2
- '@rollup/rollup-win32-x64-msvc': 4.62.2
+ '@napi-rs/lzma-linux-x64-gnu': 1.5.1
+ '@rollup/rollup-android-arm-eabi': 4.65.1
+ '@rollup/rollup-android-arm64': 4.65.1
+ '@rollup/rollup-darwin-arm64': 4.65.1
+ '@rollup/rollup-darwin-x64': 4.65.1
+ '@rollup/rollup-freebsd-arm64': 4.65.1
+ '@rollup/rollup-freebsd-x64': 4.65.1
+ '@rollup/rollup-linux-arm-gnueabihf': 4.65.1
+ '@rollup/rollup-linux-arm-musleabihf': 4.65.1
+ '@rollup/rollup-linux-arm64-gnu': 4.65.1
+ '@rollup/rollup-linux-arm64-musl': 4.65.1
+ '@rollup/rollup-linux-loong64-gnu': 4.65.1
+ '@rollup/rollup-linux-loong64-musl': 4.65.1
+ '@rollup/rollup-linux-ppc64-gnu': 4.65.1
+ '@rollup/rollup-linux-ppc64-musl': 4.65.1
+ '@rollup/rollup-linux-riscv64-gnu': 4.65.1
+ '@rollup/rollup-linux-riscv64-musl': 4.65.1
+ '@rollup/rollup-linux-s390x-gnu': 4.65.1
+ '@rollup/rollup-linux-x64-gnu': 4.65.1
+ '@rollup/rollup-linux-x64-musl': 4.65.1
+ '@rollup/rollup-openbsd-x64': 4.65.1
+ '@rollup/rollup-openharmony-arm64': 4.65.1
+ '@rollup/rollup-win32-arm64-msvc': 4.65.1
+ '@rollup/rollup-win32-ia32-msvc': 4.65.1
+ '@rollup/rollup-win32-x64-gnu': 4.65.1
+ '@rollup/rollup-win32-x64-msvc': 4.65.1
fsevents: 2.3.3
- /rou3@0.9.2:
- resolution: {integrity: sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==}
- dev: false
-
- /run-async@2.4.1:
- resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
- engines: {node: '>=0.12.0'}
- dev: true
+ rou3@0.9.2: {}
- /run-parallel@1.2.0:
- resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
- dev: true
- /rxjs@6.6.7:
- resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==}
- engines: {npm: '>=2.0.0'}
+ safe-buffer@5.2.1: {}
+
+ safer-buffer@2.1.2: {}
+
+ satori@0.33.5:
dependencies:
- tslib: 1.14.1
- dev: true
+ '@shuding/opentype.js': 1.4.0-beta.0
+ css-background-parser: 0.1.0
+ css-box-shadow: 1.0.0-3
+ css-gradient-parser: 0.0.17
+ css-to-react-native: 3.2.0
+ emoji-regex-xs: 2.0.1
+ escape-html: 1.0.3
+ fflate: 0.7.3
+ harfbuzzjs: 0.10.0
+ linebreak: 1.1.0
+ parse-css-color: 0.2.1
+ postcss-value-parser: 4.2.0
+ yoga-layout: 3.2.1
- /rxjs@7.8.2:
- resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
+ scheduler@0.23.2:
dependencies:
- tslib: 2.8.1
- dev: true
+ loose-envify: 1.4.0
- /safe-buffer@5.2.1:
- resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
- dev: true
+ scheduler@0.28.0: {}
- /safer-buffer@2.1.2:
- resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ schema-utils@4.8.1(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))):
+ dependencies:
+ '@types/json-schema': 7.0.15
+ ajv: 8.20.0
+ ajv-formats: 3.0.1
+ ajv-keywords: 5.1.0(ajv@8.20.0)
+ optionalDependencies:
+ webpack: 5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))
- /scheduler@0.23.2:
- resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
+ scroll-into-view-if-needed@3.1.0:
dependencies:
- loose-envify: 1.4.0
+ compute-scroll-into-view: 3.1.1
- /sdp@3.2.2:
- resolution: {integrity: sha512-xZocWwfyp4hkbN4hLWxMjmv2Q8aNa9MhmOZ7L9aCZPT+dZsgRr6wZRrSYE3HTdyk/2pZKPSgqI7ns7Een1xMSA==}
- dev: false
+ sdp@3.2.2: {}
- /semver@7.8.5:
- resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
- engines: {node: '>=10'}
- hasBin: true
- dev: true
+ semver@7.8.5: {}
- /sentence-case@2.1.1:
- resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==}
+ serve-handler@6.1.7:
dependencies:
- no-case: 2.3.2
- upper-case-first: 1.1.2
- dev: true
+ bytes: 3.0.0
+ content-disposition: 0.5.2
+ mime-types: 2.1.18
+ minimatch: 3.1.5
+ path-is-inside: 1.0.2
+ path-to-regexp: 3.3.0
+ range-parser: 1.2.0
+
+ serve@14.2.6(supports-color@10.2.2):
+ dependencies:
+ '@zeit/schemas': 2.36.0
+ ajv: 8.18.0
+ arg: 5.0.2
+ boxen: 7.0.0
+ chalk: 5.0.1
+ chalk-template: 0.4.0
+ clipboardy: 3.0.0
+ compression: 1.8.1(supports-color@10.2.2)
+ is-port-reachable: 4.0.0
+ serve-handler: 6.1.7
+ update-check: 1.5.4
+ transitivePeerDependencies:
+ - supports-color
- /set-cookie-parser@3.1.2:
- resolution: {integrity: sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==}
- dev: false
+ set-cookie-parser@3.2.1: {}
- /shebang-command@2.0.0:
- resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
- engines: {node: '>=8'}
+ sharp@0.35.5(@types/node@20.14.11):
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.5
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.35.5
+ '@img/sharp-darwin-x64': 0.35.5
+ '@img/sharp-freebsd-wasm32': 0.35.5
+ '@img/sharp-libvips-darwin-arm64': 1.3.4
+ '@img/sharp-libvips-darwin-x64': 1.3.4
+ '@img/sharp-libvips-linux-arm': 1.3.4
+ '@img/sharp-libvips-linux-arm64': 1.3.4
+ '@img/sharp-libvips-linux-ppc64': 1.3.4
+ '@img/sharp-libvips-linux-riscv64': 1.3.4
+ '@img/sharp-libvips-linux-s390x': 1.3.4
+ '@img/sharp-libvips-linux-x64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.3.4
+ '@img/sharp-linux-arm': 0.35.5
+ '@img/sharp-linux-arm64': 0.35.5
+ '@img/sharp-linux-ppc64': 0.35.5
+ '@img/sharp-linux-riscv64': 0.35.5
+ '@img/sharp-linux-s390x': 0.35.5
+ '@img/sharp-linux-x64': 0.35.5
+ '@img/sharp-linuxmusl-arm64': 0.35.5
+ '@img/sharp-linuxmusl-x64': 0.35.5
+ '@img/sharp-webcontainers-wasm32': 0.35.5
+ '@img/sharp-win32-arm64': 0.35.5
+ '@img/sharp-win32-ia32': 0.35.5
+ '@img/sharp-win32-x64': 0.35.5
+ '@types/node': 20.14.11
+ optional: true
+
+ sharp@0.35.5(@types/node@22.18.6):
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.5
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.35.5
+ '@img/sharp-darwin-x64': 0.35.5
+ '@img/sharp-freebsd-wasm32': 0.35.5
+ '@img/sharp-libvips-darwin-arm64': 1.3.4
+ '@img/sharp-libvips-darwin-x64': 1.3.4
+ '@img/sharp-libvips-linux-arm': 1.3.4
+ '@img/sharp-libvips-linux-arm64': 1.3.4
+ '@img/sharp-libvips-linux-ppc64': 1.3.4
+ '@img/sharp-libvips-linux-riscv64': 1.3.4
+ '@img/sharp-libvips-linux-s390x': 1.3.4
+ '@img/sharp-libvips-linux-x64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.3.4
+ '@img/sharp-linux-arm': 0.35.5
+ '@img/sharp-linux-arm64': 0.35.5
+ '@img/sharp-linux-ppc64': 0.35.5
+ '@img/sharp-linux-riscv64': 0.35.5
+ '@img/sharp-linux-s390x': 0.35.5
+ '@img/sharp-linux-x64': 0.35.5
+ '@img/sharp-linuxmusl-arm64': 0.35.5
+ '@img/sharp-linuxmusl-x64': 0.35.5
+ '@img/sharp-webcontainers-wasm32': 0.35.5
+ '@img/sharp-win32-arm64': 0.35.5
+ '@img/sharp-win32-ia32': 0.35.5
+ '@img/sharp-win32-x64': 0.35.5
+ '@types/node': 22.18.6
+
+ sharp@0.35.5(@types/node@26.6.5):
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.5
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.35.5
+ '@img/sharp-darwin-x64': 0.35.5
+ '@img/sharp-freebsd-wasm32': 0.35.5
+ '@img/sharp-libvips-darwin-arm64': 1.3.4
+ '@img/sharp-libvips-darwin-x64': 1.3.4
+ '@img/sharp-libvips-linux-arm': 1.3.4
+ '@img/sharp-libvips-linux-arm64': 1.3.4
+ '@img/sharp-libvips-linux-ppc64': 1.3.4
+ '@img/sharp-libvips-linux-riscv64': 1.3.4
+ '@img/sharp-libvips-linux-s390x': 1.3.4
+ '@img/sharp-libvips-linux-x64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.3.4
+ '@img/sharp-linux-arm': 0.35.5
+ '@img/sharp-linux-arm64': 0.35.5
+ '@img/sharp-linux-ppc64': 0.35.5
+ '@img/sharp-linux-riscv64': 0.35.5
+ '@img/sharp-linux-s390x': 0.35.5
+ '@img/sharp-linux-x64': 0.35.5
+ '@img/sharp-linuxmusl-arm64': 0.35.5
+ '@img/sharp-linuxmusl-x64': 0.35.5
+ '@img/sharp-webcontainers-wasm32': 0.35.5
+ '@img/sharp-win32-arm64': 0.35.5
+ '@img/sharp-win32-ia32': 0.35.5
+ '@img/sharp-win32-x64': 0.35.5
+ '@types/node': 26.6.5
+
+ shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
- dev: true
- /shebang-regex@3.0.0:
- resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
- engines: {node: '>=8'}
- dev: true
+ shebang-regex@3.0.0: {}
- /siginfo@2.0.0:
- resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+ shiki@4.5.0:
+ dependencies:
+ '@shikijs/core': 4.5.0
+ '@shikijs/engine-javascript': 4.5.0
+ '@shikijs/engine-oniguruma': 4.5.0
+ '@shikijs/langs': 4.5.0
+ '@shikijs/themes': 4.5.0
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
- /signal-exit@3.0.7:
- resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
- dev: true
+ siginfo@2.0.0: {}
- /slash@3.0.0:
- resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
- engines: {node: '>=8'}
- dev: true
+ signal-exit@3.0.7: {}
- /smart-buffer@4.2.0:
- resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
- engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
- dev: true
+ signal-exit@4.1.0: {}
- /snake-case@2.1.0:
- resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==}
+ sonner@1.7.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
- no-case: 2.3.2
- dev: true
+ '@types/react': 18.3.3
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
- /socks-proxy-agent@8.0.5:
- resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==}
- engines: {node: '>= 14'}
+ sonner@1.7.4(@types/react@18.3.3)(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
dependencies:
- agent-base: 7.1.4
- debug: 4.4.3
- socks: 2.8.9
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@types/react': 18.3.3
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
- /socks@2.8.9:
- resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==}
- engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
+ sonner@1.7.4(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
dependencies:
- ip-address: 10.2.0
- smart-buffer: 4.2.0
- dev: true
+ '@types/react': 19.3.0
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
- /sonner@1.5.0(react-dom@18.3.1)(react@18.3.1):
- resolution: {integrity: sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA==}
- peerDependencies:
- react: ^18.0.0
- react-dom: ^18.0.0
+ source-map-js@1.2.2: {}
+
+ source-map-support@0.5.21:
dependencies:
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- dev: false
+ buffer-from: 1.1.2
+ source-map: 0.6.1
- /source-map-js@1.2.1:
- resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
- engines: {node: '>=0.10.0'}
+ source-map@0.6.1: {}
- /source-map@0.6.1:
- resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
- engines: {node: '>=0.10.0'}
- dev: true
+ source-map@0.7.6: {}
- /source-map@0.7.6:
- resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
- engines: {node: '>= 12'}
- dev: true
+ space-separated-tokens@2.0.2: {}
- /split2@4.2.0:
- resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
- engines: {node: '>= 10.x'}
- dev: false
+ split2@4.2.0: {}
- /sql-escaper@1.5.2:
- resolution: {integrity: sha512-6CKD38c31SENivxOADeMNLdukOnUxUcflKtzVWzace7Riv1v7cAEym5Cx9Q7gYZ3ezIJI7ZpqecQq8cqNeSSFg==}
- engines: {bun: '>=1.0.0', deno: '>=2.0.0', node: '>=12.0.0'}
- dev: false
+ sql-escaper@1.5.2: {}
- /sqlstring@2.3.3:
- resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==}
- engines: {node: '>= 0.6'}
- dev: false
+ sqlstring@2.3.3: {}
- /stackback@0.0.2:
- resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+ srvx@1.0.7: {}
- /std-env@3.10.0:
- resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
+ stackback@0.0.2: {}
- /streamsearch@1.1.0:
- resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
- engines: {node: '>=10.0.0'}
+ std-env@3.10.0: {}
- /string-width@4.2.3:
- resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
- engines: {node: '>=8'}
+ streamsearch@1.1.0: {}
+
+ string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
- dev: true
- /string_decoder@1.3.0:
- resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+ string-width@5.1.2:
dependencies:
- safe-buffer: 5.2.1
- dev: true
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.2.0
- /strip-ansi@6.0.1:
- resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
- engines: {node: '>=8'}
+ string.prototype.codepointat@0.2.1: {}
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
- dev: true
- /strip-final-newline@2.0.0:
- resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
- engines: {node: '>=6'}
- dev: true
+ strip-ansi@7.2.0:
+ dependencies:
+ ansi-regex: 6.4.0
- /strip-json-comments@2.0.1:
- resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ strip-final-newline@2.0.0: {}
- /strip-json-comments@3.1.1:
- resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
- engines: {node: '>=8'}
- dev: true
+ strip-json-comments@2.0.1: {}
+
+ strip-literal@3.1.0:
+ dependencies:
+ js-tokens: 9.0.1
+
+ strip-literal@4.0.0:
+ dependencies:
+ js-tokens: 10.0.0
- /strip-literal@3.1.0:
- resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
+ style-to-js@1.1.21:
dependencies:
- js-tokens: 9.0.1
+ style-to-object: 1.0.14
- /strnum@1.1.2:
- resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==}
- dev: false
+ style-to-object@1.0.14:
+ dependencies:
+ inline-style-parser: 0.2.7
- /styled-jsx@5.1.1(react@18.3.1):
- resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
- engines: {node: '>= 12.0.0'}
- peerDependencies:
- '@babel/core': '*'
- babel-plugin-macros: '*'
- react: '>= 16.8.0 || 17.x.x || ^18.0.0-0'
- peerDependenciesMeta:
- '@babel/core':
- optional: true
- babel-plugin-macros:
- optional: true
+ styled-jsx@5.1.1(react@18.3.1):
dependencies:
client-only: 0.0.1
react: 18.3.1
- /sucrase@3.35.1:
- resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
- engines: {node: '>=16 || 14 >=14.17'}
- hasBin: true
+ styled-jsx@5.1.1(react@19.3.1):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.3.1
+
+ styled-jsx@5.1.6(react@19.3.1):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.3.1
+
+ sucrase@3.35.1:
dependencies:
'@jridgewell/gen-mapping': 0.3.13
commander: 4.1.1
@@ -6119,52 +11733,30 @@ packages:
pirates: 4.0.7
tinyglobby: 0.2.17
ts-interface-checker: 0.1.13
- dev: true
- /supports-color@5.5.0:
- resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
- engines: {node: '>=4'}
+ supports-color@10.2.2: {}
+
+ supports-color@7.2.0:
dependencies:
- has-flag: 3.0.0
- dev: true
+ has-flag: 4.0.0
- /supports-color@7.2.0:
- resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
- engines: {node: '>=8'}
+ supports-color@8.1.1:
dependencies:
has-flag: 4.0.0
- dev: true
- /supports-preserve-symlinks-flag@1.0.0:
- resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
- engines: {node: '>= 0.4'}
- dev: true
+ supports-preserve-symlinks-flag@1.0.0: {}
- /swap-case@1.1.2:
- resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==}
- dependencies:
- lower-case: 1.1.4
- upper-case: 1.1.3
- dev: true
+ tagged-tag@1.0.0: {}
- /tailwind-merge@2.4.0:
- resolution: {integrity: sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A==}
- dev: false
+ tailwind-merge@2.6.1: {}
- /tailwindcss-animate@1.0.7(tailwindcss@3.4.6):
- resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
- peerDependencies:
- tailwindcss: '>=3.0.0 || insiders'
+ tailwindcss-animate@1.0.7(tailwindcss@3.4.6):
dependencies:
tailwindcss: 3.4.6
- dev: true
- /tailwindcss@3.4.6:
- resolution: {integrity: sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==}
- engines: {node: '>=14.0.0'}
- hasBin: true
+ tailwindcss@3.4.6:
dependencies:
- '@alloc/quick-lru': 5.2.0
+ '@alloc/quick-lru': 5.3.0
arg: 5.0.2
chokidar: 3.6.0
didyoumean: 1.2.2
@@ -6183,376 +11775,504 @@ packages:
postcss-js: 4.1.0(postcss@8.4.39)
postcss-load-config: 4.0.2(postcss@8.4.39)
postcss-nested: 6.2.0(postcss@8.4.39)
- postcss-selector-parser: 6.1.4
- resolve: 1.22.12
+ postcss-selector-parser: 6.1.5
+ resolve: 1.22.13
sucrase: 3.35.1
transitivePeerDependencies:
- ts-node
- dev: true
- /text-table@0.2.0:
- resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
- dev: true
+ tailwindcss@4.3.3: {}
- /thenify-all@1.6.0:
- resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
- engines: {node: '>=0.8'}
+ tapable@2.3.3: {}
+
+ terser@5.51.2:
+ dependencies:
+ '@jridgewell/source-map': 0.3.11
+ acorn: 8.19.0
+ commander: 2.20.3
+ source-map-support: 0.5.21
+
+ thenify-all@1.6.0:
dependencies:
thenify: 3.3.1
- dev: true
- /thenify@3.3.1:
- resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+ thenify@3.3.1:
dependencies:
any-promise: 1.3.0
- dev: true
-
- /through@2.3.8:
- resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
- dev: true
- /tinybench@2.9.0:
- resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+ tiny-inflate@1.0.3: {}
- /tinycolor2@1.6.0:
- resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
- dev: true
+ tinybench@2.9.0: {}
- /tinyexec@0.3.2:
- resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+ tinyexec@0.3.2: {}
- /tinyglobby@0.2.17:
- resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
- engines: {node: '>=12.0.0'}
- dependencies:
- fdir: 6.5.0(picomatch@4.0.5)
- picomatch: 4.0.5
+ tinyexec@1.3.1: {}
- /tinygradient@1.1.5:
- resolution: {integrity: sha512-8nIfc2vgQ4TeLnk2lFj4tRLvvJwEfQuabdsmvDdQPT0xlk9TaNtpGd6nNRxXoK6vQhN6RSzj+Cnp5tTQmpxmbw==}
+ tinyglobby@0.2.17:
dependencies:
- '@types/tinycolor2': 1.4.6
- tinycolor2: 1.6.0
- dev: true
+ fdir: 6.5.0(picomatch@4.0.7)
+ picomatch: 4.0.7
- /tinypool@1.1.1:
- resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
- engines: {node: ^18.0.0 || >=20.0.0}
+ tinypool@1.1.1: {}
- /tinyrainbow@2.0.0:
- resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
- engines: {node: '>=14.0.0'}
+ tinyrainbow@2.0.0: {}
- /tinyspy@4.0.4:
- resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==}
- engines: {node: '>=14.0.0'}
+ tinyspy@4.0.6: {}
- /title-case@2.1.1:
- resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==}
+ to-regex-range@5.0.1:
dependencies:
- no-case: 2.3.2
- upper-case: 1.1.3
- dev: true
+ is-number: 7.0.0
- /tmp@0.0.33:
- resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
- engines: {node: '>=0.6.0'}
- dependencies:
- os-tmpdir: 1.0.2
- dev: true
+ tree-kill@1.2.2: {}
- /to-regex-range@5.0.1:
- resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
- engines: {node: '>=8.0'}
- dependencies:
- is-number: 7.0.0
- dev: true
+ trim-lines@3.0.1: {}
- /tree-kill@1.2.2:
- resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
- hasBin: true
- dev: true
+ trough@2.2.0: {}
- /ts-interface-checker@0.1.13:
- resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
- dev: true
+ ts-interface-checker@0.1.13: {}
- /ts-node@10.9.2(@types/node@20.14.11)(typescript@5.9.3):
- resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
- hasBin: true
- peerDependencies:
- '@swc/core': '>=1.2.50'
- '@swc/wasm': '>=1.2.50'
- '@types/node': '*'
- typescript: '>=2.7'
- peerDependenciesMeta:
- '@swc/core':
- optional: true
- '@swc/wasm':
- optional: true
+ tslib@2.8.1: {}
+
+ tsup@8.5.1(jiti@2.4.2)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1):
dependencies:
- '@cspotcode/source-map-support': 0.8.1
- '@tsconfig/node10': 1.0.12
- '@tsconfig/node12': 1.0.11
- '@tsconfig/node14': 1.0.3
- '@tsconfig/node16': 1.0.4
- '@types/node': 20.14.11
- acorn: 8.17.0
- acorn-walk: 8.3.5
- arg: 4.1.3
- create-require: 1.1.1
- diff: 4.0.4
- make-error: 1.3.6
+ bundle-require: 5.1.0(esbuild@0.27.7)
+ cac: 6.7.14
+ chokidar: 4.0.3
+ consola: 3.4.2
+ debug: 4.4.3(supports-color@10.2.2)
+ esbuild: 0.27.7
+ fix-dts-default-cjs-exports: 1.0.1
+ joycon: 3.1.1
+ picocolors: 1.1.1
+ postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.5.32)(yaml@2.9.1)
+ resolve-from: 5.0.0
+ rollup: 4.65.1
+ source-map: 0.7.6
+ sucrase: 3.35.1
+ tinyexec: 0.3.2
+ tinyglobby: 0.2.17
+ tree-kill: 1.2.2
+ optionalDependencies:
+ postcss: 8.5.32
typescript: 5.9.3
- v8-compile-cache-lib: 3.0.1
- yn: 3.1.1
- dev: true
-
- /tslib@1.14.1:
- resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
- dev: true
-
- /tslib@2.8.1:
- resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+ transitivePeerDependencies:
+ - jiti
+ - supports-color
+ - tsx
+ - yaml
- /tsup@8.5.1(jiti@2.4.2)(typescript@5.9.3):
- resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==}
- engines: {node: '>=18'}
- hasBin: true
- peerDependencies:
- '@microsoft/api-extractor': ^7.36.0
- '@swc/core': ^1
- postcss: ^8.4.12
- typescript: '>=4.5.0'
- peerDependenciesMeta:
- '@microsoft/api-extractor':
- optional: true
- '@swc/core':
- optional: true
- postcss:
- optional: true
- typescript:
- optional: true
+ tsup@8.5.1(jiti@2.7.0)(postcss@8.5.32)(supports-color@10.2.2)(typescript@5.9.3)(yaml@2.9.1):
dependencies:
bundle-require: 5.1.0(esbuild@0.27.7)
cac: 6.7.14
chokidar: 4.0.3
consola: 3.4.2
- debug: 4.4.3
+ debug: 4.4.3(supports-color@10.2.2)
esbuild: 0.27.7
fix-dts-default-cjs-exports: 1.0.1
joycon: 3.1.1
picocolors: 1.1.1
- postcss-load-config: 6.0.1(jiti@2.4.2)
+ postcss-load-config: 6.0.1(jiti@2.7.0)(postcss@8.5.32)(yaml@2.9.1)
resolve-from: 5.0.0
- rollup: 4.62.2
+ rollup: 4.65.1
source-map: 0.7.6
sucrase: 3.35.1
tinyexec: 0.3.2
tinyglobby: 0.2.17
tree-kill: 1.2.2
+ optionalDependencies:
+ postcss: 8.5.32
typescript: 5.9.3
transitivePeerDependencies:
- jiti
- supports-color
- tsx
- yaml
- dev: true
- /turbo-darwin-64@2.0.9:
- resolution: {integrity: sha512-owlGsOaExuVGBUfrnJwjkL1BWlvefjSKczEAcpLx4BI7Oh6ttakOi+JyomkPkFlYElRpjbvlR2gP8WIn6M/+xQ==}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
+ turbo-stream@3.2.1: {}
- /turbo-darwin-arm64@2.0.9:
- resolution: {integrity: sha512-XAXkKkePth5ZPPE/9G9tTnPQx0C8UTkGWmNGYkpmGgRr8NedW+HrPsi9N0HcjzzIH9A4TpNYvtiV+WcwdaEjKA==}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
+ turbo@2.11.10:
+ optionalDependencies:
+ '@turbo/darwin-64': 2.11.10
+ '@turbo/darwin-arm64': 2.11.10
+ '@turbo/linux-64': 2.11.10
+ '@turbo/linux-arm64': 2.11.10
+ '@turbo/windows-64': 2.11.10
+ '@turbo/windows-arm64': 2.11.10
- /turbo-linux-64@2.0.9:
- resolution: {integrity: sha512-l9wSgEjrCFM1aG16zItBsZ206ZlhSSx1owB8Cgskfv0XyIXRGHRkluihiaxkp+UeU5WoEfz4EN5toc+ICA0q0w==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
- /turbo-linux-arm64@2.0.9:
- resolution: {integrity: sha512-gRnjxXRne18B27SwxXMqL3fJu7jw/8kBrOBTBNRSmZZiG1Uu3nbnP7b4lgrA/bCku6C0Wligwqurvtpq6+nFHA==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ type-fest@2.19.0: {}
- /turbo-windows-64@2.0.9:
- resolution: {integrity: sha512-ZVo0apxUvaRq4Vm1qhsfqKKhtRgReYlBVf9MQvVU1O9AoyydEQvLDO1ryqpXDZWpcHoFxHAQc9msjAMtE5K2lA==}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ type-fest@5.10.0:
+ dependencies:
+ tagged-tag: 1.0.0
- /turbo-windows-arm64@2.0.9:
- resolution: {integrity: sha512-sGRz7c5Pey6y7y9OKi8ypbWNuIRPF9y8xcMqL56OZifSUSo+X2EOsOleR9MKxQXVaqHPGOUKWsE6y8hxBi9pag==}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ typescript@5.9.3: {}
- /turbo@2.0.9:
- resolution: {integrity: sha512-QaLaUL1CqblSKKPgLrFW3lZWkWG4pGBQNW+q1ScJB5v1D/nFWtsrD/yZljW/bdawg90ihi4/ftQJ3h6fz1FamA==}
- hasBin: true
+ typescript@7.0.2:
optionalDependencies:
- turbo-darwin-64: 2.0.9
- turbo-darwin-arm64: 2.0.9
- turbo-linux-64: 2.0.9
- turbo-linux-arm64: 2.0.9
- turbo-windows-64: 2.0.9
- turbo-windows-arm64: 2.0.9
- dev: true
+ '@typescript/typescript-aix-ppc64': 7.0.2
+ '@typescript/typescript-darwin-arm64': 7.0.2
+ '@typescript/typescript-darwin-x64': 7.0.2
+ '@typescript/typescript-freebsd-arm64': 7.0.2
+ '@typescript/typescript-freebsd-x64': 7.0.2
+ '@typescript/typescript-linux-arm': 7.0.2
+ '@typescript/typescript-linux-arm64': 7.0.2
+ '@typescript/typescript-linux-loong64': 7.0.2
+ '@typescript/typescript-linux-mips64el': 7.0.2
+ '@typescript/typescript-linux-ppc64': 7.0.2
+ '@typescript/typescript-linux-riscv64': 7.0.2
+ '@typescript/typescript-linux-s390x': 7.0.2
+ '@typescript/typescript-linux-x64': 7.0.2
+ '@typescript/typescript-netbsd-arm64': 7.0.2
+ '@typescript/typescript-netbsd-x64': 7.0.2
+ '@typescript/typescript-openbsd-arm64': 7.0.2
+ '@typescript/typescript-openbsd-x64': 7.0.2
+ '@typescript/typescript-sunos-x64': 7.0.2
+ '@typescript/typescript-win32-arm64': 7.0.2
+ '@typescript/typescript-win32-x64': 7.0.2
+
+ ufo@1.6.4: {}
+
+ undici-types@5.26.5: {}
+
+ undici-types@6.21.0: {}
+
+ undici-types@8.9.0: {}
+
+ undici@7.29.1: {}
+
+ unenv@2.0.0-rc.24:
+ dependencies:
+ pathe: 2.0.3
- /type-check@0.4.0:
- resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
- engines: {node: '>= 0.8.0'}
+ unicode-trie@2.0.0:
dependencies:
- prelude-ls: 1.2.1
- dev: true
+ pako: 0.2.9
+ tiny-inflate: 1.0.3
- /type-fest@0.21.3:
- resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
- engines: {node: '>=10'}
- dev: true
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
- /typescript@5.9.3:
- resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
- engines: {node: '>=14.17'}
- hasBin: true
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
- /ufo@1.6.4:
- resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
- dev: true
+ unist-util-position-from-estree@2.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
- /uglify-js@3.19.3:
- resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==}
- engines: {node: '>=0.8.0'}
- hasBin: true
- requiresBuild: true
- dev: true
- optional: true
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
- /undici-types@5.26.5:
- resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
- dev: true
+ unist-util-remove-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.2.0
- /undici-types@6.21.0:
- resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.2.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.1.0
+
+ unpic@4.2.2: {}
+
+ update-browserslist-db@1.3.4(browserslist@4.29.5):
+ dependencies:
+ browserslist: 4.29.5
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ update-check@1.5.4:
+ dependencies:
+ registry-auth-token: 3.3.2
+ registry-url: 3.1.0
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ use-callback-ref@1.3.3(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ use-callback-ref@1.3.3(@types/react@19.3.0)(react@19.3.1):
+ dependencies:
+ react: 19.3.1
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ use-sidecar@1.1.3(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 18.3.1
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 18.3.3
+
+ use-sidecar@1.1.3(@types/react@19.3.0)(react@19.3.1):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 19.3.1
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.3.0
+
+ use-sync-external-store@1.7.0(react@19.3.1):
+ dependencies:
+ react: 19.3.1
+
+ util-deprecate@1.0.2: {}
+
+ vary@1.1.2: {}
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ vinext@1.2.1(@types/node@22.18.6)(@vitejs/plugin-react@6.0.1(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)))(@vitejs/plugin-rsc@0.5.38(react-dom@19.3.1(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))))(react@19.3.1)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)))(next@14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))))(react@19.3.1)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)):
+ dependencies:
+ '@unpic/react': 1.0.2(next@14.2.35(@playwright/test@1.64.1)(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ '@vercel/og': 1.0.3(@types/node@22.18.6)
+ '@vinext/types': 1.0.2
+ '@vitejs/plugin-react': 6.0.1(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))
+ ipaddr.js: 2.5.0
+ magic-string: 0.30.21
+ react: 19.3.1
+ react-dom: 19.3.1(react@19.3.1)
+ vite: 8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)
+ vite-plugin-commonjs: 0.10.4
+ web-vitals: 4.2.4
+ optionalDependencies:
+ '@vitejs/plugin-rsc': 0.5.38(react-dom@19.3.1(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))))(react@19.3.1)(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1))
+ react-server-dom-webpack: 19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6)))
+ transitivePeerDependencies:
+ - '@types/node'
+ - next
+
+ vite-node@3.2.4(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1):
+ dependencies:
+ cac: 6.7.14
+ debug: 4.4.3(supports-color@10.2.2)
+ es-module-lexer: 1.7.0
+ pathe: 2.0.3
+ vite: 7.3.7(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
+ transitivePeerDependencies:
+ - '@types/node'
+ - jiti
+ - less
+ - lightningcss
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - yaml
+
+ vite-node@3.2.4(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1):
+ dependencies:
+ cac: 6.7.14
+ debug: 4.4.3(supports-color@10.2.2)
+ es-module-lexer: 1.7.0
+ pathe: 2.0.3
+ vite: 7.3.7(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
+ transitivePeerDependencies:
+ - '@types/node'
+ - jiti
+ - less
+ - lightningcss
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - yaml
- /universalify@2.0.1:
- resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
- engines: {node: '>= 10.0.0'}
- dev: true
+ vite-node@3.2.4(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1):
+ dependencies:
+ cac: 6.7.14
+ debug: 4.4.3(supports-color@10.2.2)
+ es-module-lexer: 1.7.0
+ pathe: 2.0.3
+ vite: 7.3.7(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
+ transitivePeerDependencies:
+ - '@types/node'
+ - jiti
+ - less
+ - lightningcss
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - yaml
- /update-browserslist-db@1.2.3(browserslist@4.28.5):
- resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
- hasBin: true
- peerDependencies:
- browserslist: '>= 4.21.0'
+ vite-plugin-commonjs@0.10.4:
dependencies:
- browserslist: 4.28.5
- escalade: 3.2.0
- picocolors: 1.1.1
- dev: true
+ acorn: 8.19.0
+ magic-string: 0.30.21
+ vite-plugin-dynamic-import: 1.6.0
- /update-check@1.5.4:
- resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==}
+ vite-plugin-dynamic-import@1.6.0:
dependencies:
- registry-auth-token: 3.3.2
- registry-url: 3.1.0
- dev: true
+ acorn: 8.19.0
+ es-module-lexer: 1.7.0
+ fast-glob: 3.3.3
+ magic-string: 0.30.21
- /upper-case-first@1.1.2:
- resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==}
+ vite@7.3.7(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1):
dependencies:
- upper-case: 1.1.3
- dev: true
-
- /upper-case@1.1.3:
- resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==}
- dev: true
+ esbuild: 0.28.2
+ fdir: 6.5.0(picomatch@4.0.7)
+ picomatch: 4.0.7
+ postcss: 8.5.32
+ rollup: 4.65.1
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 20.14.11
+ fsevents: 2.3.3
+ jiti: 2.7.0
+ lightningcss: 1.33.0
+ terser: 5.51.2
+ yaml: 2.9.1
- /uri-js@4.4.1:
- resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ vite@7.3.7(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1):
dependencies:
- punycode: 2.3.1
- dev: true
+ esbuild: 0.28.2
+ fdir: 6.5.0(picomatch@4.0.7)
+ picomatch: 4.0.7
+ postcss: 8.5.32
+ rollup: 4.65.1
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 22.18.6
+ fsevents: 2.3.3
+ jiti: 2.4.2
+ lightningcss: 1.33.0
+ terser: 5.51.2
+ yaml: 2.9.1
- /use-callback-ref@1.3.3(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ vite@7.3.7(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1):
dependencies:
- '@types/react': 18.3.3
- react: 18.3.1
- tslib: 2.8.1
- dev: false
+ esbuild: 0.28.2
+ fdir: 6.5.0(picomatch@4.0.7)
+ picomatch: 4.0.7
+ postcss: 8.5.32
+ rollup: 4.65.1
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 22.18.6
+ fsevents: 2.3.3
+ jiti: 2.7.0
+ lightningcss: 1.33.0
+ terser: 5.51.2
+ yaml: 2.9.1
- /use-sidecar@1.1.3(@types/react@18.3.3)(react@18.3.1):
- resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1):
dependencies:
- '@types/react': 18.3.3
- detect-node-es: 1.1.0
- react: 18.3.1
- tslib: 2.8.1
- dev: false
-
- /util-deprecate@1.0.2:
- resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
- dev: true
+ lightningcss: 1.33.0
+ picomatch: 4.0.7
+ postcss: 8.5.32
+ rolldown: 1.2.15
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 22.18.6
+ esbuild: 0.28.2
+ fsevents: 2.3.3
+ jiti: 2.4.2
+ terser: 5.51.2
+ yaml: 2.9.1
- /v8-compile-cache-lib@3.0.1:
- resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
- dev: true
+ vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1):
+ dependencies:
+ lightningcss: 1.33.0
+ picomatch: 4.0.7
+ postcss: 8.5.32
+ rolldown: 1.2.15
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 26.6.5
+ esbuild: 0.28.2
+ fsevents: 2.3.3
+ jiti: 2.7.0
+ terser: 5.51.2
+ yaml: 2.9.1
+ optional: true
- /validate-npm-package-name@5.0.1:
- resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
+ vitefu@1.1.3(vite@8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)):
+ optionalDependencies:
+ vite: 8.3.4(@types/node@22.18.6)(esbuild@0.28.2)(jiti@2.4.2)(terser@5.51.2)(yaml@2.9.1)
- /vite-node@3.2.4(@types/node@22.18.6)(jiti@2.4.2):
- resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
- engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
- hasBin: true
+ vitest@3.2.7(@types/debug@4.1.13)(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1):
dependencies:
- cac: 6.7.14
- debug: 4.4.3
- es-module-lexer: 1.7.0
+ '@types/chai': 5.2.3
+ '@vitest/expect': 3.2.7
+ '@vitest/mocker': 3.2.7(vite@7.3.7(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))
+ '@vitest/pretty-format': 3.2.7
+ '@vitest/runner': 3.2.7
+ '@vitest/snapshot': 3.2.7
+ '@vitest/spy': 3.2.7
+ '@vitest/utils': 3.2.7
+ chai: 5.3.3
+ debug: 4.4.3(supports-color@10.2.2)
+ expect-type: 1.4.0
+ magic-string: 0.30.21
pathe: 2.0.3
- vite: 7.3.6(@types/node@22.18.6)(jiti@2.4.2)
+ picomatch: 4.0.7
+ std-env: 3.10.0
+ tinybench: 2.9.0
+ tinyexec: 0.3.2
+ tinyglobby: 0.2.17
+ tinypool: 1.1.1
+ tinyrainbow: 2.0.0
+ vite: 7.3.7(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
+ vite-node: 3.2.4(@types/node@20.14.11)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/debug': 4.1.13
+ '@types/node': 20.14.11
transitivePeerDependencies:
- - '@types/node'
- jiti
- less
- lightningcss
+ - msw
- sass
- sass-embedded
- stylus
@@ -6562,109 +12282,76 @@ packages:
- tsx
- yaml
- /vite@7.3.6(@types/node@22.18.6)(jiti@2.4.2):
- resolution: {integrity: sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==}
- engines: {node: ^20.19.0 || >=22.12.0}
- hasBin: true
- peerDependencies:
- '@types/node': ^20.19.0 || >=22.12.0
- jiti: '>=1.21.0'
- less: ^4.0.0
- lightningcss: ^1.21.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
- jiti:
- optional: true
- less:
- optional: true
- lightningcss:
- optional: true
- sass:
- optional: true
- sass-embedded:
- optional: true
- stylus:
- optional: true
- sugarss:
- optional: true
- terser:
- optional: true
- tsx:
- optional: true
- yaml:
- optional: true
+ vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1):
dependencies:
- '@types/node': 22.18.6
- esbuild: 0.28.1
- fdir: 6.5.0(picomatch@4.0.5)
- jiti: 2.4.2
- picomatch: 4.0.5
- postcss: 8.5.16
- rollup: 4.62.2
+ '@types/chai': 5.2.3
+ '@vitest/expect': 3.2.7
+ '@vitest/mocker': 3.2.7(vite@7.3.7(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))
+ '@vitest/pretty-format': 3.2.7
+ '@vitest/runner': 3.2.7
+ '@vitest/snapshot': 3.2.7
+ '@vitest/spy': 3.2.7
+ '@vitest/utils': 3.2.7
+ chai: 5.3.3
+ debug: 4.4.3(supports-color@10.2.2)
+ expect-type: 1.4.0
+ magic-string: 0.30.21
+ pathe: 2.0.3
+ picomatch: 4.0.7
+ std-env: 3.10.0
+ tinybench: 2.9.0
+ tinyexec: 0.3.2
tinyglobby: 0.2.17
+ tinypool: 1.1.1
+ tinyrainbow: 2.0.0
+ vite: 7.3.7(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
+ vite-node: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
+ why-is-node-running: 2.3.0
optionalDependencies:
- fsevents: 2.3.3
+ '@types/debug': 4.1.13
+ '@types/node': 22.18.6
+ transitivePeerDependencies:
+ - jiti
+ - less
+ - lightningcss
+ - msw
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - yaml
- /vitest@3.2.4(@types/node@22.18.6)(jiti@2.4.2):
- resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==}
- engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
- hasBin: true
- peerDependencies:
- '@edge-runtime/vm': '*'
- '@types/debug': ^4.1.12
- '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
- '@vitest/browser': 3.2.4
- '@vitest/ui': 3.2.4
- happy-dom: '*'
- jsdom: '*'
- peerDependenciesMeta:
- '@edge-runtime/vm':
- optional: true
- '@types/debug':
- optional: true
- '@types/node':
- optional: true
- '@vitest/browser':
- optional: true
- '@vitest/ui':
- optional: true
- happy-dom:
- optional: true
- jsdom:
- optional: true
+ vitest@3.2.7(@types/debug@4.1.13)(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1):
dependencies:
'@types/chai': 5.2.3
- '@types/node': 22.18.6
- '@vitest/expect': 3.2.4
- '@vitest/mocker': 3.2.4(vite@7.3.6)
+ '@vitest/expect': 3.2.7
+ '@vitest/mocker': 3.2.7(vite@7.3.7(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))
'@vitest/pretty-format': 3.2.7
- '@vitest/runner': 3.2.4
- '@vitest/snapshot': 3.2.4
- '@vitest/spy': 3.2.4
- '@vitest/utils': 3.2.4
+ '@vitest/runner': 3.2.7
+ '@vitest/snapshot': 3.2.7
+ '@vitest/spy': 3.2.7
+ '@vitest/utils': 3.2.7
chai: 5.3.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@10.2.2)
expect-type: 1.4.0
magic-string: 0.30.21
pathe: 2.0.3
- picomatch: 4.0.5
+ picomatch: 4.0.7
std-env: 3.10.0
tinybench: 2.9.0
tinyexec: 0.3.2
tinyglobby: 0.2.17
tinypool: 1.1.1
tinyrainbow: 2.0.0
- vite: 7.3.6(@types/node@22.18.6)(jiti@2.4.2)
- vite-node: 3.2.4(@types/node@22.18.6)(jiti@2.4.2)
+ vite: 7.3.7(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1)
+ vite-node: 3.2.4(@types/node@22.18.6)(jiti@2.7.0)(lightningcss@1.33.0)(supports-color@10.2.2)(terser@5.51.2)(yaml@2.9.1)
why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/debug': 4.1.13
+ '@types/node': 22.18.6
transitivePeerDependencies:
- jiti
- less
@@ -6679,88 +12366,219 @@ packages:
- tsx
- yaml
- /wcwidth@1.0.1:
- resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
+ watchpack@2.6.3:
dependencies:
- defaults: 1.0.4
- dev: true
+ graceful-fs: 4.2.11
- /webrtc-adapter@9.0.1:
- resolution: {integrity: sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ==}
- engines: {node: '>=6.0.0', npm: '>=3.10.0'}
+ web-namespaces@2.0.1: {}
+
+ web-vitals@4.2.4: {}
+
+ webpack-sources@3.6.0: {}
+
+ webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6)):
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/json-schema': 7.0.15
+ '@webassemblyjs/ast': 1.14.1
+ '@webassemblyjs/wasm-edit': 1.14.1
+ '@webassemblyjs/wasm-parser': 1.14.1
+ browserslist: 4.29.5
+ chrome-trace-event: 1.0.4
+ enhanced-resolve: 5.26.0
+ es-module-lexer: 2.3.2
+ events: 3.3.0
+ graceful-fs: 4.2.11
+ mime-db: 1.54.0
+ minimizer-webpack-plugin: 5.13.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6))(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6)))
+ schema-utils: 4.8.1(webpack@5.112.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.4.39)(sharp@0.35.5(@types/node@22.18.6)))
+ tapable: 2.3.3
+ watchpack: 2.6.3
+ webpack-sources: 3.6.0
+ transitivePeerDependencies:
+ - '@minify-html/node'
+ - '@napi-rs/image'
+ - '@swc/core'
+ - '@swc/css'
+ - '@swc/html'
+ - clean-css
+ - cssnano
+ - csso
+ - esbuild
+ - html-minifier-terser
+ - imagemin
+ - lightningcss
+ - postcss
+ - sharp
+ - svgo
+ - uglify-js
+
+ webrtc-adapter@9.0.6:
dependencies:
sdp: 3.2.2
- dev: false
- /which@2.0.2:
- resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
- engines: {node: '>= 8'}
- hasBin: true
+ which@2.0.2:
dependencies:
isexe: 2.0.0
- dev: true
- /why-is-node-running@2.3.0:
- resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
- engines: {node: '>=8'}
- hasBin: true
+ why-is-node-running@2.3.0:
dependencies:
siginfo: 2.0.0
stackback: 0.0.2
- /word-wrap@1.2.5:
- resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
- engines: {node: '>=0.10.0'}
- dev: true
+ widest-line@4.0.1:
+ dependencies:
+ string-width: 5.1.2
- /wordwrap@1.0.0:
- resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
- dev: true
+ word-wrap@1.2.5: {}
- /wrap-ansi@6.2.0:
- resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
- engines: {node: '>=8'}
+ workerd@1.20261012.1:
+ optionalDependencies:
+ '@cloudflare/workerd-darwin-64': 1.20261012.1
+ '@cloudflare/workerd-darwin-arm64': 1.20261012.1
+ '@cloudflare/workerd-linux-64': 1.20261012.1
+ '@cloudflare/workerd-linux-arm64': 1.20261012.1
+ '@cloudflare/workerd-windows-64': 1.20261012.1
+
+ workerd@1.20261019.1:
+ optionalDependencies:
+ '@cloudflare/workerd-darwin-64': 1.20261019.1
+ '@cloudflare/workerd-darwin-arm64': 1.20261019.1
+ '@cloudflare/workerd-linux-64': 1.20261019.1
+ '@cloudflare/workerd-linux-arm64': 1.20261019.1
+ '@cloudflare/workerd-windows-64': 1.20261019.1
+
+ wrangler@4.151.3(@cloudflare/workers-types@5.20261019.1)(@types/node@22.18.6):
+ dependencies:
+ '@cloudflare/kv-asset-handler': 0.5.0
+ '@cloudflare/unenv-preset': 2.16.2(unenv@2.0.0-rc.24)(workerd@1.20261019.1)
+ blake3-wasm: 2.1.5
+ esbuild: 0.28.2
+ miniflare: 5.20261019.1-beta(@types/node@22.18.6)
+ path-to-regexp: 6.3.0
+ unenv: 2.0.0-rc.24
+ workerd: 1.20261019.1
+ optionalDependencies:
+ '@cloudflare/workers-types': 5.20261019.1
+ fsevents: 2.3.3
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
+
+ wrangler@4.151.3(@cloudflare/workers-types@5.20261019.1)(@types/node@26.6.5):
+ dependencies:
+ '@cloudflare/kv-asset-handler': 0.5.0
+ '@cloudflare/unenv-preset': 2.16.2(unenv@2.0.0-rc.24)(workerd@1.20261019.1)
+ blake3-wasm: 2.1.5
+ esbuild: 0.28.2
+ miniflare: 5.20261019.1-beta(@types/node@26.6.5)
+ path-to-regexp: 6.3.0
+ unenv: 2.0.0-rc.24
+ workerd: 1.20261019.1
+ optionalDependencies:
+ '@cloudflare/workers-types': 5.20261019.1
+ fsevents: 2.3.3
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
+
+ wrap-ansi@6.2.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
- dev: true
- /wrappy@1.0.2:
- resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
- dev: true
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.3
+ string-width: 5.1.2
+ strip-ansi: 7.2.0
- /xtend@4.0.2:
- resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
- engines: {node: '>=0.4'}
- dev: false
+ ws@8.21.0: {}
- /yaml@2.9.0:
- resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
- engines: {node: '>= 14.6'}
- hasBin: true
- dev: true
+ ws@8.22.0: {}
- /yn@3.1.1:
- resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
- engines: {node: '>=6'}
- dev: true
+ xtend@4.0.2: {}
- /yocto-queue@0.1.0:
- resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
- engines: {node: '>=10'}
- dev: true
+ y18n@5.0.8: {}
+
+ yaml@2.9.1: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
+
+ yocto-queue@0.1.0: {}
+
+ yoctocolors-cjs@2.1.3: {}
+
+ yoga-layout@3.2.1: {}
+
+ youch-core@0.3.3:
+ dependencies:
+ '@poppinss/exception': 1.2.3
+ error-stack-parser-es: 1.0.5
+
+ youch@4.1.0-beta.10:
+ dependencies:
+ '@poppinss/colors': 4.1.6
+ '@poppinss/dumper': 0.6.5
+ '@speed-highlight/core': 1.2.24
+ cookie: 1.1.1
+ youch-core: 0.3.3
+
+ yuku-analyzer@0.19.0:
+ dependencies:
+ '@yuku-toolchain/types': 0.19.0
+ yuku-ast: 0.19.0
+ yuku-core: 0.19.0
+
+ yuku-ast@0.19.0:
+ dependencies:
+ '@yuku-toolchain/types': 0.19.0
+
+ yuku-core@0.19.0:
+ dependencies:
+ '@yuku-toolchain/types': 0.19.0
+ optionalDependencies:
+ '@yuku-core/binding-android-arm64': 0.19.0
+ '@yuku-core/binding-darwin-arm64': 0.19.0
+ '@yuku-core/binding-darwin-x64': 0.19.0
+ '@yuku-core/binding-freebsd-x64': 0.19.0
+ '@yuku-core/binding-linux-arm-gnu': 0.19.0
+ '@yuku-core/binding-linux-arm-musl': 0.19.0
+ '@yuku-core/binding-linux-arm64-gnu': 0.19.0
+ '@yuku-core/binding-linux-arm64-musl': 0.19.0
+ '@yuku-core/binding-linux-x64-gnu': 0.19.0
+ '@yuku-core/binding-linux-x64-musl': 0.19.0
+ '@yuku-core/binding-win32-arm64': 0.19.0
+ '@yuku-core/binding-win32-x64': 0.19.0
+
+ zbsearch@4.0.1: {}
+
+ zod@3.25.76: {}
- /zod@3.25.67:
- resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==}
- dev: false
+ zod@4.6.7: {}
- /zod@4.6.5:
- resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==}
- dev: false
+ zwitch@2.0.4: {}
- /zxing-wasm@1.3.4:
- resolution: {integrity: sha512-9l0QymyATF19FmI92QHe7Dayb+BUN7P7zFAt5iDgTnUf0dFWokz6GVA/W9EepjW5q8s3e89fIE/7uxpX27yqEQ==}
+ zxing-wasm@3.1.6(@types/emscripten@1.41.6):
dependencies:
- '@types/emscripten': 1.41.5
- dev: false
+ '@types/emscripten': 1.41.6
+ type-fest: 5.10.0
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 3ff5faaaf..9e47213c8 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,3 +1,23 @@
packages:
- "apps/*"
+ - "templates/*"
- "packages/*"
+ - "e2e"
+allowBuilds:
+ esbuild: true
+ workerd: true
+overrides:
+ "@libsql/kysely-libsql>@libsql/client": "0.17.4"
+packageExtensions:
+ "next@14.2.35":
+ peerDependencies:
+ "@types/react": "*"
+ "qrcode.react@4.2.0":
+ peerDependencies:
+ "@types/react": "*"
+ "@yudiel/react-qr-scanner@2.6.0":
+ peerDependencies:
+ "@types/react": "*"
+ "sonner@1.7.4":
+ peerDependencies:
+ "@types/react": "*"
diff --git a/templates/nextjs-full/.env.example b/templates/nextjs-full/.env.example
new file mode 100644
index 000000000..7a8d94a30
--- /dev/null
+++ b/templates/nextjs-full/.env.example
@@ -0,0 +1,67 @@
+# Copy this file to .env. Keep real secrets in ignored environment files.
+# Local development works with an empty .env using these defaults.
+DATABASE_URL=file:.data/web.db
+NEXT_PUBLIC_APP_URL=http://localhost:3000
+
+# Required in production: set a unique secret with at least 32 characters.
+# Generate one with: node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"
+BETTER_AUTH_SECRET=
+
+# Required for full-template production: replace NEXT_PUBLIC_APP_URL with your
+# deployment URL, configure persistent database storage, and set the S3 and
+# Discord variables below. Production requires S3 even when developing locally
+# with filesystem uploads. Set either the Discord participant role ID or name.
+# HACKKIT_BLOB_ADAPTER=s3
+# HACKKIT_S3_BUCKET=
+# HACKKIT_S3_REGION=us-east-1
+# HACKKIT_S3_ACCESS_KEY_ID=
+# HACKKIT_S3_SECRET_ACCESS_KEY=
+# DISCORD_GUILD_ID=
+# DISCORD_BOT_API_URL=
+# DISCORD_INTERNAL_AUTH_KEY=
+# DISCORD_PARTICIPANT_ROLE_ID=
+# DISCORD_PARTICIPANT_ROLE_NAME=
+
+# Optional: auth URL defaults to NEXT_PUBLIC_APP_URL.
+# BETTER_AUTH_URL=http://localhost:3000
+# Optional: comma-separated additional trusted origins.
+# BETTER_AUTH_TRUSTED_ORIGINS=https://another-origin.example.com
+
+# Optional: database dialect is inferred from DATABASE_URL. Set libsql explicitly
+# for a local libSQL file; supported values are sqlite, libsql, postgresql, mysql.
+# HACKKIT_DATABASE_DIALECT=sqlite
+# Optional: required only for authenticated remote libSQL / Turso databases.
+# TURSO_AUTH_TOKEN=
+
+# Optional: local development storage defaults to these values.
+# HACKKIT_BLOB_ADAPTER=local
+# HACKKIT_LOCAL_BLOB_BASE_DIR=.data/uploads
+# Optional: custom endpoint for S3-compatible stores such as R2.
+# HACKKIT_S3_ENDPOINT=
+# Optional: verification links default to NEXT_PUBLIC_APP_URL.
+# DISCORD_VERIFICATION_BASE_URL=http://localhost:3000
+
+# Optional: OAuth providers. Enable a provider by setting both its ID and secret.
+# GITHUB_CLIENT_ID=
+# GITHUB_CLIENT_SECRET=
+# GOOGLE_CLIENT_ID=
+# GOOGLE_CLIENT_SECRET=
+
+# Optional: email defaults to none. For Resend, configure:
+# HACKKIT_EMAIL_PROVIDER=resend
+# RESEND_API_KEY=
+# HACKKIT_EMAIL_FROM="HackKit
"
+# HACKKIT_EMAIL_REPLY_TO=
+
+# Optional: use SMTP instead of Resend by configuring:
+# HACKKIT_EMAIL_PROVIDER=smtp
+# SMTP_HOST=
+# SMTP_PORT=587
+# SMTP_SECURE=false
+# SMTP_USERNAME=
+# SMTP_PASSWORD=
+# HACKKIT_EMAIL_FROM="HackKit "
+# HACKKIT_EMAIL_REPLY_TO=
+
+# Optional: migration history directory, relative to this template or absolute.
+# HACKKIT_MIGRATIONS_PATH=db/migrations/sqlite
diff --git a/templates/nextjs-full/README.md b/templates/nextjs-full/README.md
new file mode 100644
index 000000000..0c2f8edda
--- /dev/null
+++ b/templates/nextjs-full/README.md
@@ -0,0 +1,89 @@
+# HackKit reference web app
+
+Next.js app using MikroORM, Core-owned Better Auth, HackKit UI, Teams, Discord verification, and notifications.
+
+## Local setup
+
+Use Node.js 22.17 or newer and the repository-pinned pnpm 12.15.0. Run these commands from the repository root:
+
+1. Install dependencies with `pnpm install`.
+2. Build workspace packages with `pnpm exec turbo run build --filter=@hackkit/template-nextjs-full^...`.
+3. Sync plugin routes with `pnpm --filter @hackkit/template-nextjs-full sync`.
+4. Configure the database and plugins in `hackkit.config.ts` and the environment files. Use an empty development database.
+5. Generate your initial migration with `pnpm --filter @hackkit/template-nextjs-full db:generate --name initial`.
+6. Review the generated migration and snapshot, then apply with `pnpm --filter @hackkit/template-nextjs-full db:migrate`.
+7. Insert configured roles with `pnpm --filter @hackkit/template-nextjs-full db:seed`.
+8. Commit the migration and snapshot to your application repository, then start Next.js with `pnpm --filter @hackkit/template-nextjs-full dev`.
+
+The local `.env` starts empty and is ignored by Git. On a fresh checkout, copy [`.env.example`](.env.example) to `.env` to configure this template. The example lists production requirements and comments out optional integrations. An empty `.env` uses local development defaults. Never commit populated environment files.
+
+Development defaults use `http://localhost:3000`, SQLite at `templates/nextjs-full/.data/web.db`, and local blob storage. OAuth, email, and Discord providers are optional locally. The runtime does not migrate or seed on startup. Plugin sync only updates routes and `hackkit.lock`.
+
+After signup, bootstrap an owner explicitly by assigning `core.owner` to that user's `role_id` in `core_user`, selected by `id`. Better Auth's `user.id` is the canonical ID. The runtime does not infer ownership from email.
+
+`pnpm --filter @hackkit/template-nextjs-full db:reset` drops registered tables and migration history in the selected local SQLite database, then migrates and seeds. It refuses production and non-SQLite drivers. Never use it for data you need to retain.
+
+## Database selection
+
+| Driver | DATABASE_URL | HACKKIT_DATABASE_DIALECT |
+| ---------------------- | ------------------------------------------ | ---------------------------------- |
+| SQLite | `file:.data/web.db` | `sqlite` (default for local paths) |
+| local libSQL | `file:.data/web.db` | `libsql` (explicit) |
+| network libSQL / Turso | `libsql://...` or `https://...` | `libsql` (inferred) |
+| PostgreSQL | `postgresql://user:password@host/database` | `postgresql` (inferred) |
+| MySQL | `mysql://user:password@host/database` | `mysql` (inferred) |
+
+Set `TURSO_AUTH_TOKEN` when the libSQL endpoint requires authentication. Driver options live in [lib/database-config.ts](lib/database-config.ts).
+
+## Entity and migration workflow
+
+Core, Better Auth, installed plugins (including disabled plugins), and application entities form one native MikroORM registry. Add app-owned `defineEntity` definitions through `entities` in `hackkit.config.ts`; plugins expose an `entities` array. Runtime and app migration scripts use the same registry. Auth plugins requiring extra tables or fields must declare them before initialization; undeclared schema fails early.
+
+The template ships without migration history or schema snapshots. First setup generates a baseline for your configured database and entity registry. Commit it in your application repository. Later clones of that application apply its existing migrations; they do not generate another baseline. Existing databases must retain the migration history that created them.
+
+The selected dialect uses `db/migrations/postgresql`, `db/migrations/mysql`, or `db/migrations/sqlite`. libSQL uses the SQLite dialect directory. `HACKKIT_MIGRATIONS_PATH` optionally overrides the directory, relative to this application or absolute. Maintain the history for the dialect your application uses. If your application supports several dialects, maintain and test each of those histories. After changing entities:
+
+1. Select a disposable development database for the dialect using the variables above.
+2. Run `pnpm --filter @hackkit/template-nextjs-full db:generate --name describe-change`.
+3. Review the generated TypeScript migration and snapshot. Generate for other dialects only if your application supports them.
+4. Apply with `pnpm --filter @hackkit/template-nextjs-full db:migrate` and validate against fresh databases.
+5. Commit each supported dialect's reviewed migration and snapshot.
+
+Set `enabled: false` on a registered plugin to disable behavior while keeping its schema and data. Removing it can generate table drops. Review data retention before applying them. `db:seed` only inserts missing configured role IDs; it does not update existing roles or assign them to users.
+
+The database commands now use application-owned utility scripts, independently of the CLI. Use `db:status`, `db:check`, staged `db:migrate --to`, `db:rollback`, and `db:generate --blank` for upgrades. See [the migration guide](../../docs/guides/database-migrations.md) for exact commands, data transformations, MySQL recovery, and plugin retention.
+
+## Authentication and request scope
+
+[lib/auth-options.ts](lib/auth-options.ts) supplies secrets, origins, and OAuth providers. Core owns Better Auth construction, native entities, and the pinned community adapter. Better Auth identity and HackKit profile fields share the canonical `core_user` row.
+
+[lib/runtime.ts](lib/runtime.ts) initializes shared connections and registers a function that creates request-scoped domain APIs. Next owns cookies, headers, guards, and redirects. Browser mutations use the package-owned HTTP handler and return JSON DTOs. Browser code uses `@hackkit/core/client`; it does not import the ORM.
+
+## Production configuration
+
+Set explicit `DATABASE_URL`, `NEXT_PUBLIC_APP_URL`, `BETTER_AUTH_URL`, and `BETTER_AUTH_SECRET` (at least 32 characters). Configure `BETTER_AUTH_TRUSTED_ORIGINS` as a comma-separated list when needed. The app's production checks also require:
+
+- `HACKKIT_BLOB_ADAPTER=s3`, bucket, region, access key, and secret key; set `HACKKIT_S3_ENDPOINT` for compatible stores.
+- `DISCORD_GUILD_ID`, `DISCORD_BOT_API_URL`, `DISCORD_INTERNAL_AUTH_KEY`, and `DISCORD_PARTICIPANT_ROLE_ID` (or role name).
+- Optional email through `HACKKIT_EMAIL_PROVIDER=resend` plus `RESEND_API_KEY`, or `smtp` plus SMTP settings.
+
+See [env.ts](env.ts) for exact variable names. Database storage must persist across application restarts. Apply migrations and seed as explicit release steps. Builds must have valid configuration but do not apply schema changes.
+
+## Validation
+
+Integration tests now live in [E2E](../../e2e/README.md). From the repository root, run `corepack pnpm test:e2e:db` for database workflows and the configured driver matrix, `corepack pnpm test:e2e:http` for production HTTP checks, or `corepack pnpm test:e2e:browser` for browser journeys. `corepack pnpm test:e2e` runs all suites. Every run uses disposable storage. CI requires PostgreSQL, MySQL, and HTTP libSQL in addition to SQLite and local libSQL.
+
+Package behavior tests remain beside their packages and run through `corepack pnpm test`. The template's `verify` command syncs plugin files, typechecks, and builds after dependencies and production configuration are ready.
+
+## Distribution
+
+This is a runnable workspace example. Packages remain private and use workspace dependencies. [Standalone distribution and CLI init](../../docs/plans/template-distribution.md) are deferred. The [minimal template](../nextjs-minimal/README.md) provides Core registration and basic administration with SQLite and local uploads.
+
+## Architecture
+
+- [Next integration guide](../../docs/guides/next-integration.md)
+- [MikroORM and Core auth decision](../../docs/adr/0013-mikroorm-and-core-auth.md)
+- [hackkit.config.ts](hackkit.config.ts): plugins, database, auth, settings, and seed roles.
+- [Database migration guide](../../docs/guides/database-migrations.md): initial generation and application-owned history.
+
+The UI provider receives a typed better-call path client created at module scope in `app/providers.tsx`. Plugin components bind their endpoint types using the provider's HTTP settings. `hackkit plugin sync` installs page reexports and updates `hackkit.lock`; it generates no client metadata. The single `/api/hackkit/[...path]` route forwards POST to the host handler. No app-level action wrappers or action maps are needed.
diff --git a/templates/nextjs-full/app/admin/check-in/page.tsx b/templates/nextjs-full/app/admin/check-in/page.tsx
new file mode 100644
index 000000000..871705bf6
--- /dev/null
+++ b/templates/nextjs-full/app/admin/check-in/page.tsx
@@ -0,0 +1,30 @@
+import { CheckInScanner } from "@hackkit/ui";
+import { CorePermission } from "@hackkit/core";
+import Link from "next/link";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function CheckInPage() {
+ const pageGuards = await getPageGuards();
+ await pageGuards.requirePermission(CorePermission.UsersCheckIn);
+
+ return (
+
+
+
+
+ Hackathon check-in
+
+
+ Dashboard
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/events/[id]/edit/page.tsx b/templates/nextjs-full/app/admin/events/[id]/edit/page.tsx
new file mode 100644
index 000000000..92443ebe8
--- /dev/null
+++ b/templates/nextjs-full/app/admin/events/[id]/edit/page.tsx
@@ -0,0 +1,49 @@
+import { notFound } from "next/navigation";
+import { EventAdminForm, toDateTimeLocalValue } from "@hackkit/ui";
+import { CorePermission } from "@hackkit/core";
+import { getHackkit, getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function EditEventPage({
+ params,
+}: {
+ params: { id: string };
+}) {
+ const pageGuards = await getPageGuards();
+ const principal = await pageGuards.requirePermission(
+ CorePermission.EventsUpdate,
+ );
+ const hackkit = await getHackkit();
+ const event = await hackkit.events.getEvent({
+ eventId: params.id,
+ actorAuthId: principal.user.id,
+ });
+
+ if (!event) notFound();
+
+ return (
+
+
+
+ Edit event
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/events/new/page.tsx b/templates/nextjs-full/app/admin/events/new/page.tsx
new file mode 100644
index 000000000..04b7ff5c2
--- /dev/null
+++ b/templates/nextjs-full/app/admin/events/new/page.tsx
@@ -0,0 +1,29 @@
+import { EventAdminForm, toDateTimeLocalValue } from "@hackkit/ui";
+import { CorePermission } from "@hackkit/core";
+import { getHackkit, getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function NewEventPage() {
+ const pageGuards = await getPageGuards();
+ await pageGuards.requirePermission(CorePermission.EventsCreate);
+ const hackkit = await getHackkit();
+
+ return (
+
+
+
New event
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/events/page.tsx b/templates/nextjs-full/app/admin/events/page.tsx
new file mode 100644
index 000000000..d21b075bc
--- /dev/null
+++ b/templates/nextjs-full/app/admin/events/page.tsx
@@ -0,0 +1,44 @@
+import Link from "next/link";
+import { EventAdminList } from "@hackkit/ui";
+import { CorePermission } from "@hackkit/core";
+import { getHackkit, getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminEventsPage() {
+ const pageGuards = await getPageGuards();
+ const principal = await pageGuards.requirePermission(
+ CorePermission.EventsView,
+ );
+ const hackkit = await getHackkit();
+ const events = await hackkit.events.listEvents({
+ actorAuthId: principal.user.id,
+ });
+
+ return (
+
+
+
+
+
+ Events
+
+
+ Manage the hackathon schedule.
+
+
+
+ New event
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/layout.tsx b/templates/nextjs-full/app/admin/layout.tsx
new file mode 100644
index 000000000..cb5b2a9df
--- /dev/null
+++ b/templates/nextjs-full/app/admin/layout.tsx
@@ -0,0 +1,50 @@
+import type * as React from "react";
+import { CorePermission } from "@hackkit/core";
+import Link from "next/link";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireNotBanned();
+ await guards.requirePermission(CorePermission.Admin);
+
+ const navItems = [
+ { href: "/admin", label: "Overview" },
+ { href: "/admin/users", label: "Users" },
+ { href: "/admin/roles", label: "Roles" },
+ { href: "/admin/events", label: "Events" },
+ { href: "/admin/check-in", label: "Check-in" },
+ { href: "/admin/settings", label: "Settings" },
+ ];
+
+ return (
+
+
+
+
Admin
+
+ Hackathon operations
+
+
+
+ {navItems.map((item) => (
+
+ {item.label}
+
+ ))}
+
+
+
{children}
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/page.tsx b/templates/nextjs-full/app/admin/page.tsx
new file mode 100644
index 000000000..c439891b1
--- /dev/null
+++ b/templates/nextjs-full/app/admin/page.tsx
@@ -0,0 +1,24 @@
+import { AdminOverviewPanel } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminOverviewPage() {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const overview = await runtime.hackkit.admin.getOverview({ actorAuthId });
+
+ return (
+
+
+
+ Admin Overview
+
+
+ Registration, approval, suspension, and check-in summary.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/roles/page.tsx b/templates/nextjs-full/app/admin/roles/page.tsx
new file mode 100644
index 000000000..77ef4780f
--- /dev/null
+++ b/templates/nextjs-full/app/admin/roles/page.tsx
@@ -0,0 +1,26 @@
+import { CorePermission } from "@hackkit/core";
+import { AdminRolesPanel } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminRolesPage() {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const roles = await runtime.hackkit.roles.listRoles({ actorAuthId });
+
+ return (
+
+
+
Roles
+
+ Manage admin roles and permissions.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/scanner/[eventId]/page.tsx b/templates/nextjs-full/app/admin/scanner/[eventId]/page.tsx
new file mode 100644
index 000000000..288d61d68
--- /dev/null
+++ b/templates/nextjs-full/app/admin/scanner/[eventId]/page.tsx
@@ -0,0 +1,44 @@
+import Link from "next/link";
+import { notFound } from "next/navigation";
+import { EventScanner } from "@hackkit/ui";
+import { CorePermission } from "@hackkit/core";
+import { getHackkit, getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function EventScannerPage({
+ params,
+}: {
+ params: { eventId: string };
+}) {
+ const pageGuards = await getPageGuards();
+ const principal = await pageGuards.requirePermission(
+ CorePermission.EventsScan,
+ );
+ const hackkit = await getHackkit();
+ const event = await hackkit.events.getEvent({
+ eventId: params.eventId,
+ actorAuthId: principal.user.id,
+ });
+
+ if (!event) notFound();
+
+ return (
+
+
+
+
+ Event scanner
+
+
+ Back to events
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/settings/page.tsx b/templates/nextjs-full/app/admin/settings/page.tsx
new file mode 100644
index 000000000..5f3d4935f
--- /dev/null
+++ b/templates/nextjs-full/app/admin/settings/page.tsx
@@ -0,0 +1,28 @@
+import { CorePermission } from "@hackkit/core";
+import { HackathonSettingsForm } from "@hackkit/ui";
+import { getPageGuards, getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminSettingsPage() {
+ const guards = await getPageGuards();
+ const principal = await guards.requirePermission(
+ CorePermission.SettingsManage,
+ );
+ const { hackkit } = await getRuntime();
+ const settings = await hackkit.settings.list({
+ actorAuthId: principal.user.id,
+ });
+
+ return (
+
+
+
Hackathon Settings
+
+ Manage live hackathon policy settings.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/users/[authId]/page.tsx b/templates/nextjs-full/app/admin/users/[authId]/page.tsx
new file mode 100644
index 000000000..03d390f9e
--- /dev/null
+++ b/templates/nextjs-full/app/admin/users/[authId]/page.tsx
@@ -0,0 +1,36 @@
+import { notFound } from "next/navigation";
+import { AdminUserDetail } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminUserDetailPage({
+ params,
+}: {
+ params: { authId: string };
+}) {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const targetAuthId = decodeURIComponent(params.authId);
+ const [record, roles] = await Promise.all([
+ runtime.hackkit.admin.getUser({ actorAuthId, targetAuthId }),
+ runtime.hackkit.roles.listRoles({ actorAuthId }),
+ ]);
+
+ if (!record) notFound();
+
+ return (
+
+
+
+ User Detail
+
+
+ Account, registration, approval, suspension, and role
+ details.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/admin/users/page.tsx b/templates/nextjs-full/app/admin/users/page.tsx
new file mode 100644
index 000000000..da56a8791
--- /dev/null
+++ b/templates/nextjs-full/app/admin/users/page.tsx
@@ -0,0 +1,23 @@
+import { AdminUsersTable } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminUsersPage() {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const users = await runtime.hackkit.admin.listUsers({ actorAuthId });
+
+ return (
+
+
+
Users
+
+ Review registrations, approvals, roles, suspensions, and
+ check-ins.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/api/admin/export/route.ts b/templates/nextjs-full/app/api/admin/export/route.ts
new file mode 100644
index 000000000..3ffa24d73
--- /dev/null
+++ b/templates/nextjs-full/app/api/admin/export/route.ts
@@ -0,0 +1,57 @@
+import { HackKitError } from "@hackkit/core";
+import { NextResponse } from "next/server";
+import { getAuthSession } from "@/lib/auth";
+import { getRuntime } from "@/lib/runtime";
+
+function escapeCsv(value: unknown): string {
+ if (value === null || value === undefined) return "";
+ const stringValue =
+ value instanceof Date
+ ? value.toISOString()
+ : typeof value === "string"
+ ? value
+ : String(value);
+ if (/[",\n\r]/.test(stringValue)) {
+ return `"${stringValue.replaceAll('"', '""')}"`;
+ }
+ return stringValue;
+}
+
+function toCsv(rows: Record[]): string {
+ if (rows.length === 0) return "";
+ const headers = Object.keys(rows[0] ?? {});
+ const body = rows.map((row) =>
+ headers.map((header) => escapeCsv(row[header])).join(","),
+ );
+ return [headers.join(","), ...body].join("\r\n");
+}
+
+export async function GET() {
+ const session = await getAuthSession();
+ if (!session) {
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ }
+
+ const runtime = await getRuntime();
+ const actor = await runtime.getCurrentUser();
+ const rows = await runtime.hackkit.admin
+ .exportUsers({
+ actorAuthId: actor.id,
+ })
+ .catch((error: unknown) => {
+ if (error instanceof HackKitError && error.code === "FORBIDDEN")
+ return null;
+ throw error;
+ });
+ if (!rows)
+ return NextResponse.json({ error: "Forbidden" }, { status: 403 });
+ const csv = toCsv(rows);
+ const timestamp = new Date().toISOString().replaceAll(":", "-");
+
+ return new NextResponse(csv, {
+ headers: {
+ "Content-Type": "text/csv; charset=utf-8",
+ "Content-Disposition": `attachment; filename="hackkit-users-${timestamp}.csv"`,
+ },
+ });
+}
diff --git a/templates/nextjs-full/app/api/auth/[...all]/route.ts b/templates/nextjs-full/app/api/auth/[...all]/route.ts
new file mode 100644
index 000000000..ac24ae8cf
--- /dev/null
+++ b/templates/nextjs-full/app/api/auth/[...all]/route.ts
@@ -0,0 +1,9 @@
+import { getAuth } from "@/lib/auth";
+
+export async function GET(request: Request) {
+ return (await getAuth()).handler(request);
+}
+
+export async function POST(request: Request) {
+ return (await getAuth()).handler(request);
+}
diff --git a/apps/web/app/api/files/register/route.ts b/templates/nextjs-full/app/api/files/register/route.ts
similarity index 100%
rename from apps/web/app/api/files/register/route.ts
rename to templates/nextjs-full/app/api/files/register/route.ts
diff --git a/apps/web/app/api/files/upload/route.ts b/templates/nextjs-full/app/api/files/upload/route.ts
similarity index 100%
rename from apps/web/app/api/files/upload/route.ts
rename to templates/nextjs-full/app/api/files/upload/route.ts
diff --git a/apps/web/app/api/files/view/route.ts b/templates/nextjs-full/app/api/files/view/route.ts
similarity index 100%
rename from apps/web/app/api/files/view/route.ts
rename to templates/nextjs-full/app/api/files/view/route.ts
diff --git a/templates/nextjs-full/app/api/hackkit/[...path]/route.ts b/templates/nextjs-full/app/api/hackkit/[...path]/route.ts
new file mode 100644
index 000000000..7584eab06
--- /dev/null
+++ b/templates/nextjs-full/app/api/hackkit/[...path]/route.ts
@@ -0,0 +1,4 @@
+import { handleHackkitRequest } from "@/lib/runtime";
+export const runtime = "nodejs";
+export const dynamic = "force-dynamic";
+export const POST = handleHackkitRequest;
diff --git a/templates/nextjs-full/app/app-bar.tsx b/templates/nextjs-full/app/app-bar.tsx
new file mode 100644
index 000000000..f5afbe76c
--- /dev/null
+++ b/templates/nextjs-full/app/app-bar.tsx
@@ -0,0 +1,77 @@
+import Link from "next/link";
+import { CorePermission } from "@hackkit/core";
+import { getAuthSession } from "@/lib/auth";
+import { getCurrentUser, getRuntime } from "@/lib/runtime";
+import { publicSiteConfig } from "@/lib/public-site-config";
+import { getEnabledSiteLinks } from "@/lib/plugin-navigation";
+import { ProfileMenu } from "./profile-menu";
+
+async function getIsAdmin(authId: string) {
+ const runtime = await getRuntime();
+ return runtime.hackkit.accessControl.hasPermission(
+ authId,
+ CorePermission.Admin,
+ );
+}
+
+export async function AppBar() {
+ const session = await getAuthSession();
+ const currentUser = session ? await getCurrentUser() : null;
+ const isAdmin = currentUser ? await getIsAdmin(currentUser.id) : false;
+
+ return (
+
+ );
+}
diff --git a/templates/nextjs-full/app/contact/page.tsx b/templates/nextjs-full/app/contact/page.tsx
new file mode 100644
index 000000000..dbc3d35d1
--- /dev/null
+++ b/templates/nextjs-full/app/contact/page.tsx
@@ -0,0 +1 @@
+export { default } from "../help/page";
diff --git a/templates/nextjs-full/app/dashboard/layout.tsx b/templates/nextjs-full/app/dashboard/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-full/app/dashboard/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-full/app/dashboard/page.tsx b/templates/nextjs-full/app/dashboard/page.tsx
new file mode 100644
index 000000000..973ef0d12
--- /dev/null
+++ b/templates/nextjs-full/app/dashboard/page.tsx
@@ -0,0 +1,71 @@
+import {
+ CompetitorOnboardingProgress,
+ ParticipantDashboard,
+} from "@hackkit/ui";
+import { publicSiteConfig } from "@/lib/public-site-config";
+import { getEnabledSiteLinks } from "@/lib/plugin-navigation";
+import { getHackkit } from "@/lib/runtime";
+import {
+ getCompetitorOnboardingState,
+ getRequireApproval,
+} from "@/lib/onboarding";
+
+export const dynamic = "force-dynamic";
+
+export default async function DashboardPage() {
+ const {
+ steps,
+ nextHref,
+ user: currentUser,
+ userData,
+ hacker,
+ } = await getCompetitorOnboardingState("/dashboard");
+ const [hackkit, requireApproval] = await Promise.all([
+ getHackkit(),
+ getRequireApproval(),
+ ]);
+ const role = currentUser.roleId
+ ? await hackkit.roles.getRole(currentUser.roleId)
+ : null;
+ const participantName =
+ currentUser.name || currentUser.hackTag || "participant";
+
+ return (
+
+ ),
+ }
+ : undefined
+ }
+ />
+ );
+}
diff --git a/apps/web/app/discord/page.tsx b/templates/nextjs-full/app/discord/page.tsx
similarity index 100%
rename from apps/web/app/discord/page.tsx
rename to templates/nextjs-full/app/discord/page.tsx
diff --git a/apps/web/app/discord/verify/page.tsx b/templates/nextjs-full/app/discord/verify/page.tsx
similarity index 100%
rename from apps/web/app/discord/verify/page.tsx
rename to templates/nextjs-full/app/discord/verify/page.tsx
diff --git a/templates/nextjs-full/app/globals.css b/templates/nextjs-full/app/globals.css
new file mode 100644
index 000000000..e0ea2ecce
--- /dev/null
+++ b/templates/nextjs-full/app/globals.css
@@ -0,0 +1,58 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
+ --primary: 221.2 83.2% 53.3%;
+ --primary-foreground: 210 40% 98%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 221.2 83.2% 53.3%;
+ --radius: 0.5rem;
+ }
+
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
+ --primary: 217.2 91.2% 59.8%;
+ --primary-foreground: 222.2 47.4% 11.2%;
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 224.3 76.3% 48%;
+ }
+
+ * {
+ @apply border-border;
+ }
+
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/templates/nextjs-full/app/help/page.tsx b/templates/nextjs-full/app/help/page.tsx
new file mode 100644
index 000000000..4876f845d
--- /dev/null
+++ b/templates/nextjs-full/app/help/page.tsx
@@ -0,0 +1,13 @@
+import { PublicHelpPage } from "@hackkit/ui";
+import { publicSiteConfig } from "@/lib/public-site-config";
+
+export default function HelpPage() {
+ return (
+
+ );
+}
diff --git a/templates/nextjs-full/app/i/approval/layout.tsx b/templates/nextjs-full/app/i/approval/layout.tsx
new file mode 100644
index 000000000..6e9c3af0d
--- /dev/null
+++ b/templates/nextjs-full/app/i/approval/layout.tsx
@@ -0,0 +1,14 @@
+import type * as React from "react";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function ApprovalLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireApprovalPendingAccess();
+ return children;
+}
diff --git a/templates/nextjs-full/app/i/approval/page.tsx b/templates/nextjs-full/app/i/approval/page.tsx
new file mode 100644
index 000000000..8a4c460c6
--- /dev/null
+++ b/templates/nextjs-full/app/i/approval/page.tsx
@@ -0,0 +1,27 @@
+import Link from "next/link";
+
+export default function ApprovalPendingPage() {
+ return (
+
+
+
+ Registration received
+
+
+ Your account is awaiting approval.
+
+
+ Organizers are reviewing your registration. Once approved,
+ you can access participant features like your Event Pass,
+ teams, and RSVP.
+
+
+ Back to dashboard
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/invites/layout.tsx b/templates/nextjs-full/app/invites/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-full/app/invites/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-full/app/invites/page.tsx b/templates/nextjs-full/app/invites/page.tsx
new file mode 100644
index 000000000..0e48306e9
--- /dev/null
+++ b/templates/nextjs-full/app/invites/page.tsx
@@ -0,0 +1,4 @@
+// @hackkit-generated — do not edit
+// Owner: teams@0.0.0
+export * from "@hackkit/plugin-teams/app/invites/page";
+export { default } from "@hackkit/plugin-teams/app/invites/page";
diff --git a/apps/web/app/layout.tsx b/templates/nextjs-full/app/layout.tsx
similarity index 100%
rename from apps/web/app/layout.tsx
rename to templates/nextjs-full/app/layout.tsx
diff --git a/templates/nextjs-full/app/onboarding/hacker/hacker-form-defaults.ts b/templates/nextjs-full/app/onboarding/hacker/hacker-form-defaults.ts
new file mode 100644
index 000000000..edd46c9ef
--- /dev/null
+++ b/templates/nextjs-full/app/onboarding/hacker/hacker-form-defaults.ts
@@ -0,0 +1,18 @@
+import type { Hacker } from "@hackkit/core";
+
+export function toHackerFormDefaults(hacker: Hacker | null) {
+ if (!hacker) return undefined;
+ return {
+ university: hacker.university,
+ major: hacker.major,
+ schoolId: hacker.schoolId ?? undefined,
+ levelOfStudy: hacker.levelOfStudy,
+ hackathonsAttended: hacker.hackathonsAttended,
+ softwareExperience: hacker.softwareExperience,
+ heardFrom: hacker.heardFrom ?? undefined,
+ githubUrl: hacker.githubUrl ?? undefined,
+ linkedInUrl: hacker.linkedInUrl ?? undefined,
+ personalWebsiteUrl: hacker.personalWebsiteUrl ?? undefined,
+ resumeUrl: hacker.resumeUrl ?? undefined,
+ };
+}
diff --git a/templates/nextjs-full/app/onboarding/hacker/hacker-registration-client.tsx b/templates/nextjs-full/app/onboarding/hacker/hacker-registration-client.tsx
new file mode 100644
index 000000000..1cb6ab6fb
--- /dev/null
+++ b/templates/nextjs-full/app/onboarding/hacker/hacker-registration-client.tsx
@@ -0,0 +1,45 @@
+"use client";
+
+import { HackerRegistrationForm } from "@hackkit/ui";
+import type { User } from "@hackkit/core";
+import type { HackerRegistrationOptions } from "@hackkit/config";
+import { uploadResumeFile } from "@/lib/upload-resume";
+
+export function HackerRegistrationClient({
+ currentUser,
+ defaultValues,
+ registrationOptions,
+ successRedirectTo = "/dashboard",
+}: {
+ currentUser: User;
+ defaultValues?: Partial<{
+ university: string;
+ major: string;
+ schoolId?: string;
+ levelOfStudy: string;
+ hackathonsAttended: number;
+ softwareExperience: string;
+ heardFrom?: string;
+ githubUrl?: string;
+ linkedInUrl?: string;
+ personalWebsiteUrl?: string;
+ resumeUrl?: string;
+ }>;
+ registrationOptions?: HackerRegistrationOptions;
+ successRedirectTo?: string;
+}) {
+ return (
+
+ );
+}
diff --git a/templates/nextjs-full/app/onboarding/hacker/page.tsx b/templates/nextjs-full/app/onboarding/hacker/page.tsx
new file mode 100644
index 000000000..c05b57516
--- /dev/null
+++ b/templates/nextjs-full/app/onboarding/hacker/page.tsx
@@ -0,0 +1,40 @@
+import { redirect } from "next/navigation";
+import { getCurrentUser, getHackkit, getPageGuards } from "@/lib/runtime";
+import { appConfig } from "@/lib/app-config";
+import { getOnboardingSteps } from "@/lib/onboarding";
+import { OnboardingShell } from "../onboarding-shell";
+import { HackerRegistrationClient } from "./hacker-registration-client";
+import { toHackerFormDefaults } from "./hacker-form-defaults";
+
+export const dynamic = "force-dynamic";
+
+export default async function HackerOnboardingPage() {
+ await (await getPageGuards()).requireHackerRegistrationOpenForNewHacker();
+ const currentUser = await getCurrentUser();
+ if (!currentUser.hackTag) {
+ redirect("/onboarding/hacktag");
+ }
+
+ const hackkit = await getHackkit();
+ const userData = await hackkit.userData.getUserData(currentUser.id);
+ if (!userData) {
+ redirect("/onboarding/user-data");
+ }
+
+ const hacker = await hackkit.hackers.getHacker(currentUser.id);
+ const steps = await getOnboardingSteps("/onboarding/hacker");
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/onboarding/hacktag/page.tsx b/templates/nextjs-full/app/onboarding/hacktag/page.tsx
new file mode 100644
index 000000000..7c98a15d4
--- /dev/null
+++ b/templates/nextjs-full/app/onboarding/hacktag/page.tsx
@@ -0,0 +1,30 @@
+import { HackTagForm } from "@hackkit/ui";
+import { getCurrentUser } from "@/lib/runtime";
+import { getOnboardingSteps } from "@/lib/onboarding";
+import { OnboardingShell } from "../onboarding-shell";
+
+export const dynamic = "force-dynamic";
+
+export default async function HackTagOnboardingPage() {
+ const currentUser = await getCurrentUser();
+ const steps = await getOnboardingSteps("/onboarding/hacktag");
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/onboarding/layout.tsx b/templates/nextjs-full/app/onboarding/layout.tsx
new file mode 100644
index 000000000..b2898f3bb
--- /dev/null
+++ b/templates/nextjs-full/app/onboarding/layout.tsx
@@ -0,0 +1,14 @@
+import type * as React from "react";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function OnboardingLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireOnboardingAccess();
+ return children;
+}
diff --git a/templates/nextjs-full/app/onboarding/onboarding-shell.tsx b/templates/nextjs-full/app/onboarding/onboarding-shell.tsx
new file mode 100644
index 000000000..5196fa8aa
--- /dev/null
+++ b/templates/nextjs-full/app/onboarding/onboarding-shell.tsx
@@ -0,0 +1,35 @@
+import {
+ CompetitorOnboardingProgress,
+ type CompetitorOnboardingStep,
+} from "@hackkit/ui";
+import type * as React from "react";
+
+export function OnboardingShell({
+ steps,
+ title,
+ description,
+ children,
+}: {
+ steps: CompetitorOnboardingStep[];
+ title: string;
+ description: string;
+ children: React.ReactNode;
+}) {
+ return (
+
+
+
+
+ Competitor onboarding
+
+
+ {title}
+
+
{description}
+
+
+ {children}
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/onboarding/user-data/page.tsx b/templates/nextjs-full/app/onboarding/user-data/page.tsx
new file mode 100644
index 000000000..394f5136b
--- /dev/null
+++ b/templates/nextjs-full/app/onboarding/user-data/page.tsx
@@ -0,0 +1,38 @@
+import { UserDataForm, toUserDataFormDefaultValues } from "@hackkit/ui";
+import { redirect } from "next/navigation";
+import { getCurrentUser, getHackkit } from "@/lib/runtime";
+import { getOnboardingSteps } from "@/lib/onboarding";
+import { OnboardingShell } from "../onboarding-shell";
+
+export const dynamic = "force-dynamic";
+
+export default async function UserDataOnboardingPage() {
+ const currentUser = await getCurrentUser();
+ if (!currentUser.hackTag) {
+ redirect("/onboarding/hacktag");
+ }
+
+ const hackkit = await getHackkit();
+ const existingUserData = await hackkit.userData.getUserData(currentUser.id);
+ const steps = await getOnboardingSteps("/onboarding/user-data");
+
+ return (
+
+
+
+ );
+}
diff --git a/apps/web/app/page.tsx b/templates/nextjs-full/app/page.tsx
similarity index 100%
rename from apps/web/app/page.tsx
rename to templates/nextjs-full/app/page.tsx
diff --git a/templates/nextjs-full/app/participant-layout.tsx b/templates/nextjs-full/app/participant-layout.tsx
new file mode 100644
index 000000000..09ccadc7a
--- /dev/null
+++ b/templates/nextjs-full/app/participant-layout.tsx
@@ -0,0 +1,14 @@
+import type * as React from "react";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function ParticipantLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireParticipantAccess();
+ return children;
+}
diff --git a/templates/nextjs-full/app/pass/event-pass-shell.tsx b/templates/nextjs-full/app/pass/event-pass-shell.tsx
new file mode 100644
index 000000000..64f3d7168
--- /dev/null
+++ b/templates/nextjs-full/app/pass/event-pass-shell.tsx
@@ -0,0 +1,42 @@
+"use client";
+
+import { createEventPassQrPayload } from "@hackkit/ui";
+import type { User } from "@hackkit/core";
+import { EventPass } from "@hackkit/ui";
+import * as React from "react";
+
+export function EventPassShell({
+ user,
+ eventPassQrTtlMs,
+}: {
+ user: User;
+ eventPassQrTtlMs: number;
+}) {
+ const [issuedAt, setIssuedAt] = React.useState(() => new Date());
+ const qrPayload = React.useMemo(
+ () => createEventPassQrPayload(user.id, issuedAt),
+ [user.id, issuedAt],
+ );
+
+ React.useEffect(() => {
+ const expiresAt = issuedAt.getTime() + eventPassQrTtlMs;
+ const msUntilExpiry = expiresAt - Date.now();
+ const refresh = () => setIssuedAt(new Date());
+
+ if (msUntilExpiry <= 0) {
+ refresh();
+ return;
+ }
+
+ const timeoutId = window.setTimeout(refresh, msUntilExpiry);
+ return () => window.clearTimeout(timeoutId);
+ }, [issuedAt, eventPassQrTtlMs]);
+
+ return (
+ setIssuedAt(new Date())}
+ />
+ );
+}
diff --git a/templates/nextjs-full/app/pass/layout.tsx b/templates/nextjs-full/app/pass/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-full/app/pass/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-full/app/pass/page.tsx b/templates/nextjs-full/app/pass/page.tsx
new file mode 100644
index 000000000..6a616afad
--- /dev/null
+++ b/templates/nextjs-full/app/pass/page.tsx
@@ -0,0 +1,22 @@
+import { CoreSetting } from "@hackkit/core";
+import { getCurrentUser, getRuntime } from "@/lib/runtime";
+import { EventPassShell } from "./event-pass-shell";
+
+export const dynamic = "force-dynamic";
+
+export default async function PassPage() {
+ const user = await getCurrentUser();
+ const runtime = await getRuntime();
+ const eventPassQrTtlMs = await runtime.getSettingValue(
+ CoreSetting.EventPassQrTtlMs,
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/profile-menu.tsx b/templates/nextjs-full/app/profile-menu.tsx
new file mode 100644
index 000000000..25c01ee34
--- /dev/null
+++ b/templates/nextjs-full/app/profile-menu.tsx
@@ -0,0 +1,116 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import { useRouter } from "next/navigation";
+import { authClient } from "@/lib/auth-client";
+
+export function ProfileMenu({
+ name,
+ email,
+ image,
+ isAdmin = false,
+}: {
+ name: string;
+ email: string;
+ image?: string | null;
+ isAdmin?: boolean;
+}) {
+ const router = useRouter();
+ const [isOpen, setIsOpen] = useState(false);
+ const [isSigningOut, setIsSigningOut] = useState(false);
+ const initials =
+ name
+ .split(/\s+/)
+ .filter(Boolean)
+ .slice(0, 2)
+ .map((part) => part[0]?.toUpperCase())
+ .join("") || "U";
+
+ async function signOut() {
+ setIsSigningOut(true);
+ await authClient.signOut();
+ router.push("/sign-in");
+ router.refresh();
+ }
+
+ return (
+
+
setIsOpen((value) => !value)}
+ className="flex items-center gap-2 rounded-full border bg-background px-2 py-1.5 text-sm font-medium shadow-sm transition hover:bg-muted"
+ aria-label="Open account menu"
+ aria-haspopup="menu"
+ aria-expanded={isOpen}
+ >
+ {image ? (
+ // eslint-disable-next-line @next/next/no-img-element
+
+ ) : (
+
+ {initials}
+
+ )}
+
+ {name}
+
+
+
+ {isOpen ? (
+
+
+
+ setIsOpen(false)}
+ className="block rounded-md px-3 py-2 text-sm hover:bg-muted"
+ >
+ Settings
+
+ setIsOpen(false)}
+ className="block rounded-md px-3 py-2 text-sm hover:bg-muted"
+ >
+ Registration
+
+ {isAdmin ? (
+ setIsOpen(false)}
+ className="block rounded-md px-3 py-2 text-sm text-accent-foreground hover:bg-muted"
+ >
+ Admin
+
+ ) : null}
+
+ {isSigningOut ? "Signing out..." : "Log out"}
+
+
+
+ ) : null}
+
+ );
+}
diff --git a/templates/nextjs-full/app/providers.tsx b/templates/nextjs-full/app/providers.tsx
new file mode 100644
index 000000000..35d6da071
--- /dev/null
+++ b/templates/nextjs-full/app/providers.tsx
@@ -0,0 +1,12 @@
+"use client";
+import { HackKitUIProvider } from "@hackkit/ui";
+import { createHackkitClient } from "@hackkit/core/http/client";
+import type * as React from "react";
+
+const hackkitClient = createHackkitClient();
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+ {children}
+ );
+}
diff --git a/templates/nextjs-full/app/register/page.tsx b/templates/nextjs-full/app/register/page.tsx
new file mode 100644
index 000000000..ad808fca8
--- /dev/null
+++ b/templates/nextjs-full/app/register/page.tsx
@@ -0,0 +1,5 @@
+import { redirect } from "next/navigation";
+
+export default function RegisterRedirectPage() {
+ redirect("/onboarding/user-data");
+}
diff --git a/templates/nextjs-full/app/registration-closed/page.tsx b/templates/nextjs-full/app/registration-closed/page.tsx
new file mode 100644
index 000000000..c11572fac
--- /dev/null
+++ b/templates/nextjs-full/app/registration-closed/page.tsx
@@ -0,0 +1,26 @@
+import Link from "next/link";
+
+export default function RegistrationClosedPage() {
+ return (
+
+
+
+ Registration closed
+
+
+ New hacker registrations are closed.
+
+
+ If you have already started registration, sign in to check
+ your current status or contact the organizing team.
+
+
+ Go to dashboard
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/rsvp/layout.tsx b/templates/nextjs-full/app/rsvp/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-full/app/rsvp/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-full/app/rsvp/page.tsx b/templates/nextjs-full/app/rsvp/page.tsx
new file mode 100644
index 000000000..055b84fd1
--- /dev/null
+++ b/templates/nextjs-full/app/rsvp/page.tsx
@@ -0,0 +1,19 @@
+import { RsvpConfirmation } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function RsvpPage() {
+ const runtime = await getRuntime();
+ const authId = await runtime.getAuthId();
+ const [rsvp, summary] = await Promise.all([
+ runtime.hackkit.rsvp.getRsvp(authId),
+ runtime.hackkit.rsvp.getSummary(),
+ ]);
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/schedule/[eventId]/page.tsx b/templates/nextjs-full/app/schedule/[eventId]/page.tsx
new file mode 100644
index 000000000..1716bf638
--- /dev/null
+++ b/templates/nextjs-full/app/schedule/[eventId]/page.tsx
@@ -0,0 +1,37 @@
+import { notFound } from "next/navigation";
+import { ScheduleDetail } from "@hackkit/ui";
+import { getHackkit } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+type ScheduleEventPageProps = {
+ params: {
+ eventId: string;
+ };
+};
+
+export default async function ScheduleEventPage({
+ params,
+}: ScheduleEventPageProps) {
+ const hackkit = await getHackkit();
+ const event = await hackkit.events.getEvent({ eventId: params.eventId });
+
+ if (!event) notFound();
+
+ const eventType = hackkit.events.options.find(
+ (option) => option.value === event.type,
+ );
+
+ return (
+
+ );
+}
diff --git a/templates/nextjs-full/app/schedule/page.tsx b/templates/nextjs-full/app/schedule/page.tsx
new file mode 100644
index 000000000..7a1304fae
--- /dev/null
+++ b/templates/nextjs-full/app/schedule/page.tsx
@@ -0,0 +1,29 @@
+import { ScheduleList } from "@hackkit/ui";
+import { getHackkit } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function SchedulePage() {
+ const hackkit = await getHackkit();
+ const events = await hackkit.events.listEvents();
+
+ return (
+
+
+
+
+ Schedule
+
+
+ Public agenda for the hackathon.
+
+
+
`/schedule/${event.id}`}
+ />
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/settings/layout.tsx b/templates/nextjs-full/app/settings/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-full/app/settings/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-full/app/settings/page.tsx b/templates/nextjs-full/app/settings/page.tsx
new file mode 100644
index 000000000..dd5cccc10
--- /dev/null
+++ b/templates/nextjs-full/app/settings/page.tsx
@@ -0,0 +1,53 @@
+import Link from "next/link";
+import { getCurrentUser, getHackkit } from "@/lib/runtime";
+import { ProfileSettingsClient } from "./profile-settings-client";
+
+export const dynamic = "force-dynamic";
+
+export default async function SettingsPage() {
+ const currentUser = await getCurrentUser();
+ const hackkit = await getHackkit();
+
+ return (
+
+
+
Settings
+
+ Manage your account profile and public HackKit profile.
+
+
+
+
+
+ {hackkit.isPluginEnabled("discord") ? (
+
+ Discord
+
+ Link Discord and sync participant, organiser role, and
+ Group roles for the event server.
+
+
+ Manage Discord
+
+
+ ) : null}
+
+
+ Registration
+
+ You can update your demographic, logistics, school,
+ experience, and resume information after registration.
+
+
+ Edit registration
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/settings/profile-settings-client.tsx b/templates/nextjs-full/app/settings/profile-settings-client.tsx
new file mode 100644
index 000000000..f75f12c06
--- /dev/null
+++ b/templates/nextjs-full/app/settings/profile-settings-client.tsx
@@ -0,0 +1,14 @@
+"use client";
+
+import { UserProfileSettingsForm } from "@hackkit/ui";
+import type { User } from "@hackkit/core";
+import { uploadProfilePhotoFile } from "@/lib/upload-profile-photo";
+
+export function ProfileSettingsClient({ currentUser }: { currentUser: User }) {
+ return (
+
+ );
+}
diff --git a/templates/nextjs-full/app/settings/registration/page.tsx b/templates/nextjs-full/app/settings/registration/page.tsx
new file mode 100644
index 000000000..f72c69355
--- /dev/null
+++ b/templates/nextjs-full/app/settings/registration/page.tsx
@@ -0,0 +1,54 @@
+import Link from "next/link";
+import { UserDataForm, toUserDataFormDefaultValues } from "@hackkit/ui";
+import { getCurrentUser, getHackkit } from "@/lib/runtime";
+import { appConfig } from "@/lib/app-config";
+import { toHackerFormDefaults } from "@/app/onboarding/hacker/hacker-form-defaults";
+import { HackerRegistrationClient } from "@/app/onboarding/hacker/hacker-registration-client";
+
+export const dynamic = "force-dynamic";
+
+export default async function RegistrationSettingsPage() {
+ const currentUser = await getCurrentUser();
+ const hackkit = await getHackkit();
+ const [userData, hacker] = await Promise.all([
+ hackkit.userData.getUserData(currentUser.id),
+ hackkit.hackers.getHacker(currentUser.id),
+ ]);
+
+ return (
+
+
+
+ Back to settings
+
+
+ Registration Settings
+
+
+ Update registration details that organizers use for
+ logistics and participant review.
+
+
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/sign-in/auth-form.tsx b/templates/nextjs-full/app/sign-in/auth-form.tsx
new file mode 100644
index 000000000..aad59d2f0
--- /dev/null
+++ b/templates/nextjs-full/app/sign-in/auth-form.tsx
@@ -0,0 +1,100 @@
+"use client";
+
+import { useState, type FormEvent } from "react";
+import Link from "next/link";
+import { useRouter } from "next/navigation";
+import { authClient } from "@/lib/auth-client";
+
+type AuthMode = "sign-in" | "sign-up";
+
+export function AuthForm({ mode }: { mode: AuthMode }) {
+ const router = useRouter();
+ const [error, setError] = useState(null);
+ const [isPending, setIsPending] = useState(false);
+ const isSignUp = mode === "sign-up";
+
+ async function onSubmit(event: FormEvent) {
+ event.preventDefault();
+ setError(null);
+ setIsPending(true);
+
+ const form = new FormData(event.currentTarget);
+ const email = String(form.get("email") ?? "");
+ const password = String(form.get("password") ?? "");
+ const name = String(form.get("name") ?? email);
+
+ const result = isSignUp
+ ? await authClient.signUp.email({ email, password, name })
+ : await authClient.signIn.email({ email, password });
+
+ setIsPending(false);
+
+ if (result.error) {
+ setError(result.error.message ?? "Authentication failed.");
+ return;
+ }
+
+ router.push(isSignUp ? "/register" : "/");
+ router.refresh();
+ }
+
+ return (
+
+ {isSignUp ? (
+
+ Name
+
+
+ ) : null}
+
+ Email
+
+
+
+ Password
+
+
+ {error ? {error}
: null}
+
+ {isPending
+ ? "Working..."
+ : isSignUp
+ ? "Create account"
+ : "Sign in"}
+
+
+ {isSignUp
+ ? "Have an account? Sign in"
+ : "Need an account? Sign up"}
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/sign-in/page.tsx b/templates/nextjs-full/app/sign-in/page.tsx
new file mode 100644
index 000000000..03f759629
--- /dev/null
+++ b/templates/nextjs-full/app/sign-in/page.tsx
@@ -0,0 +1,24 @@
+import { redirect } from "next/navigation";
+import { getAuthSession } from "@/lib/auth";
+import { AuthForm } from "./auth-form";
+
+export const dynamic = "force-dynamic";
+
+export default async function SignInPage() {
+ const session = await getAuthSession();
+ if (session) redirect("/");
+
+ return (
+
+
+
+
HackKit
+
+ Sign in
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/sign-up/page.tsx b/templates/nextjs-full/app/sign-up/page.tsx
new file mode 100644
index 000000000..d43a22eeb
--- /dev/null
+++ b/templates/nextjs-full/app/sign-up/page.tsx
@@ -0,0 +1,27 @@
+import { redirect } from "next/navigation";
+import { getAuthSession } from "@/lib/auth";
+import { AuthForm } from "../sign-in/auth-form";
+
+export const dynamic = "force-dynamic";
+
+export default async function SignUpPage() {
+ const session = await getAuthSession();
+ if (session) redirect("/onboarding/hacktag");
+
+ return (
+
+
+
+
HackKit
+
+ Sign up
+
+
+ Create an account, then complete registration.
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/suspended/page.tsx b/templates/nextjs-full/app/suspended/page.tsx
new file mode 100644
index 000000000..694e510f8
--- /dev/null
+++ b/templates/nextjs-full/app/suspended/page.tsx
@@ -0,0 +1,18 @@
+export default function SuspendedPage() {
+ return (
+
+
+
+ Account suspended
+
+
+ Your access to this HackKit app is suspended.
+
+
+ If you think this is a mistake, contact the organizing team
+ for help.
+
+
+
+ );
+}
diff --git a/templates/nextjs-full/app/teams/layout.tsx b/templates/nextjs-full/app/teams/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-full/app/teams/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-full/app/teams/page.tsx b/templates/nextjs-full/app/teams/page.tsx
new file mode 100644
index 000000000..6aad72fe7
--- /dev/null
+++ b/templates/nextjs-full/app/teams/page.tsx
@@ -0,0 +1,4 @@
+// @hackkit-generated — do not edit
+// Owner: teams@0.0.0
+export * from "@hackkit/plugin-teams/app/teams/page";
+export { default } from "@hackkit/plugin-teams/app/teams/page";
diff --git a/templates/nextjs-full/app/user/[tag]/page.tsx b/templates/nextjs-full/app/user/[tag]/page.tsx
new file mode 100644
index 000000000..7777572a7
--- /dev/null
+++ b/templates/nextjs-full/app/user/[tag]/page.tsx
@@ -0,0 +1,23 @@
+import { notFound } from "next/navigation";
+import { PublicProfileCard } from "@hackkit/ui";
+import { getHackkit } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function PublicUserProfilePage({
+ params,
+}: {
+ params: { tag: string };
+}) {
+ const tag = decodeURIComponent(params.tag);
+ const profile = await (
+ await getHackkit()
+ ).users.getPublicProfileByHackTag(tag);
+ if (!profile) notFound();
+
+ return (
+
+
+
+ );
+}
diff --git a/apps/web/env.ts b/templates/nextjs-full/env.ts
similarity index 98%
rename from apps/web/env.ts
rename to templates/nextjs-full/env.ts
index d31148b4d..f72160359 100644
--- a/apps/web/env.ts
+++ b/templates/nextjs-full/env.ts
@@ -11,6 +11,7 @@ type TestWebEnv = {
betterAuthTrustedOrigins: string[];
databaseUrl: string;
databaseDialect: DatabaseDialect;
+ migrationsPath?: string;
tursoAuthToken?: string;
blobAdapter: BlobAdapter;
localBlobBaseDir: string;
@@ -185,6 +186,7 @@ export function resolveTestWebEnv(): TestWebEnv {
betterAuthTrustedOrigins: readList("BETTER_AUTH_TRUSTED_ORIGINS"),
databaseUrl,
databaseDialect: resolveDatabaseDialect(databaseUrl),
+ migrationsPath: read("HACKKIT_MIGRATIONS_PATH"),
tursoAuthToken: read("TURSO_AUTH_TOKEN"),
blobAdapter,
localBlobBaseDir:
diff --git a/apps/web/hackkit.config.ts b/templates/nextjs-full/hackkit.config.ts
similarity index 100%
rename from apps/web/hackkit.config.ts
rename to templates/nextjs-full/hackkit.config.ts
diff --git a/apps/web/hackkit.lock b/templates/nextjs-full/hackkit.lock
similarity index 100%
rename from apps/web/hackkit.lock
rename to templates/nextjs-full/hackkit.lock
diff --git a/apps/web/lib/app-config.ts b/templates/nextjs-full/lib/app-config.ts
similarity index 100%
rename from apps/web/lib/app-config.ts
rename to templates/nextjs-full/lib/app-config.ts
diff --git a/templates/nextjs-full/lib/auth-client.ts b/templates/nextjs-full/lib/auth-client.ts
new file mode 100644
index 000000000..2f75fd48b
--- /dev/null
+++ b/templates/nextjs-full/lib/auth-client.ts
@@ -0,0 +1,5 @@
+"use client";
+
+import { createAuthClient } from "better-auth/react";
+
+export const authClient = createAuthClient();
diff --git a/apps/web/lib/auth-options.ts b/templates/nextjs-full/lib/auth-options.ts
similarity index 100%
rename from apps/web/lib/auth-options.ts
rename to templates/nextjs-full/lib/auth-options.ts
diff --git a/templates/nextjs-full/lib/auth.ts b/templates/nextjs-full/lib/auth.ts
new file mode 100644
index 000000000..66b0565a1
--- /dev/null
+++ b/templates/nextjs-full/lib/auth.ts
@@ -0,0 +1,11 @@
+import "server-only";
+import { headers } from "next/headers";
+import { getCoreRuntime } from "./runtime";
+
+export async function getAuth() {
+ return (await getCoreRuntime()).auth;
+}
+
+export async function getAuthSession() {
+ return (await getAuth()).api.getSession({ headers: await headers() });
+}
diff --git a/apps/web/lib/blob.ts b/templates/nextjs-full/lib/blob.ts
similarity index 100%
rename from apps/web/lib/blob.ts
rename to templates/nextjs-full/lib/blob.ts
diff --git a/apps/web/lib/database-config.ts b/templates/nextjs-full/lib/database-config.ts
similarity index 94%
rename from apps/web/lib/database-config.ts
rename to templates/nextjs-full/lib/database-config.ts
index ddecb4c38..07802116f 100644
--- a/apps/web/lib/database-config.ts
+++ b/templates/nextjs-full/lib/database-config.ts
@@ -11,8 +11,8 @@ const appDirectory = process.cwd();
const migrations = {
path: resolve(
appDirectory,
- "db/migrations",
- env.databaseDialect === "libsql" ? "sqlite" : env.databaseDialect,
+ env.migrationsPath ??
+ `db/migrations/${env.databaseDialect === "libsql" ? "sqlite" : env.databaseDialect}`,
),
emit: "ts" as const,
snapshot: true,
diff --git a/templates/nextjs-full/lib/hackkit-ui-routes.ts b/templates/nextjs-full/lib/hackkit-ui-routes.ts
new file mode 100644
index 000000000..afca1c43b
--- /dev/null
+++ b/templates/nextjs-full/lib/hackkit-ui-routes.ts
@@ -0,0 +1,7 @@
+import { DEFAULT_HACKKIT_UI_ROUTES, type HackKitUIRoutes } from "@hackkit/ui";
+
+/**
+ * Single place for HackKit UI route policy in this HackKit Web App.
+ * Passed to HackKitUIProvider and buildCompetitorOnboardingSteps.
+ */
+export const hackKitUIRoutes: HackKitUIRoutes = DEFAULT_HACKKIT_UI_ROUTES;
diff --git a/templates/nextjs-full/lib/logger.ts b/templates/nextjs-full/lib/logger.ts
new file mode 100644
index 000000000..18b9b02c4
--- /dev/null
+++ b/templates/nextjs-full/lib/logger.ts
@@ -0,0 +1,11 @@
+import { createLogger, type HackKitLogger } from "@hackkit/core";
+import { appConfig } from "./app-config";
+
+let logger: HackKitLogger | null = null;
+
+export function getAppLogger(): HackKitLogger {
+ if (!logger) {
+ logger = createLogger(appConfig.logger);
+ }
+ return logger;
+}
diff --git a/templates/nextjs-full/lib/onboarding.ts b/templates/nextjs-full/lib/onboarding.ts
new file mode 100644
index 000000000..d876e88ff
--- /dev/null
+++ b/templates/nextjs-full/lib/onboarding.ts
@@ -0,0 +1,54 @@
+import "server-only";
+
+import {
+ buildCompetitorOnboardingSteps,
+ getNextOnboardingStepHref,
+ type CompetitorOnboardingStep,
+} from "@hackkit/ui";
+import { CoreSetting } from "@hackkit/core";
+import { hackKitUIRoutes } from "./hackkit-ui-routes";
+import { getCurrentUser, getHackkit, getRuntime } from "./runtime";
+
+async function loadCompetitorOnboardingInput(currentPath: string) {
+ const user = await getCurrentUser();
+ const hackkit = await getHackkit();
+ const runtime = await getRuntime();
+ const [userData, hacker, requireApproval] = await Promise.all([
+ hackkit.userData.getUserData(user.id),
+ hackkit.hackers.getHacker(user.id),
+ runtime.getSettingValue(CoreSetting.RequireApproval),
+ ]);
+ return {
+ user,
+ userData,
+ hacker,
+ requireApproval: Boolean(requireApproval),
+ currentPath,
+ routes: hackKitUIRoutes,
+ };
+}
+
+export async function getOnboardingSteps(
+ currentPath: string,
+): Promise {
+ const input = await loadCompetitorOnboardingInput(currentPath);
+ return buildCompetitorOnboardingSteps(input);
+}
+
+export async function getCompetitorOnboardingState(currentPath: string) {
+ const input = await loadCompetitorOnboardingInput(currentPath);
+ const steps = buildCompetitorOnboardingSteps(input);
+ return {
+ steps,
+ nextHref: getNextOnboardingStepHref(steps),
+ user: input.user,
+ userData: input.userData,
+ hacker: input.hacker,
+ };
+}
+
+export async function getRequireApproval(): Promise {
+ return Boolean(
+ await (await getRuntime()).getSettingValue(CoreSetting.RequireApproval),
+ );
+}
diff --git a/templates/nextjs-full/lib/plugin-navigation.ts b/templates/nextjs-full/lib/plugin-navigation.ts
new file mode 100644
index 000000000..4d32b273e
--- /dev/null
+++ b/templates/nextjs-full/lib/plugin-navigation.ts
@@ -0,0 +1,20 @@
+import "server-only";
+import type { PublicShellLink } from "@hackkit/ui";
+import { appConfig } from "./app-config";
+
+// Route ownership belongs to the application, including custom navigation.
+const pluginRoutes: Record = {
+ "/teams": "teams",
+ "/invites": "teams",
+ "/discord": "discord",
+};
+
+export function getEnabledSiteLinks(links: readonly PublicShellLink[]) {
+ return links.filter((link) => {
+ const pluginId = pluginRoutes[link.href];
+ if (!pluginId) return true;
+ return appConfig.plugins.some(
+ (plugin) => plugin.id === pluginId && plugin.enabled !== false,
+ );
+ });
+}
diff --git a/apps/web/lib/public-site-config.ts b/templates/nextjs-full/lib/public-site-config.ts
similarity index 100%
rename from apps/web/lib/public-site-config.ts
rename to templates/nextjs-full/lib/public-site-config.ts
diff --git a/apps/web/lib/runtime.ts b/templates/nextjs-full/lib/runtime.ts
similarity index 100%
rename from apps/web/lib/runtime.ts
rename to templates/nextjs-full/lib/runtime.ts
diff --git a/templates/nextjs-full/lib/upload-profile-photo.ts b/templates/nextjs-full/lib/upload-profile-photo.ts
new file mode 100644
index 000000000..2c6b14b87
--- /dev/null
+++ b/templates/nextjs-full/lib/upload-profile-photo.ts
@@ -0,0 +1,34 @@
+export async function uploadProfilePhotoFile(file: File): Promise {
+ const registerResponse = await fetch("/api/files/register", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ location: "profile-photos",
+ fileName: file.name,
+ }),
+ });
+
+ if (!registerResponse.ok) {
+ throw new Error("Could not prepare profile photo upload.");
+ }
+
+ const { uploadUrl, storedFileReference } =
+ (await registerResponse.json()) as {
+ uploadUrl: string;
+ storedFileReference: string;
+ };
+
+ const uploadResponse = await fetch(uploadUrl, {
+ method: "PUT",
+ body: file,
+ headers: {
+ "Content-Type": file.type || "application/octet-stream",
+ },
+ });
+
+ if (!uploadResponse.ok) {
+ throw new Error("Could not upload profile photo.");
+ }
+
+ return storedFileReference;
+}
diff --git a/templates/nextjs-full/lib/upload-resume.ts b/templates/nextjs-full/lib/upload-resume.ts
new file mode 100644
index 000000000..d8767b1ec
--- /dev/null
+++ b/templates/nextjs-full/lib/upload-resume.ts
@@ -0,0 +1,59 @@
+async function responseError(
+ response: Response,
+ fallback: string,
+): Promise {
+ try {
+ const body = (await response.json()) as { error?: string };
+ if (body.error) return new Error(body.error);
+ } catch {
+ // Use the actionable fallback when the server did not return JSON.
+ }
+ return new Error(fallback);
+}
+
+export async function uploadResumeFile(file: File): Promise {
+ if (file.type && file.type !== "application/pdf") {
+ throw new Error(
+ "Choose a PDF resume before submitting your registration.",
+ );
+ }
+
+ const registerResponse = await fetch("/api/files/register", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ location: "resumes",
+ fileName: file.name,
+ }),
+ });
+
+ if (!registerResponse.ok) {
+ throw await responseError(
+ registerResponse,
+ "Could not prepare your resume upload. Please sign in again and retry.",
+ );
+ }
+
+ const { uploadUrl, storedFileReference } =
+ (await registerResponse.json()) as {
+ uploadUrl: string;
+ storedFileReference: string;
+ };
+
+ const uploadResponse = await fetch(uploadUrl, {
+ method: "PUT",
+ body: file,
+ headers: {
+ "Content-Type": file.type || "application/pdf",
+ },
+ });
+
+ if (!uploadResponse.ok) {
+ throw await responseError(
+ uploadResponse,
+ "Could not upload your resume. Check your connection and retry.",
+ );
+ }
+
+ return storedFileReference;
+}
diff --git a/templates/nextjs-full/middleware.ts b/templates/nextjs-full/middleware.ts
new file mode 100644
index 000000000..c5e2110a8
--- /dev/null
+++ b/templates/nextjs-full/middleware.ts
@@ -0,0 +1,72 @@
+import { NextResponse, type NextRequest } from "next/server";
+
+const AUTH_ROUTE_PATHS = new Set(["/sign-in", "/sign-up"]);
+const PUBLIC_ROUTE_PATHS = new Set([
+ "/",
+ "/favicon.ico",
+ "/registration-closed",
+ "/suspended",
+]);
+const PUBLIC_ROUTE_PREFIXES = ["/api/", "/i/approval", "/schedule", "/user/"];
+const PROTECTED_ROUTE_PREFIXES = [
+ "/admin",
+ "/dashboard",
+ "/invites",
+ "/onboarding",
+ "/pass",
+ "/register",
+ "/rsvp",
+ "/settings",
+ "/teams",
+];
+
+function hasAuthSessionCookie(request: NextRequest): boolean {
+ return request.cookies
+ .getAll()
+ .some((cookie) => cookie.name.includes("better-auth.session_token"));
+}
+
+function isPublicRoute(pathname: string): boolean {
+ return (
+ PUBLIC_ROUTE_PATHS.has(pathname) ||
+ AUTH_ROUTE_PATHS.has(pathname) ||
+ PUBLIC_ROUTE_PREFIXES.some((prefix) => pathname.startsWith(prefix))
+ );
+}
+
+function isProtectedRoute(pathname: string): boolean {
+ return PROTECTED_ROUTE_PREFIXES.some(
+ (prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`),
+ );
+}
+
+export function middleware(request: NextRequest) {
+ const { pathname } = request.nextUrl;
+ const hasSession = hasAuthSessionCookie(request);
+
+ if (pathname.startsWith("/@")) {
+ const tag = pathname.slice(2).split("/")[0];
+ if (tag) {
+ return NextResponse.rewrite(new URL(`/user/${tag}`, request.url));
+ }
+ }
+
+ if (AUTH_ROUTE_PATHS.has(pathname) && hasSession) {
+ return NextResponse.redirect(new URL("/", request.url));
+ }
+
+ if (!hasSession && isProtectedRoute(pathname) && !isPublicRoute(pathname)) {
+ const signInUrl = new URL("/sign-in", request.url);
+ signInUrl.searchParams.set(
+ "next",
+ `${pathname}${request.nextUrl.search}`,
+ );
+ return NextResponse.redirect(signInUrl);
+ }
+
+ return NextResponse.next();
+}
+
+export const config = {
+ matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\..*).*)"],
+};
diff --git a/apps/web/next-env.d.ts b/templates/nextjs-full/next-env.d.ts
similarity index 100%
rename from apps/web/next-env.d.ts
rename to templates/nextjs-full/next-env.d.ts
diff --git a/apps/web/next.config.mjs b/templates/nextjs-full/next.config.mjs
similarity index 100%
rename from apps/web/next.config.mjs
rename to templates/nextjs-full/next.config.mjs
diff --git a/apps/web/package.json b/templates/nextjs-full/package.json
similarity index 77%
rename from apps/web/package.json
rename to templates/nextjs-full/package.json
index aa3dd8bbc..f8f1ce0cf 100644
--- a/apps/web/package.json
+++ b/templates/nextjs-full/package.json
@@ -1,5 +1,5 @@
{
- "name": "web",
+ "name": "@hackkit/template-nextjs-full",
"version": "0.0.0",
"private": true,
"type": "module",
@@ -9,17 +9,12 @@
"db:migrate": "node scripts/db.mjs migrate",
"db:seed": "node scripts/db.mjs seed",
"db:reset": "node scripts/db.mjs reset",
- "test": "vitest run db/__tests__/database-workflow.test.ts db/__tests__/migration-workflow.test.ts",
- "test:db-workflow": "bash scripts/test-db-workflow.sh",
"sync": "pnpm plugin:sync",
- "predev": "turbo run build --filter=web^...",
"dev": "next dev -p 3000",
"build": "next build",
"verify": "pnpm sync && pnpm typecheck && pnpm build",
"start": "next start",
- "typecheck": "turbo run build --filter=@hackkit/cli && tsc -p tsconfig.json --noEmit",
- "test:db-matrix": "vitest run db/__tests__/dialects.test.ts",
- "test:runtime": "node scripts/test-runtime.mjs",
+ "typecheck": "tsc -p tsconfig.json --noEmit",
"db:status": "node scripts/db.mjs status",
"db:check": "node scripts/db.mjs check",
"db:rollback": "node scripts/db.mjs rollback"
@@ -57,7 +52,6 @@
"autoprefixer": "10.4.19",
"postcss": "8.4.39",
"tailwindcss": "3.4.6",
- "tailwindcss-animate": "1.0.7",
- "vitest": "^3.2.4"
+ "tailwindcss-animate": "1.0.7"
}
}
diff --git a/templates/nextjs-full/postcss.config.cjs b/templates/nextjs-full/postcss.config.cjs
new file mode 100644
index 000000000..e873f1a4f
--- /dev/null
+++ b/templates/nextjs-full/postcss.config.cjs
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/apps/web/scripts/database.ts b/templates/nextjs-full/scripts/database.ts
similarity index 100%
rename from apps/web/scripts/database.ts
rename to templates/nextjs-full/scripts/database.ts
diff --git a/apps/web/scripts/db.mjs b/templates/nextjs-full/scripts/db.mjs
similarity index 100%
rename from apps/web/scripts/db.mjs
rename to templates/nextjs-full/scripts/db.mjs
diff --git a/templates/nextjs-full/tailwind.config.ts b/templates/nextjs-full/tailwind.config.ts
new file mode 100644
index 000000000..cff883b9f
--- /dev/null
+++ b/templates/nextjs-full/tailwind.config.ts
@@ -0,0 +1,60 @@
+import type { Config } from "tailwindcss";
+
+const config = {
+ darkMode: ["class"],
+ content: [
+ "./app/**/*.{ts,tsx}",
+ "./components/**/*.{ts,tsx}",
+ "./lib/**/*.{ts,tsx}",
+ "../../packages/ui/src/**/*.{ts,tsx}",
+ "../../packages/plugin-*/src/**/*.{ts,tsx}",
+ "../../packages/plugin-*/app/**/*.{ts,tsx}",
+ ],
+ theme: {
+ extend: {
+ colors: {
+ border: "hsl(var(--border))",
+ input: "hsl(var(--input))",
+ ring: "hsl(var(--ring))",
+ background: "hsl(var(--background))",
+ foreground: "hsl(var(--foreground))",
+ primary: {
+ DEFAULT: "hsl(var(--primary))",
+ foreground: "hsl(var(--primary-foreground))",
+ },
+ secondary: {
+ DEFAULT: "hsl(var(--secondary))",
+ foreground: "hsl(var(--secondary-foreground))",
+ },
+ destructive: {
+ DEFAULT: "hsl(var(--destructive))",
+ foreground: "hsl(var(--destructive-foreground))",
+ },
+ muted: {
+ DEFAULT: "hsl(var(--muted))",
+ foreground: "hsl(var(--muted-foreground))",
+ },
+ accent: {
+ DEFAULT: "hsl(var(--accent))",
+ foreground: "hsl(var(--accent-foreground))",
+ },
+ popover: {
+ DEFAULT: "hsl(var(--popover))",
+ foreground: "hsl(var(--popover-foreground))",
+ },
+ card: {
+ DEFAULT: "hsl(var(--card))",
+ foreground: "hsl(var(--card-foreground))",
+ },
+ },
+ borderRadius: {
+ lg: "var(--radius)",
+ md: "calc(var(--radius) - 2px)",
+ sm: "calc(var(--radius) - 4px)",
+ },
+ },
+ },
+ plugins: [require("tailwindcss-animate")],
+} satisfies Config;
+
+export default config;
diff --git a/apps/web/tsconfig.json b/templates/nextjs-full/tsconfig.json
similarity index 100%
rename from apps/web/tsconfig.json
rename to templates/nextjs-full/tsconfig.json
diff --git a/templates/nextjs-minimal/.env.example b/templates/nextjs-minimal/.env.example
new file mode 100644
index 000000000..7a82b8ed9
--- /dev/null
+++ b/templates/nextjs-minimal/.env.example
@@ -0,0 +1,21 @@
+# Copy this file to .env. Keep real secrets in ignored environment files.
+# Local development works with an empty .env using these defaults.
+DATABASE_URL=file:.data/web.db
+NEXT_PUBLIC_APP_URL=http://localhost:3000
+
+# Required in production: set a unique secret with at least 32 characters.
+# Generate one with: node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"
+BETTER_AUTH_SECRET=
+
+# Production: replace NEXT_PUBLIC_APP_URL with your deployment URL and use
+# persistent disk paths for DATABASE_URL and HACKKIT_LOCAL_BLOB_BASE_DIR.
+
+# Optional: auth URL defaults to NEXT_PUBLIC_APP_URL.
+# BETTER_AUTH_URL=http://localhost:3000
+# Optional: comma-separated additional trusted origins.
+# BETTER_AUTH_TRUSTED_ORIGINS=https://another-origin.example.com
+# Optional: local upload directory, relative to this template or absolute.
+# HACKKIT_LOCAL_BLOB_BASE_DIR=.data/uploads
+
+# Optional: migration history directory, relative to this template or absolute.
+# HACKKIT_MIGRATIONS_PATH=db/migrations/sqlite
diff --git a/templates/nextjs-minimal/README.md b/templates/nextjs-minimal/README.md
new file mode 100644
index 000000000..cb8671e0c
--- /dev/null
+++ b/templates/nextjs-minimal/README.md
@@ -0,0 +1,42 @@
+# HackKit minimal Next.js template
+
+A runnable workspace example for hackathon registration and basic administration. It uses Core, Better Auth, HackKit UI, SQLite, and local file storage. It registers no plugins and needs no cloud-provider credentials.
+
+## Setup
+
+Use Node.js 22.17 or newer and the repository-pinned pnpm 12.15.0. From the repository root:
+
+1. Run `corepack pnpm install`.
+2. Build dependencies with `corepack pnpm exec turbo run build --filter=@hackkit/template-nextjs-minimal^...`.
+3. Run `corepack pnpm --filter @hackkit/template-nextjs-minimal sync`.
+4. Configure this template using `.env.example` and `hackkit.config.ts`. Use an empty SQLite development database.
+5. Run `corepack pnpm --filter @hackkit/template-nextjs-minimal db:generate --name initial`.
+6. Review the generated migration and snapshot, then run `corepack pnpm --filter @hackkit/template-nextjs-minimal db:migrate`.
+7. Run `corepack pnpm --filter @hackkit/template-nextjs-minimal db:seed`.
+8. Commit the migration and snapshot in your application repository. Run `corepack pnpm dev:minimal` and open `http://localhost:3000`.
+
+The local `.env` starts empty and is ignored by Git. On a fresh checkout, copy [`.env.example`](.env.example) to `.env` to configure this template. The example lists production requirements and comments out optional integrations. An empty `.env` uses local development defaults. Never commit populated environment files.
+
+Configuration belongs to this folder. Optional local overrides go in `.env.local`. Defaults use `.data/web.db` and `.data/uploads` relative to this template. Starting the app never migrates or seeds its database. Start either template individually; both development servers use port 3000.
+
+Sign up and complete HackTag, user data, and hacker registration. Organizers can then manage users, roles, approvals, settings, and CSV exports. Owner bootstrap is explicit: assign `core.owner` to the intended user's `core_user.role_id`, selected by the canonical Better Auth `user.id`. No account becomes an owner automatically.
+
+## Database commands
+
+Run `corepack pnpm --filter @hackkit/template-nextjs-minimal db:` from the repository root. Commands are `generate`, `migrate`, `seed`, `status`, `check`, `rollback`, and `reset`. Arguments are forwarded, for example `db:generate --name add_field` or `db:rollback --to MigrationName`.
+
+The template ships without migration history or snapshots. Generate a baseline once during new-project setup, after choosing your configuration. Commit the reviewed SQLite migration and snapshot under `db/migrations/sqlite` in your application repository. Later clones apply this history without generating another baseline. Future entity changes produce additional migrations. Existing databases must retain the history that created them.
+
+`HACKKIT_MIGRATIONS_PATH` optionally overrides the migration directory, relative to this application or absolute. `db:check` fails on pending migrations or schema drift. `db:reset` drops the selected database's registered tables and migration history, then migrates and seeds; it is restricted to local SQLite in development/tests. Use only disposable data for reset.
+
+## Production
+
+Set `NEXT_PUBLIC_APP_URL` or `BETTER_AUTH_URL` and a `BETTER_AUTH_SECRET` with at least 32 characters. `DATABASE_URL` must be a local SQLite path, such as `file:/persistent/hackkit/web.db`. Set `HACKKIT_LOCAL_BLOB_BASE_DIR=/persistent/hackkit/uploads` for uploads. Both locations must persist across application restarts. This template requires a Node server with persistent disk storage.
+
+After building dependencies, run this template's `typecheck` and `build`, apply reviewed migrations and seed explicitly, then run its `start` command. Cloud services and plugins are configured only in the [full template](../nextjs-full/README.md).
+
+## Validation and distribution
+
+Repository integration tests live in [E2E](../../e2e/README.md) and execute this template's real configuration, commands, and production build against temporary storage. `corepack pnpm test:e2e` validates both templates.
+
+This is a workspace example. Keep it inside a clone of the repository while dependencies use `workspace:*`. Standalone distribution and CLI initialization are a [later milestone](../../docs/plans/template-distribution.md).
diff --git a/templates/nextjs-minimal/app/admin/layout.tsx b/templates/nextjs-minimal/app/admin/layout.tsx
new file mode 100644
index 000000000..4c3ac90f3
--- /dev/null
+++ b/templates/nextjs-minimal/app/admin/layout.tsx
@@ -0,0 +1,48 @@
+import type * as React from "react";
+import { CorePermission } from "@hackkit/core";
+import Link from "next/link";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireNotBanned();
+ await guards.requirePermission(CorePermission.Admin);
+
+ const navItems = [
+ { href: "/admin", label: "Overview" },
+ { href: "/admin/users", label: "Users" },
+ { href: "/admin/roles", label: "Roles" },
+ { href: "/admin/settings", label: "Settings" },
+ ];
+
+ return (
+
+
+
+
Admin
+
+ Hackathon operations
+
+
+
+ {navItems.map((item) => (
+
+ {item.label}
+
+ ))}
+
+
+
{children}
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/admin/page.tsx b/templates/nextjs-minimal/app/admin/page.tsx
new file mode 100644
index 000000000..341549aa2
--- /dev/null
+++ b/templates/nextjs-minimal/app/admin/page.tsx
@@ -0,0 +1,27 @@
+import { AdminOverviewPanel } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminOverviewPage() {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const overview = await runtime.hackkit.admin.getOverview({ actorAuthId });
+
+ return (
+
+
+
+ Admin Overview
+
+
+ Registration, approval, and suspension summary.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/admin/roles/page.tsx b/templates/nextjs-minimal/app/admin/roles/page.tsx
new file mode 100644
index 000000000..77ef4780f
--- /dev/null
+++ b/templates/nextjs-minimal/app/admin/roles/page.tsx
@@ -0,0 +1,26 @@
+import { CorePermission } from "@hackkit/core";
+import { AdminRolesPanel } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminRolesPage() {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const roles = await runtime.hackkit.roles.listRoles({ actorAuthId });
+
+ return (
+
+
+
Roles
+
+ Manage admin roles and permissions.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/admin/settings/page.tsx b/templates/nextjs-minimal/app/admin/settings/page.tsx
new file mode 100644
index 000000000..122466338
--- /dev/null
+++ b/templates/nextjs-minimal/app/admin/settings/page.tsx
@@ -0,0 +1,38 @@
+import { CorePermission, CoreSetting } from "@hackkit/core";
+import { HackathonSettingsForm } from "@hackkit/ui";
+import { getPageGuards, getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+const registrationSettings = new Set([
+ CoreSetting.RegistrationOpen,
+ CoreSetting.RequireApproval,
+ CoreSetting.MaximumRegistrations,
+ CoreSetting.HackathonCapacity,
+]);
+
+export default async function AdminSettingsPage() {
+ const guards = await getPageGuards();
+ const principal = await guards.requirePermission(
+ CorePermission.SettingsManage,
+ );
+ const { hackkit } = await getRuntime();
+ const settings = await hackkit.settings.list({
+ actorAuthId: principal.user.id,
+ });
+
+ return (
+
+
+
Hackathon Settings
+
+ Manage live hackathon policy settings.
+
+
+
+ registrationSettings.has(setting.key),
+ )}
+ />
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/admin/users/[authId]/page.tsx b/templates/nextjs-minimal/app/admin/users/[authId]/page.tsx
new file mode 100644
index 000000000..4088acacc
--- /dev/null
+++ b/templates/nextjs-minimal/app/admin/users/[authId]/page.tsx
@@ -0,0 +1,40 @@
+import { notFound } from "next/navigation";
+import { AdminUserDetail } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminUserDetailPage({
+ params,
+}: {
+ params: { authId: string };
+}) {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const targetAuthId = decodeURIComponent(params.authId);
+ const [record, roles] = await Promise.all([
+ runtime.hackkit.admin.getUser({ actorAuthId, targetAuthId }),
+ runtime.hackkit.roles.listRoles({ actorAuthId }),
+ ]);
+
+ if (!record) notFound();
+
+ return (
+
+
+
+ User Detail
+
+
+ Account, registration, approval, suspension, and role
+ details.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/admin/users/page.tsx b/templates/nextjs-minimal/app/admin/users/page.tsx
new file mode 100644
index 000000000..c78ecd013
--- /dev/null
+++ b/templates/nextjs-minimal/app/admin/users/page.tsx
@@ -0,0 +1,26 @@
+import { AdminUsersTable } from "@hackkit/ui";
+import { getRuntime } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function AdminUsersPage() {
+ const runtime = await getRuntime();
+ const actorAuthId = await runtime.getAuthId();
+ const users = await runtime.hackkit.admin.listUsers({ actorAuthId });
+
+ return (
+
+
+
Users
+
+ Review registrations, approvals, roles, and suspensions.
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/api/admin/export/route.ts b/templates/nextjs-minimal/app/api/admin/export/route.ts
new file mode 100644
index 000000000..3ffa24d73
--- /dev/null
+++ b/templates/nextjs-minimal/app/api/admin/export/route.ts
@@ -0,0 +1,57 @@
+import { HackKitError } from "@hackkit/core";
+import { NextResponse } from "next/server";
+import { getAuthSession } from "@/lib/auth";
+import { getRuntime } from "@/lib/runtime";
+
+function escapeCsv(value: unknown): string {
+ if (value === null || value === undefined) return "";
+ const stringValue =
+ value instanceof Date
+ ? value.toISOString()
+ : typeof value === "string"
+ ? value
+ : String(value);
+ if (/[",\n\r]/.test(stringValue)) {
+ return `"${stringValue.replaceAll('"', '""')}"`;
+ }
+ return stringValue;
+}
+
+function toCsv(rows: Record[]): string {
+ if (rows.length === 0) return "";
+ const headers = Object.keys(rows[0] ?? {});
+ const body = rows.map((row) =>
+ headers.map((header) => escapeCsv(row[header])).join(","),
+ );
+ return [headers.join(","), ...body].join("\r\n");
+}
+
+export async function GET() {
+ const session = await getAuthSession();
+ if (!session) {
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ }
+
+ const runtime = await getRuntime();
+ const actor = await runtime.getCurrentUser();
+ const rows = await runtime.hackkit.admin
+ .exportUsers({
+ actorAuthId: actor.id,
+ })
+ .catch((error: unknown) => {
+ if (error instanceof HackKitError && error.code === "FORBIDDEN")
+ return null;
+ throw error;
+ });
+ if (!rows)
+ return NextResponse.json({ error: "Forbidden" }, { status: 403 });
+ const csv = toCsv(rows);
+ const timestamp = new Date().toISOString().replaceAll(":", "-");
+
+ return new NextResponse(csv, {
+ headers: {
+ "Content-Type": "text/csv; charset=utf-8",
+ "Content-Disposition": `attachment; filename="hackkit-users-${timestamp}.csv"`,
+ },
+ });
+}
diff --git a/templates/nextjs-minimal/app/api/auth/[...all]/route.ts b/templates/nextjs-minimal/app/api/auth/[...all]/route.ts
new file mode 100644
index 000000000..ac24ae8cf
--- /dev/null
+++ b/templates/nextjs-minimal/app/api/auth/[...all]/route.ts
@@ -0,0 +1,9 @@
+import { getAuth } from "@/lib/auth";
+
+export async function GET(request: Request) {
+ return (await getAuth()).handler(request);
+}
+
+export async function POST(request: Request) {
+ return (await getAuth()).handler(request);
+}
diff --git a/templates/nextjs-minimal/app/api/files/register/route.ts b/templates/nextjs-minimal/app/api/files/register/route.ts
new file mode 100644
index 000000000..16d935a0c
--- /dev/null
+++ b/templates/nextjs-minimal/app/api/files/register/route.ts
@@ -0,0 +1,41 @@
+import { NextResponse } from "next/server";
+import { getAuthSession } from "@/lib/auth";
+import { getBlobStorage } from "@/lib/blob";
+
+export async function POST(request: Request): Promise {
+ const session = await getAuthSession();
+ if (!session) {
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ }
+
+ try {
+ const body = (await request.json()) as {
+ location?: string;
+ fileName?: string;
+ };
+ if (!body.location || !body.fileName) {
+ return NextResponse.json(
+ { error: "location and fileName are required" },
+ { status: 400 },
+ );
+ }
+ if (!["resumes", "profile-photos"].includes(body.location)) {
+ return NextResponse.json(
+ { error: "Unsupported upload location." },
+ { status: 400 },
+ );
+ }
+
+ const target = await getBlobStorage().getUploadTarget({
+ location: body.location,
+ fileName: body.fileName,
+ });
+
+ return NextResponse.json(target);
+ } catch (error) {
+ return NextResponse.json(
+ { error: error instanceof Error ? error.message : "Bad request" },
+ { status: 400 },
+ );
+ }
+}
diff --git a/templates/nextjs-minimal/app/api/files/upload/route.ts b/templates/nextjs-minimal/app/api/files/upload/route.ts
new file mode 100644
index 000000000..fad7b0999
--- /dev/null
+++ b/templates/nextjs-minimal/app/api/files/upload/route.ts
@@ -0,0 +1,30 @@
+import { writeFile } from "node:fs/promises";
+import { NextResponse } from "next/server";
+import { getAuthSession } from "@/lib/auth";
+import { getBlobStorage } from "@/lib/blob";
+
+export async function PUT(request: Request): Promise {
+ const session = await getAuthSession();
+ if (!session) {
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ }
+
+ const url = new URL(request.url);
+ const key = url.searchParams.get("key");
+ if (!key) {
+ return NextResponse.json({ error: "key is required" }, { status: 400 });
+ }
+ if (!key.startsWith("resumes/") && !key.startsWith("profile-photos/")) {
+ return NextResponse.json(
+ { error: "Unsupported upload key." },
+ { status: 400 },
+ );
+ }
+
+ const storage = getBlobStorage();
+ const filePath = await storage.ensureDirectoryForKey(key);
+ const body = new Uint8Array(await request.arrayBuffer());
+ await writeFile(filePath, body);
+
+ return new NextResponse(null, { status: 204 });
+}
diff --git a/templates/nextjs-minimal/app/api/files/view/route.ts b/templates/nextjs-minimal/app/api/files/view/route.ts
new file mode 100644
index 000000000..82568f986
--- /dev/null
+++ b/templates/nextjs-minimal/app/api/files/view/route.ts
@@ -0,0 +1,55 @@
+import { NextResponse } from "next/server";
+import { CorePermission } from "@hackkit/core";
+import { getAuthSession } from "@/lib/auth";
+import { getBlobStorage } from "@/lib/blob";
+import { getRuntime } from "@/lib/runtime";
+
+function storedFileReferenceForKey(key: string): string {
+ return `/api/files/view?key=${encodeURIComponent(key)}`;
+}
+
+async function canViewFile(key: string): Promise {
+ if (key.startsWith("profile-photos/")) return true;
+
+ const session = await getAuthSession();
+ if (!session) return false;
+
+ const runtime = await getRuntime();
+ const currentUser = await runtime.getCurrentUser();
+ const hacker = await runtime.hackkit.hackers.getHacker(currentUser.id);
+ if (hacker?.resumeUrl === storedFileReferenceForKey(key)) return true;
+
+ return runtime.hackkit.accessControl.hasPermission(
+ currentUser.id,
+ CorePermission.HackersView,
+ );
+}
+
+export async function GET(request: Request): Promise {
+ const url = new URL(request.url);
+ const key = url.searchParams.get("key");
+ if (!key) {
+ return NextResponse.json({ error: "key is required" }, { status: 400 });
+ }
+ if (!key.startsWith("resumes/") && !key.startsWith("profile-photos/")) {
+ return NextResponse.json({ error: "Not found" }, { status: 404 });
+ }
+ if (!(await canViewFile(key))) {
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+ }
+
+ const storage = getBlobStorage();
+
+ const result = await storage.readObject({ key });
+ if (!result)
+ return NextResponse.json({ error: "Not found" }, { status: 404 });
+ const body =
+ result.body instanceof Uint8Array
+ ? Uint8Array.from(result.body).buffer
+ : await new Response(result.body).arrayBuffer();
+ return new NextResponse(body, {
+ headers: {
+ "Content-Type": result.contentType ?? "application/octet-stream",
+ },
+ });
+}
diff --git a/templates/nextjs-minimal/app/api/hackkit/[...path]/route.ts b/templates/nextjs-minimal/app/api/hackkit/[...path]/route.ts
new file mode 100644
index 000000000..7584eab06
--- /dev/null
+++ b/templates/nextjs-minimal/app/api/hackkit/[...path]/route.ts
@@ -0,0 +1,4 @@
+import { handleHackkitRequest } from "@/lib/runtime";
+export const runtime = "nodejs";
+export const dynamic = "force-dynamic";
+export const POST = handleHackkitRequest;
diff --git a/templates/nextjs-minimal/app/app-bar.tsx b/templates/nextjs-minimal/app/app-bar.tsx
new file mode 100644
index 000000000..cd64b6213
--- /dev/null
+++ b/templates/nextjs-minimal/app/app-bar.tsx
@@ -0,0 +1,76 @@
+import Link from "next/link";
+import { CorePermission } from "@hackkit/core";
+import { getAuthSession } from "@/lib/auth";
+import { getCurrentUser, getRuntime } from "@/lib/runtime";
+import { publicSiteConfig } from "@/lib/public-site-config";
+import { ProfileMenu } from "./profile-menu";
+
+async function getIsAdmin(authId: string) {
+ const runtime = await getRuntime();
+ return runtime.hackkit.accessControl.hasPermission(
+ authId,
+ CorePermission.Admin,
+ );
+}
+
+export async function AppBar() {
+ const session = await getAuthSession();
+ const currentUser = session ? await getCurrentUser() : null;
+ const isAdmin = currentUser ? await getIsAdmin(currentUser.id) : false;
+
+ return (
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/contact/page.tsx b/templates/nextjs-minimal/app/contact/page.tsx
new file mode 100644
index 000000000..dbc3d35d1
--- /dev/null
+++ b/templates/nextjs-minimal/app/contact/page.tsx
@@ -0,0 +1 @@
+export { default } from "../help/page";
diff --git a/templates/nextjs-minimal/app/dashboard/layout.tsx b/templates/nextjs-minimal/app/dashboard/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-minimal/app/dashboard/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-minimal/app/dashboard/page.tsx b/templates/nextjs-minimal/app/dashboard/page.tsx
new file mode 100644
index 000000000..15ec73fe2
--- /dev/null
+++ b/templates/nextjs-minimal/app/dashboard/page.tsx
@@ -0,0 +1,68 @@
+import {
+ CompetitorOnboardingProgress,
+ ParticipantDashboard,
+} from "@hackkit/ui";
+import { publicSiteConfig } from "@/lib/public-site-config";
+import { getHackkit } from "@/lib/runtime";
+import {
+ getCompetitorOnboardingState,
+ getRequireApproval,
+} from "@/lib/onboarding";
+
+export const dynamic = "force-dynamic";
+
+export default async function DashboardPage() {
+ const {
+ steps,
+ nextHref,
+ user: currentUser,
+ userData,
+ hacker,
+ } = await getCompetitorOnboardingState("/dashboard");
+ const [hackkit, requireApproval] = await Promise.all([
+ getHackkit(),
+ getRequireApproval(),
+ ]);
+ const role = currentUser.roleId
+ ? await hackkit.roles.getRole(currentUser.roleId)
+ : null;
+ const participantName =
+ currentUser.name || currentUser.hackTag || "participant";
+
+ return (
+
+ ),
+ }
+ : undefined
+ }
+ />
+ );
+}
diff --git a/templates/nextjs-minimal/app/globals.css b/templates/nextjs-minimal/app/globals.css
new file mode 100644
index 000000000..e0ea2ecce
--- /dev/null
+++ b/templates/nextjs-minimal/app/globals.css
@@ -0,0 +1,58 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
+ --primary: 221.2 83.2% 53.3%;
+ --primary-foreground: 210 40% 98%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 221.2 83.2% 53.3%;
+ --radius: 0.5rem;
+ }
+
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
+ --primary: 217.2 91.2% 59.8%;
+ --primary-foreground: 222.2 47.4% 11.2%;
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 224.3 76.3% 48%;
+ }
+
+ * {
+ @apply border-border;
+ }
+
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/templates/nextjs-minimal/app/help/page.tsx b/templates/nextjs-minimal/app/help/page.tsx
new file mode 100644
index 000000000..4876f845d
--- /dev/null
+++ b/templates/nextjs-minimal/app/help/page.tsx
@@ -0,0 +1,13 @@
+import { PublicHelpPage } from "@hackkit/ui";
+import { publicSiteConfig } from "@/lib/public-site-config";
+
+export default function HelpPage() {
+ return (
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/i/approval/layout.tsx b/templates/nextjs-minimal/app/i/approval/layout.tsx
new file mode 100644
index 000000000..6e9c3af0d
--- /dev/null
+++ b/templates/nextjs-minimal/app/i/approval/layout.tsx
@@ -0,0 +1,14 @@
+import type * as React from "react";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function ApprovalLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireApprovalPendingAccess();
+ return children;
+}
diff --git a/templates/nextjs-minimal/app/i/approval/page.tsx b/templates/nextjs-minimal/app/i/approval/page.tsx
new file mode 100644
index 000000000..d17b19d1b
--- /dev/null
+++ b/templates/nextjs-minimal/app/i/approval/page.tsx
@@ -0,0 +1,26 @@
+import Link from "next/link";
+
+export default function ApprovalPendingPage() {
+ return (
+
+
+
+ Registration received
+
+
+ Your account is awaiting approval.
+
+
+ Organizers are reviewing your registration. Once approved,
+ you can access participant dashboard and profile settings.
+
+
+ Back to dashboard
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/layout.tsx b/templates/nextjs-minimal/app/layout.tsx
new file mode 100644
index 000000000..526d48b13
--- /dev/null
+++ b/templates/nextjs-minimal/app/layout.tsx
@@ -0,0 +1,38 @@
+import type * as React from "react";
+import type { Metadata } from "next";
+import { PublicSiteFooter } from "@hackkit/ui";
+import {
+ getPublicThemeStyle,
+ publicSiteConfig,
+} from "@/lib/public-site-config";
+import "./globals.css";
+import { AppBar } from "./app-bar";
+import { Providers } from "./providers";
+
+export const metadata: Metadata = {
+ title: publicSiteConfig.brand.name,
+ description: publicSiteConfig.brand.description,
+};
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+
+
+ {children}
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/onboarding/hacker/hacker-form-defaults.ts b/templates/nextjs-minimal/app/onboarding/hacker/hacker-form-defaults.ts
new file mode 100644
index 000000000..edd46c9ef
--- /dev/null
+++ b/templates/nextjs-minimal/app/onboarding/hacker/hacker-form-defaults.ts
@@ -0,0 +1,18 @@
+import type { Hacker } from "@hackkit/core";
+
+export function toHackerFormDefaults(hacker: Hacker | null) {
+ if (!hacker) return undefined;
+ return {
+ university: hacker.university,
+ major: hacker.major,
+ schoolId: hacker.schoolId ?? undefined,
+ levelOfStudy: hacker.levelOfStudy,
+ hackathonsAttended: hacker.hackathonsAttended,
+ softwareExperience: hacker.softwareExperience,
+ heardFrom: hacker.heardFrom ?? undefined,
+ githubUrl: hacker.githubUrl ?? undefined,
+ linkedInUrl: hacker.linkedInUrl ?? undefined,
+ personalWebsiteUrl: hacker.personalWebsiteUrl ?? undefined,
+ resumeUrl: hacker.resumeUrl ?? undefined,
+ };
+}
diff --git a/templates/nextjs-minimal/app/onboarding/hacker/hacker-registration-client.tsx b/templates/nextjs-minimal/app/onboarding/hacker/hacker-registration-client.tsx
new file mode 100644
index 000000000..1cb6ab6fb
--- /dev/null
+++ b/templates/nextjs-minimal/app/onboarding/hacker/hacker-registration-client.tsx
@@ -0,0 +1,45 @@
+"use client";
+
+import { HackerRegistrationForm } from "@hackkit/ui";
+import type { User } from "@hackkit/core";
+import type { HackerRegistrationOptions } from "@hackkit/config";
+import { uploadResumeFile } from "@/lib/upload-resume";
+
+export function HackerRegistrationClient({
+ currentUser,
+ defaultValues,
+ registrationOptions,
+ successRedirectTo = "/dashboard",
+}: {
+ currentUser: User;
+ defaultValues?: Partial<{
+ university: string;
+ major: string;
+ schoolId?: string;
+ levelOfStudy: string;
+ hackathonsAttended: number;
+ softwareExperience: string;
+ heardFrom?: string;
+ githubUrl?: string;
+ linkedInUrl?: string;
+ personalWebsiteUrl?: string;
+ resumeUrl?: string;
+ }>;
+ registrationOptions?: HackerRegistrationOptions;
+ successRedirectTo?: string;
+}) {
+ return (
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/onboarding/hacker/page.tsx b/templates/nextjs-minimal/app/onboarding/hacker/page.tsx
new file mode 100644
index 000000000..c05b57516
--- /dev/null
+++ b/templates/nextjs-minimal/app/onboarding/hacker/page.tsx
@@ -0,0 +1,40 @@
+import { redirect } from "next/navigation";
+import { getCurrentUser, getHackkit, getPageGuards } from "@/lib/runtime";
+import { appConfig } from "@/lib/app-config";
+import { getOnboardingSteps } from "@/lib/onboarding";
+import { OnboardingShell } from "../onboarding-shell";
+import { HackerRegistrationClient } from "./hacker-registration-client";
+import { toHackerFormDefaults } from "./hacker-form-defaults";
+
+export const dynamic = "force-dynamic";
+
+export default async function HackerOnboardingPage() {
+ await (await getPageGuards()).requireHackerRegistrationOpenForNewHacker();
+ const currentUser = await getCurrentUser();
+ if (!currentUser.hackTag) {
+ redirect("/onboarding/hacktag");
+ }
+
+ const hackkit = await getHackkit();
+ const userData = await hackkit.userData.getUserData(currentUser.id);
+ if (!userData) {
+ redirect("/onboarding/user-data");
+ }
+
+ const hacker = await hackkit.hackers.getHacker(currentUser.id);
+ const steps = await getOnboardingSteps("/onboarding/hacker");
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/onboarding/hacktag/page.tsx b/templates/nextjs-minimal/app/onboarding/hacktag/page.tsx
new file mode 100644
index 000000000..7c98a15d4
--- /dev/null
+++ b/templates/nextjs-minimal/app/onboarding/hacktag/page.tsx
@@ -0,0 +1,30 @@
+import { HackTagForm } from "@hackkit/ui";
+import { getCurrentUser } from "@/lib/runtime";
+import { getOnboardingSteps } from "@/lib/onboarding";
+import { OnboardingShell } from "../onboarding-shell";
+
+export const dynamic = "force-dynamic";
+
+export default async function HackTagOnboardingPage() {
+ const currentUser = await getCurrentUser();
+ const steps = await getOnboardingSteps("/onboarding/hacktag");
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/onboarding/layout.tsx b/templates/nextjs-minimal/app/onboarding/layout.tsx
new file mode 100644
index 000000000..b2898f3bb
--- /dev/null
+++ b/templates/nextjs-minimal/app/onboarding/layout.tsx
@@ -0,0 +1,14 @@
+import type * as React from "react";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function OnboardingLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireOnboardingAccess();
+ return children;
+}
diff --git a/templates/nextjs-minimal/app/onboarding/onboarding-shell.tsx b/templates/nextjs-minimal/app/onboarding/onboarding-shell.tsx
new file mode 100644
index 000000000..5196fa8aa
--- /dev/null
+++ b/templates/nextjs-minimal/app/onboarding/onboarding-shell.tsx
@@ -0,0 +1,35 @@
+import {
+ CompetitorOnboardingProgress,
+ type CompetitorOnboardingStep,
+} from "@hackkit/ui";
+import type * as React from "react";
+
+export function OnboardingShell({
+ steps,
+ title,
+ description,
+ children,
+}: {
+ steps: CompetitorOnboardingStep[];
+ title: string;
+ description: string;
+ children: React.ReactNode;
+}) {
+ return (
+
+
+
+
+ Competitor onboarding
+
+
+ {title}
+
+
{description}
+
+
+ {children}
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/onboarding/user-data/page.tsx b/templates/nextjs-minimal/app/onboarding/user-data/page.tsx
new file mode 100644
index 000000000..394f5136b
--- /dev/null
+++ b/templates/nextjs-minimal/app/onboarding/user-data/page.tsx
@@ -0,0 +1,38 @@
+import { UserDataForm, toUserDataFormDefaultValues } from "@hackkit/ui";
+import { redirect } from "next/navigation";
+import { getCurrentUser, getHackkit } from "@/lib/runtime";
+import { getOnboardingSteps } from "@/lib/onboarding";
+import { OnboardingShell } from "../onboarding-shell";
+
+export const dynamic = "force-dynamic";
+
+export default async function UserDataOnboardingPage() {
+ const currentUser = await getCurrentUser();
+ if (!currentUser.hackTag) {
+ redirect("/onboarding/hacktag");
+ }
+
+ const hackkit = await getHackkit();
+ const existingUserData = await hackkit.userData.getUserData(currentUser.id);
+ const steps = await getOnboardingSteps("/onboarding/user-data");
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/page.tsx b/templates/nextjs-minimal/app/page.tsx
new file mode 100644
index 000000000..a5682ee66
--- /dev/null
+++ b/templates/nextjs-minimal/app/page.tsx
@@ -0,0 +1,17 @@
+import { PublicLandingPage } from "@hackkit/ui";
+import { getAuthSession } from "@/lib/auth";
+import { publicSiteConfig } from "@/lib/public-site-config";
+
+export const dynamic = "force-dynamic";
+
+export default async function HomePage() {
+ const session = await getAuthSession();
+ const { signedInAction, ...landing } = publicSiteConfig.landing;
+
+ return (
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/participant-layout.tsx b/templates/nextjs-minimal/app/participant-layout.tsx
new file mode 100644
index 000000000..09ccadc7a
--- /dev/null
+++ b/templates/nextjs-minimal/app/participant-layout.tsx
@@ -0,0 +1,14 @@
+import type * as React from "react";
+import { getPageGuards } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function ParticipantLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const guards = await getPageGuards();
+ await guards.requireParticipantAccess();
+ return children;
+}
diff --git a/templates/nextjs-minimal/app/profile-menu.tsx b/templates/nextjs-minimal/app/profile-menu.tsx
new file mode 100644
index 000000000..25c01ee34
--- /dev/null
+++ b/templates/nextjs-minimal/app/profile-menu.tsx
@@ -0,0 +1,116 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import { useRouter } from "next/navigation";
+import { authClient } from "@/lib/auth-client";
+
+export function ProfileMenu({
+ name,
+ email,
+ image,
+ isAdmin = false,
+}: {
+ name: string;
+ email: string;
+ image?: string | null;
+ isAdmin?: boolean;
+}) {
+ const router = useRouter();
+ const [isOpen, setIsOpen] = useState(false);
+ const [isSigningOut, setIsSigningOut] = useState(false);
+ const initials =
+ name
+ .split(/\s+/)
+ .filter(Boolean)
+ .slice(0, 2)
+ .map((part) => part[0]?.toUpperCase())
+ .join("") || "U";
+
+ async function signOut() {
+ setIsSigningOut(true);
+ await authClient.signOut();
+ router.push("/sign-in");
+ router.refresh();
+ }
+
+ return (
+
+
setIsOpen((value) => !value)}
+ className="flex items-center gap-2 rounded-full border bg-background px-2 py-1.5 text-sm font-medium shadow-sm transition hover:bg-muted"
+ aria-label="Open account menu"
+ aria-haspopup="menu"
+ aria-expanded={isOpen}
+ >
+ {image ? (
+ // eslint-disable-next-line @next/next/no-img-element
+
+ ) : (
+
+ {initials}
+
+ )}
+
+ {name}
+
+
+
+ {isOpen ? (
+
+
+
+ setIsOpen(false)}
+ className="block rounded-md px-3 py-2 text-sm hover:bg-muted"
+ >
+ Settings
+
+ setIsOpen(false)}
+ className="block rounded-md px-3 py-2 text-sm hover:bg-muted"
+ >
+ Registration
+
+ {isAdmin ? (
+ setIsOpen(false)}
+ className="block rounded-md px-3 py-2 text-sm text-accent-foreground hover:bg-muted"
+ >
+ Admin
+
+ ) : null}
+
+ {isSigningOut ? "Signing out..." : "Log out"}
+
+
+
+ ) : null}
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/providers.tsx b/templates/nextjs-minimal/app/providers.tsx
new file mode 100644
index 000000000..35d6da071
--- /dev/null
+++ b/templates/nextjs-minimal/app/providers.tsx
@@ -0,0 +1,12 @@
+"use client";
+import { HackKitUIProvider } from "@hackkit/ui";
+import { createHackkitClient } from "@hackkit/core/http/client";
+import type * as React from "react";
+
+const hackkitClient = createHackkitClient();
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+ {children}
+ );
+}
diff --git a/templates/nextjs-minimal/app/register/page.tsx b/templates/nextjs-minimal/app/register/page.tsx
new file mode 100644
index 000000000..ad808fca8
--- /dev/null
+++ b/templates/nextjs-minimal/app/register/page.tsx
@@ -0,0 +1,5 @@
+import { redirect } from "next/navigation";
+
+export default function RegisterRedirectPage() {
+ redirect("/onboarding/user-data");
+}
diff --git a/templates/nextjs-minimal/app/registration-closed/page.tsx b/templates/nextjs-minimal/app/registration-closed/page.tsx
new file mode 100644
index 000000000..c11572fac
--- /dev/null
+++ b/templates/nextjs-minimal/app/registration-closed/page.tsx
@@ -0,0 +1,26 @@
+import Link from "next/link";
+
+export default function RegistrationClosedPage() {
+ return (
+
+
+
+ Registration closed
+
+
+ New hacker registrations are closed.
+
+
+ If you have already started registration, sign in to check
+ your current status or contact the organizing team.
+
+
+ Go to dashboard
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/settings/layout.tsx b/templates/nextjs-minimal/app/settings/layout.tsx
new file mode 100644
index 000000000..fb92bcda9
--- /dev/null
+++ b/templates/nextjs-minimal/app/settings/layout.tsx
@@ -0,0 +1 @@
+export { default, dynamic } from "../participant-layout";
diff --git a/templates/nextjs-minimal/app/settings/page.tsx b/templates/nextjs-minimal/app/settings/page.tsx
new file mode 100644
index 000000000..a2c9193e7
--- /dev/null
+++ b/templates/nextjs-minimal/app/settings/page.tsx
@@ -0,0 +1,36 @@
+import Link from "next/link";
+import { getCurrentUser } from "@/lib/runtime";
+import { ProfileSettingsClient } from "./profile-settings-client";
+
+export const dynamic = "force-dynamic";
+
+export default async function SettingsPage() {
+ const currentUser = await getCurrentUser();
+
+ return (
+
+
+
Settings
+
+ Manage your account profile and public HackKit profile.
+
+
+
+
+
+
+ Registration
+
+ You can update your demographic, logistics, school,
+ experience, and resume information after registration.
+
+
+ Edit registration
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/settings/profile-settings-client.tsx b/templates/nextjs-minimal/app/settings/profile-settings-client.tsx
new file mode 100644
index 000000000..12e089aa4
--- /dev/null
+++ b/templates/nextjs-minimal/app/settings/profile-settings-client.tsx
@@ -0,0 +1,15 @@
+"use client";
+
+import { UserProfileSettingsForm } from "@hackkit/ui";
+import type { User } from "@hackkit/core";
+import { uploadProfilePhotoFile } from "@/lib/upload-profile-photo";
+
+export function ProfileSettingsClient({ currentUser }: { currentUser: User }) {
+ return (
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/settings/registration/page.tsx b/templates/nextjs-minimal/app/settings/registration/page.tsx
new file mode 100644
index 000000000..f72c69355
--- /dev/null
+++ b/templates/nextjs-minimal/app/settings/registration/page.tsx
@@ -0,0 +1,54 @@
+import Link from "next/link";
+import { UserDataForm, toUserDataFormDefaultValues } from "@hackkit/ui";
+import { getCurrentUser, getHackkit } from "@/lib/runtime";
+import { appConfig } from "@/lib/app-config";
+import { toHackerFormDefaults } from "@/app/onboarding/hacker/hacker-form-defaults";
+import { HackerRegistrationClient } from "@/app/onboarding/hacker/hacker-registration-client";
+
+export const dynamic = "force-dynamic";
+
+export default async function RegistrationSettingsPage() {
+ const currentUser = await getCurrentUser();
+ const hackkit = await getHackkit();
+ const [userData, hacker] = await Promise.all([
+ hackkit.userData.getUserData(currentUser.id),
+ hackkit.hackers.getHacker(currentUser.id),
+ ]);
+
+ return (
+
+
+
+ Back to settings
+
+
+ Registration Settings
+
+
+ Update registration details that organizers use for
+ logistics and participant review.
+
+
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/sign-in/auth-form.tsx b/templates/nextjs-minimal/app/sign-in/auth-form.tsx
new file mode 100644
index 000000000..aad59d2f0
--- /dev/null
+++ b/templates/nextjs-minimal/app/sign-in/auth-form.tsx
@@ -0,0 +1,100 @@
+"use client";
+
+import { useState, type FormEvent } from "react";
+import Link from "next/link";
+import { useRouter } from "next/navigation";
+import { authClient } from "@/lib/auth-client";
+
+type AuthMode = "sign-in" | "sign-up";
+
+export function AuthForm({ mode }: { mode: AuthMode }) {
+ const router = useRouter();
+ const [error, setError] = useState(null);
+ const [isPending, setIsPending] = useState(false);
+ const isSignUp = mode === "sign-up";
+
+ async function onSubmit(event: FormEvent) {
+ event.preventDefault();
+ setError(null);
+ setIsPending(true);
+
+ const form = new FormData(event.currentTarget);
+ const email = String(form.get("email") ?? "");
+ const password = String(form.get("password") ?? "");
+ const name = String(form.get("name") ?? email);
+
+ const result = isSignUp
+ ? await authClient.signUp.email({ email, password, name })
+ : await authClient.signIn.email({ email, password });
+
+ setIsPending(false);
+
+ if (result.error) {
+ setError(result.error.message ?? "Authentication failed.");
+ return;
+ }
+
+ router.push(isSignUp ? "/register" : "/");
+ router.refresh();
+ }
+
+ return (
+
+ {isSignUp ? (
+
+ Name
+
+
+ ) : null}
+
+ Email
+
+
+
+ Password
+
+
+ {error ? {error}
: null}
+
+ {isPending
+ ? "Working..."
+ : isSignUp
+ ? "Create account"
+ : "Sign in"}
+
+
+ {isSignUp
+ ? "Have an account? Sign in"
+ : "Need an account? Sign up"}
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/sign-in/page.tsx b/templates/nextjs-minimal/app/sign-in/page.tsx
new file mode 100644
index 000000000..03f759629
--- /dev/null
+++ b/templates/nextjs-minimal/app/sign-in/page.tsx
@@ -0,0 +1,24 @@
+import { redirect } from "next/navigation";
+import { getAuthSession } from "@/lib/auth";
+import { AuthForm } from "./auth-form";
+
+export const dynamic = "force-dynamic";
+
+export default async function SignInPage() {
+ const session = await getAuthSession();
+ if (session) redirect("/");
+
+ return (
+
+
+
+
HackKit
+
+ Sign in
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/sign-up/page.tsx b/templates/nextjs-minimal/app/sign-up/page.tsx
new file mode 100644
index 000000000..d43a22eeb
--- /dev/null
+++ b/templates/nextjs-minimal/app/sign-up/page.tsx
@@ -0,0 +1,27 @@
+import { redirect } from "next/navigation";
+import { getAuthSession } from "@/lib/auth";
+import { AuthForm } from "../sign-in/auth-form";
+
+export const dynamic = "force-dynamic";
+
+export default async function SignUpPage() {
+ const session = await getAuthSession();
+ if (session) redirect("/onboarding/hacktag");
+
+ return (
+
+
+
+
HackKit
+
+ Sign up
+
+
+ Create an account, then complete registration.
+
+
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/suspended/page.tsx b/templates/nextjs-minimal/app/suspended/page.tsx
new file mode 100644
index 000000000..694e510f8
--- /dev/null
+++ b/templates/nextjs-minimal/app/suspended/page.tsx
@@ -0,0 +1,18 @@
+export default function SuspendedPage() {
+ return (
+
+
+
+ Account suspended
+
+
+ Your access to this HackKit app is suspended.
+
+
+ If you think this is a mistake, contact the organizing team
+ for help.
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/app/user/[tag]/page.tsx b/templates/nextjs-minimal/app/user/[tag]/page.tsx
new file mode 100644
index 000000000..7777572a7
--- /dev/null
+++ b/templates/nextjs-minimal/app/user/[tag]/page.tsx
@@ -0,0 +1,23 @@
+import { notFound } from "next/navigation";
+import { PublicProfileCard } from "@hackkit/ui";
+import { getHackkit } from "@/lib/runtime";
+
+export const dynamic = "force-dynamic";
+
+export default async function PublicUserProfilePage({
+ params,
+}: {
+ params: { tag: string };
+}) {
+ const tag = decodeURIComponent(params.tag);
+ const profile = await (
+ await getHackkit()
+ ).users.getPublicProfileByHackTag(tag);
+ if (!profile) notFound();
+
+ return (
+
+
+
+ );
+}
diff --git a/templates/nextjs-minimal/env.ts b/templates/nextjs-minimal/env.ts
new file mode 100644
index 000000000..4b0a303d9
--- /dev/null
+++ b/templates/nextjs-minimal/env.ts
@@ -0,0 +1,50 @@
+function read(name: string) {
+ const value = process.env[name]?.trim();
+ return value || undefined;
+}
+
+export function resolveTemplateEnv() {
+ const production = process.env.NODE_ENV === "production";
+ const appUrl =
+ read("NEXT_PUBLIC_APP_URL") ??
+ read("BETTER_AUTH_URL") ??
+ "http://localhost:3000";
+ const betterAuthSecret =
+ read("BETTER_AUTH_SECRET") ??
+ "minimal-development-secret-change-me-please";
+ if (production) {
+ if (!read("NEXT_PUBLIC_APP_URL") && !read("BETTER_AUTH_URL"))
+ throw new Error(
+ "Set NEXT_PUBLIC_APP_URL or BETTER_AUTH_URL in production.",
+ );
+ if (!read("BETTER_AUTH_SECRET") || betterAuthSecret.length < 32)
+ throw new Error(
+ "Set BETTER_AUTH_SECRET to at least 32 characters in production.",
+ );
+ }
+ const databaseUrl = read("DATABASE_URL") ?? "file:.data/web.db";
+ if (
+ /^[a-z][a-z\d+.-]*:/i.test(databaseUrl) &&
+ !databaseUrl.startsWith("file:") &&
+ databaseUrl !== ":memory:"
+ )
+ throw new Error(
+ "The minimal template requires a local SQLite DATABASE_URL.",
+ );
+ return {
+ nodeEnv: production ? "production" : "development",
+ appUrl,
+ betterAuthUrl: read("BETTER_AUTH_URL") ?? appUrl,
+ betterAuthSecret,
+ betterAuthTrustedOrigins:
+ read("BETTER_AUTH_TRUSTED_ORIGINS")
+ ?.split(",")
+ .map((value) => value.trim())
+ .filter(Boolean) ?? [],
+ databaseUrl,
+ migrationsPath: read("HACKKIT_MIGRATIONS_PATH"),
+ localBlobBaseDir:
+ read("HACKKIT_LOCAL_BLOB_BASE_DIR") ?? ".data/uploads",
+ };
+}
+export const env = resolveTemplateEnv();
diff --git a/templates/nextjs-minimal/hackkit.config.ts b/templates/nextjs-minimal/hackkit.config.ts
new file mode 100644
index 000000000..e1ae2b121
--- /dev/null
+++ b/templates/nextjs-minimal/hackkit.config.ts
@@ -0,0 +1,105 @@
+import { defineHackkitConfig } from "@hackkit/config";
+import { CorePermission } from "@hackkit/core";
+import { databaseOptions } from "./lib/database-config";
+import { authOptions } from "./lib/auth-options";
+import { env } from "./env";
+const shirtSizeOptions = [
+ { value: "s", label: "Small" },
+ { value: "m", label: "Medium" },
+ { value: "l", label: "Large" },
+ { value: "xl", label: "Extra large" },
+ { value: "2xl", label: "2XL" },
+ { value: "3xl", label: "3XL" },
+];
+
+const countryOptions = [
+ { value: "us", label: "United States" },
+ { value: "ca", label: "Canada" },
+ { value: "mx", label: "Mexico" },
+ { value: "gb", label: "United Kingdom" },
+ { value: "other", label: "Other" },
+];
+
+const schoolOptions = [
+ {
+ value: "University of Texas at San Antonio",
+ label: "University of Texas at San Antonio",
+ },
+ {
+ value: "University of Texas at Austin",
+ label: "University of Texas at Austin",
+ },
+ { value: "Texas A&M University", label: "Texas A&M University" },
+ { value: "Rice University", label: "Rice University" },
+ { value: "other", label: "Other" },
+];
+
+const majorOptions = [
+ { value: "Computer Science", label: "Computer Science" },
+ { value: "Computer Engineering", label: "Computer Engineering" },
+ { value: "Electrical Engineering", label: "Electrical Engineering" },
+ { value: "Data Science", label: "Data Science" },
+ { value: "Design", label: "Design" },
+ { value: "Business", label: "Business" },
+ { value: "other", label: "Other" },
+];
+
+const levelsOfStudy = [
+ { value: "Freshman", label: "Freshman" },
+ { value: "Sophomore", label: "Sophomore" },
+ { value: "Junior", label: "Junior" },
+ { value: "Senior", label: "Senior" },
+ { value: "Graduate", label: "Graduate" },
+ { value: "Recent Grad", label: "Recent Grad" },
+ { value: "Other", label: "Other" },
+];
+
+const softwareExperienceOptions = [
+ { value: "Beginner", label: "Beginner" },
+ { value: "Intermediate", label: "Intermediate" },
+ { value: "Advanced", label: "Advanced" },
+ { value: "Expert", label: "Expert" },
+];
+
+const heardFromOptions = [
+ { value: "Instagram", label: "Instagram" },
+ { value: "Class Presentation", label: "Class presentation" },
+ { value: "Twitter", label: "Twitter" },
+ { value: "Event Site", label: "Event site" },
+ { value: "Friend", label: "Friend" },
+ { value: "Other", label: "Other" },
+];
+
+export default defineHackkitConfig({
+ database: databaseOptions,
+ auth: authOptions,
+ defaultCompetitorRoleId: "core.participant",
+ seedRoles: [
+ {
+ id: "core.participant",
+ name: "Participant",
+ position: 10,
+ permissions: [],
+ },
+ {
+ id: "core.owner",
+ name: "Owner",
+ position: 0,
+ permissions: Object.values(CorePermission),
+ },
+ ],
+ blob: { adapter: "local", baseDir: env.localBlobBaseDir },
+ logger: { level: env.nodeEnv === "production" ? "warn" : "debug" },
+ plugins: [],
+ userDataOptions: {
+ shirtSize: shirtSizeOptions,
+ countryOfResidence: countryOptions,
+ },
+ hackerRegistrationOptions: {
+ schools: schoolOptions,
+ majors: majorOptions,
+ levelsOfStudy,
+ softwareExperience: softwareExperienceOptions,
+ heardFrom: heardFromOptions,
+ },
+});
diff --git a/templates/nextjs-minimal/hackkit.lock b/templates/nextjs-minimal/hackkit.lock
new file mode 100644
index 000000000..2e7bed4e6
--- /dev/null
+++ b/templates/nextjs-minimal/hackkit.lock
@@ -0,0 +1,4 @@
+{
+ "version": 1,
+ "plugins": []
+}
diff --git a/templates/nextjs-minimal/lib/app-config.ts b/templates/nextjs-minimal/lib/app-config.ts
new file mode 100644
index 000000000..31a9a0e16
--- /dev/null
+++ b/templates/nextjs-minimal/lib/app-config.ts
@@ -0,0 +1,11 @@
+import "server-only";
+
+import { resolveHackkitConfig } from "@hackkit/config";
+import hackkitConfig from "../hackkit.config";
+import { env } from "../env";
+
+export const appConfig = resolveHackkitConfig(hackkitConfig);
+
+export function resolveAppBaseUrl(): string {
+ return env.appUrl;
+}
diff --git a/templates/nextjs-minimal/lib/auth-client.ts b/templates/nextjs-minimal/lib/auth-client.ts
new file mode 100644
index 000000000..2f75fd48b
--- /dev/null
+++ b/templates/nextjs-minimal/lib/auth-client.ts
@@ -0,0 +1,5 @@
+"use client";
+
+import { createAuthClient } from "better-auth/react";
+
+export const authClient = createAuthClient();
diff --git a/templates/nextjs-minimal/lib/auth-options.ts b/templates/nextjs-minimal/lib/auth-options.ts
new file mode 100644
index 000000000..8ba418753
--- /dev/null
+++ b/templates/nextjs-minimal/lib/auth-options.ts
@@ -0,0 +1,8 @@
+import type { HackKitAuthOptions } from "@hackkit/core";
+import { env } from "../env";
+export const authOptions = {
+ baseURL: env.betterAuthUrl,
+ secret: env.betterAuthSecret,
+ trustedOrigins: env.betterAuthTrustedOrigins,
+ emailAndPassword: { enabled: true },
+} satisfies HackKitAuthOptions;
diff --git a/templates/nextjs-minimal/lib/auth.ts b/templates/nextjs-minimal/lib/auth.ts
new file mode 100644
index 000000000..66b0565a1
--- /dev/null
+++ b/templates/nextjs-minimal/lib/auth.ts
@@ -0,0 +1,11 @@
+import "server-only";
+import { headers } from "next/headers";
+import { getCoreRuntime } from "./runtime";
+
+export async function getAuth() {
+ return (await getCoreRuntime()).auth;
+}
+
+export async function getAuthSession() {
+ return (await getAuth()).api.getSession({ headers: await headers() });
+}
diff --git a/templates/nextjs-minimal/lib/blob.ts b/templates/nextjs-minimal/lib/blob.ts
new file mode 100644
index 000000000..4a7883040
--- /dev/null
+++ b/templates/nextjs-minimal/lib/blob.ts
@@ -0,0 +1,11 @@
+import "server-only";
+import { createLocalBlobStorage } from "@hackkit/blob-local";
+import { env } from "../env";
+let storage: ReturnType | undefined;
+export function getBlobStorage() {
+ return (storage ??= createLocalBlobStorage({
+ baseDir: env.localBlobBaseDir,
+ appBaseUrl: env.appUrl,
+ filesRoutePrefix: "/api/files",
+ }));
+}
diff --git a/templates/nextjs-minimal/lib/database-config.ts b/templates/nextjs-minimal/lib/database-config.ts
new file mode 100644
index 000000000..67b5d4f77
--- /dev/null
+++ b/templates/nextjs-minimal/lib/database-config.ts
@@ -0,0 +1,19 @@
+import { resolve } from "node:path";
+import { SqliteDriver } from "@mikro-orm/sqlite";
+import { env } from "../env";
+
+// Application commands and Next run from this template's directory.
+export const databaseOptions = {
+ driver: SqliteDriver,
+ dbName:
+ env.databaseUrl === ":memory:"
+ ? ":memory:"
+ : resolve(env.databaseUrl.replace(/^file:/, "")),
+ migrations: {
+ path: resolve(env.migrationsPath ?? "db/migrations/sqlite"),
+ emit: "ts" as const,
+ snapshot: true,
+ snapshotName: ".snapshot",
+ snapshotOnMigrate: false,
+ },
+};
diff --git a/templates/nextjs-minimal/lib/hackkit-ui-routes.ts b/templates/nextjs-minimal/lib/hackkit-ui-routes.ts
new file mode 100644
index 000000000..afca1c43b
--- /dev/null
+++ b/templates/nextjs-minimal/lib/hackkit-ui-routes.ts
@@ -0,0 +1,7 @@
+import { DEFAULT_HACKKIT_UI_ROUTES, type HackKitUIRoutes } from "@hackkit/ui";
+
+/**
+ * Single place for HackKit UI route policy in this HackKit Web App.
+ * Passed to HackKitUIProvider and buildCompetitorOnboardingSteps.
+ */
+export const hackKitUIRoutes: HackKitUIRoutes = DEFAULT_HACKKIT_UI_ROUTES;
diff --git a/templates/nextjs-minimal/lib/logger.ts b/templates/nextjs-minimal/lib/logger.ts
new file mode 100644
index 000000000..18b9b02c4
--- /dev/null
+++ b/templates/nextjs-minimal/lib/logger.ts
@@ -0,0 +1,11 @@
+import { createLogger, type HackKitLogger } from "@hackkit/core";
+import { appConfig } from "./app-config";
+
+let logger: HackKitLogger | null = null;
+
+export function getAppLogger(): HackKitLogger {
+ if (!logger) {
+ logger = createLogger(appConfig.logger);
+ }
+ return logger;
+}
diff --git a/templates/nextjs-minimal/lib/onboarding.ts b/templates/nextjs-minimal/lib/onboarding.ts
new file mode 100644
index 000000000..d876e88ff
--- /dev/null
+++ b/templates/nextjs-minimal/lib/onboarding.ts
@@ -0,0 +1,54 @@
+import "server-only";
+
+import {
+ buildCompetitorOnboardingSteps,
+ getNextOnboardingStepHref,
+ type CompetitorOnboardingStep,
+} from "@hackkit/ui";
+import { CoreSetting } from "@hackkit/core";
+import { hackKitUIRoutes } from "./hackkit-ui-routes";
+import { getCurrentUser, getHackkit, getRuntime } from "./runtime";
+
+async function loadCompetitorOnboardingInput(currentPath: string) {
+ const user = await getCurrentUser();
+ const hackkit = await getHackkit();
+ const runtime = await getRuntime();
+ const [userData, hacker, requireApproval] = await Promise.all([
+ hackkit.userData.getUserData(user.id),
+ hackkit.hackers.getHacker(user.id),
+ runtime.getSettingValue(CoreSetting.RequireApproval),
+ ]);
+ return {
+ user,
+ userData,
+ hacker,
+ requireApproval: Boolean(requireApproval),
+ currentPath,
+ routes: hackKitUIRoutes,
+ };
+}
+
+export async function getOnboardingSteps(
+ currentPath: string,
+): Promise {
+ const input = await loadCompetitorOnboardingInput(currentPath);
+ return buildCompetitorOnboardingSteps(input);
+}
+
+export async function getCompetitorOnboardingState(currentPath: string) {
+ const input = await loadCompetitorOnboardingInput(currentPath);
+ const steps = buildCompetitorOnboardingSteps(input);
+ return {
+ steps,
+ nextHref: getNextOnboardingStepHref(steps),
+ user: input.user,
+ userData: input.userData,
+ hacker: input.hacker,
+ };
+}
+
+export async function getRequireApproval(): Promise {
+ return Boolean(
+ await (await getRuntime()).getSettingValue(CoreSetting.RequireApproval),
+ );
+}
diff --git a/templates/nextjs-minimal/lib/public-site-config.ts b/templates/nextjs-minimal/lib/public-site-config.ts
new file mode 100644
index 000000000..1d7f368e2
--- /dev/null
+++ b/templates/nextjs-minimal/lib/public-site-config.ts
@@ -0,0 +1,122 @@
+import type { CSSProperties } from "react";
+import type {
+ PublicLandingPageProps,
+ PublicShellLink,
+ PublicSiteFooterGroup,
+} from "@hackkit/ui";
+
+export type PublicSiteConfig = {
+ brand: {
+ name: string;
+ shortName: string;
+ description: string;
+ };
+ event: {
+ name: string;
+ dates: string;
+ location: string;
+ timezone: string;
+ };
+ theme: {
+ primary: string;
+ ring: string;
+ };
+ nav: {
+ public: PublicShellLink[];
+ participant: PublicShellLink[];
+ };
+ landing: Omit<
+ PublicLandingPageProps,
+ "primaryAction" | "secondaryAction"
+ > & {
+ primaryAction: PublicShellLink;
+ secondaryAction: PublicShellLink;
+ signedInAction: PublicShellLink;
+ };
+ help: {
+ title: string;
+ description: string;
+ contacts: PublicShellLink[];
+ resources: PublicShellLink[];
+ };
+ dashboard: {
+ primaryActions: PublicShellLink[];
+ resourceLinks: PublicShellLink[];
+ };
+ footer: {
+ linkGroups: PublicSiteFooterGroup[];
+ };
+};
+
+export const publicSiteConfig = {
+ brand: {
+ name: "HackKit",
+ shortName: "HackKit",
+ description: "Hackathon registration and participant management.",
+ },
+ event: {
+ name: "Your hackathon",
+ dates: "Dates to be announced",
+ location: "Location to be announced",
+ timezone: "America/Chicago",
+ },
+ theme: { primary: "221.2 83.2% 53.3%", ring: "221.2 83.2% 53.3%" },
+ nav: {
+ public: [{ label: "Help", href: "/help" }],
+ participant: [
+ { label: "Dashboard", href: "/dashboard" },
+ { label: "Settings", href: "/settings" },
+ ],
+ },
+ landing: {
+ eyebrow: "HackKit",
+ title: "Register for your next hackathon.",
+ description:
+ "Create an account, complete registration, and manage your participant profile.",
+ primaryAction: { label: "Apply now", href: "/sign-up" },
+ secondaryAction: { label: "Get help", href: "/help" },
+ signedInAction: { label: "Open dashboard", href: "/dashboard" },
+ highlights: [],
+ sections: [],
+ stats: [],
+ },
+ help: {
+ title: "Contact and help",
+ description: "Contact the organizing team for registration help.",
+ contacts: [
+ {
+ label: "Organizer support",
+ href: "mailto:organizers@example.com",
+ },
+ ],
+ resources: [
+ { label: "Dashboard", href: "/dashboard" },
+ { label: "Registration", href: "/settings/registration" },
+ ],
+ },
+ dashboard: {
+ primaryActions: [
+ { label: "Edit registration", href: "/settings/registration" },
+ { label: "Profile settings", href: "/settings" },
+ ],
+ resourceLinks: [{ label: "Help", href: "/help" }],
+ },
+ footer: {
+ linkGroups: [
+ {
+ title: "HackKit",
+ links: [
+ { label: "Help", href: "/help" },
+ { label: "Apply", href: "/sign-up" },
+ { label: "Dashboard", href: "/dashboard" },
+ ],
+ },
+ ],
+ },
+} satisfies PublicSiteConfig;
+export function getPublicThemeStyle(): CSSProperties {
+ return {
+ "--primary": publicSiteConfig.theme.primary,
+ "--ring": publicSiteConfig.theme.ring,
+ } as CSSProperties;
+}
diff --git a/templates/nextjs-minimal/lib/runtime.ts b/templates/nextjs-minimal/lib/runtime.ts
new file mode 100644
index 000000000..27d87c0df
--- /dev/null
+++ b/templates/nextjs-minimal/lib/runtime.ts
@@ -0,0 +1,35 @@
+import "server-only";
+
+import {
+ createHackkitRuntimeFromConfig,
+ setHackkitRuntime,
+} from "@hackkit/next";
+import { appConfig } from "./app-config";
+
+const host = createHackkitRuntimeFromConfig({
+ config: appConfig,
+});
+
+setHackkitRuntime(host.getRuntime);
+
+export async function getRuntime() {
+ return host.getRuntime();
+}
+
+export async function getCurrentUser() {
+ return (await getRuntime()).getCurrentUser();
+}
+
+export async function getHackkit() {
+ return (await getRuntime()).hackkit;
+}
+
+export async function getPageGuards() {
+ return (await getRuntime()).pageGuards;
+}
+
+export function getCoreRuntime() {
+ return host.core;
+}
+
+export const handleHackkitRequest = host.handler;
diff --git a/templates/nextjs-minimal/lib/upload-profile-photo.ts b/templates/nextjs-minimal/lib/upload-profile-photo.ts
new file mode 100644
index 000000000..2c6b14b87
--- /dev/null
+++ b/templates/nextjs-minimal/lib/upload-profile-photo.ts
@@ -0,0 +1,34 @@
+export async function uploadProfilePhotoFile(file: File): Promise {
+ const registerResponse = await fetch("/api/files/register", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ location: "profile-photos",
+ fileName: file.name,
+ }),
+ });
+
+ if (!registerResponse.ok) {
+ throw new Error("Could not prepare profile photo upload.");
+ }
+
+ const { uploadUrl, storedFileReference } =
+ (await registerResponse.json()) as {
+ uploadUrl: string;
+ storedFileReference: string;
+ };
+
+ const uploadResponse = await fetch(uploadUrl, {
+ method: "PUT",
+ body: file,
+ headers: {
+ "Content-Type": file.type || "application/octet-stream",
+ },
+ });
+
+ if (!uploadResponse.ok) {
+ throw new Error("Could not upload profile photo.");
+ }
+
+ return storedFileReference;
+}
diff --git a/templates/nextjs-minimal/lib/upload-resume.ts b/templates/nextjs-minimal/lib/upload-resume.ts
new file mode 100644
index 000000000..d8767b1ec
--- /dev/null
+++ b/templates/nextjs-minimal/lib/upload-resume.ts
@@ -0,0 +1,59 @@
+async function responseError(
+ response: Response,
+ fallback: string,
+): Promise {
+ try {
+ const body = (await response.json()) as { error?: string };
+ if (body.error) return new Error(body.error);
+ } catch {
+ // Use the actionable fallback when the server did not return JSON.
+ }
+ return new Error(fallback);
+}
+
+export async function uploadResumeFile(file: File): Promise {
+ if (file.type && file.type !== "application/pdf") {
+ throw new Error(
+ "Choose a PDF resume before submitting your registration.",
+ );
+ }
+
+ const registerResponse = await fetch("/api/files/register", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ location: "resumes",
+ fileName: file.name,
+ }),
+ });
+
+ if (!registerResponse.ok) {
+ throw await responseError(
+ registerResponse,
+ "Could not prepare your resume upload. Please sign in again and retry.",
+ );
+ }
+
+ const { uploadUrl, storedFileReference } =
+ (await registerResponse.json()) as {
+ uploadUrl: string;
+ storedFileReference: string;
+ };
+
+ const uploadResponse = await fetch(uploadUrl, {
+ method: "PUT",
+ body: file,
+ headers: {
+ "Content-Type": file.type || "application/pdf",
+ },
+ });
+
+ if (!uploadResponse.ok) {
+ throw await responseError(
+ uploadResponse,
+ "Could not upload your resume. Check your connection and retry.",
+ );
+ }
+
+ return storedFileReference;
+}
diff --git a/templates/nextjs-minimal/middleware.ts b/templates/nextjs-minimal/middleware.ts
new file mode 100644
index 000000000..b95da4afd
--- /dev/null
+++ b/templates/nextjs-minimal/middleware.ts
@@ -0,0 +1,68 @@
+import { NextResponse, type NextRequest } from "next/server";
+
+const AUTH_ROUTE_PATHS = new Set(["/sign-in", "/sign-up"]);
+const PUBLIC_ROUTE_PATHS = new Set([
+ "/",
+ "/favicon.ico",
+ "/registration-closed",
+ "/suspended",
+]);
+const PUBLIC_ROUTE_PREFIXES = ["/api/", "/i/approval", "/user/"];
+const PROTECTED_ROUTE_PREFIXES = [
+ "/admin",
+ "/dashboard",
+ "/onboarding",
+ "/register",
+ "/settings",
+];
+
+function hasAuthSessionCookie(request: NextRequest): boolean {
+ return request.cookies
+ .getAll()
+ .some((cookie) => cookie.name.includes("better-auth.session_token"));
+}
+
+function isPublicRoute(pathname: string): boolean {
+ return (
+ PUBLIC_ROUTE_PATHS.has(pathname) ||
+ AUTH_ROUTE_PATHS.has(pathname) ||
+ PUBLIC_ROUTE_PREFIXES.some((prefix) => pathname.startsWith(prefix))
+ );
+}
+
+function isProtectedRoute(pathname: string): boolean {
+ return PROTECTED_ROUTE_PREFIXES.some(
+ (prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`),
+ );
+}
+
+export function middleware(request: NextRequest) {
+ const { pathname } = request.nextUrl;
+ const hasSession = hasAuthSessionCookie(request);
+
+ if (pathname.startsWith("/@")) {
+ const tag = pathname.slice(2).split("/")[0];
+ if (tag) {
+ return NextResponse.rewrite(new URL(`/user/${tag}`, request.url));
+ }
+ }
+
+ if (AUTH_ROUTE_PATHS.has(pathname) && hasSession) {
+ return NextResponse.redirect(new URL("/", request.url));
+ }
+
+ if (!hasSession && isProtectedRoute(pathname) && !isPublicRoute(pathname)) {
+ const signInUrl = new URL("/sign-in", request.url);
+ signInUrl.searchParams.set(
+ "next",
+ `${pathname}${request.nextUrl.search}`,
+ );
+ return NextResponse.redirect(signInUrl);
+ }
+
+ return NextResponse.next();
+}
+
+export const config = {
+ matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\..*).*)"],
+};
diff --git a/templates/nextjs-minimal/next-env.d.ts b/templates/nextjs-minimal/next-env.d.ts
new file mode 100644
index 000000000..40c3d6809
--- /dev/null
+++ b/templates/nextjs-minimal/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
diff --git a/templates/nextjs-minimal/next.config.mjs b/templates/nextjs-minimal/next.config.mjs
new file mode 100644
index 000000000..29986317f
--- /dev/null
+++ b/templates/nextjs-minimal/next.config.mjs
@@ -0,0 +1,20 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ experimental: {
+ // SQL drivers load native modules and must execute through Node.
+ serverComponentsExternalPackages: [
+ "@hackkit/core",
+ "@mikro-orm/core",
+ "@mikro-orm/sql",
+ "@mikro-orm/sqlite",
+ "@mikro-orm/libsql",
+ "@mikro-orm/mysql",
+ "@mikro-orm/postgresql",
+ "@mikro-orm/migrations",
+ "@a77ay/better-auth-mikro-orm",
+ ],
+ },
+ transpilePackages: ["@hackkit/ui", "@hackkit/next"],
+};
+
+export default nextConfig;
diff --git a/templates/nextjs-minimal/package.json b/templates/nextjs-minimal/package.json
new file mode 100644
index 000000000..cad6293be
--- /dev/null
+++ b/templates/nextjs-minimal/package.json
@@ -0,0 +1,50 @@
+{
+ "name": "@hackkit/template-nextjs-minimal",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "plugin:sync": "hackkit plugin sync",
+ "db:generate": "node scripts/db.mjs generate",
+ "db:migrate": "node scripts/db.mjs migrate",
+ "db:seed": "node scripts/db.mjs seed",
+ "db:reset": "node scripts/db.mjs reset",
+ "sync": "pnpm plugin:sync",
+ "dev": "next dev -p 3000",
+ "build": "next build",
+ "verify": "pnpm sync && pnpm typecheck && pnpm build",
+ "start": "next start",
+ "typecheck": "tsc -p tsconfig.json --noEmit",
+ "db:status": "node scripts/db.mjs status",
+ "db:check": "node scripts/db.mjs check",
+ "db:rollback": "node scripts/db.mjs rollback"
+ },
+ "dependencies": {
+ "@hackkit/blob-local": "workspace:*",
+ "@hackkit/cli": "workspace:*",
+ "@hackkit/config": "workspace:*",
+ "@hackkit/core": "workspace:*",
+ "@hackkit/next": "workspace:*",
+ "@hackkit/ui": "workspace:*",
+ "better-auth": "1.7.6",
+ "next": "14.2.35",
+ "react": "18.3.1",
+ "react-dom": "18.3.1",
+ "sonner": "^1.5.0",
+ "typescript": "5.9.3",
+ "@mikro-orm/sqlite": "7.2.1",
+ "@mikro-orm/migrations": "7.2.1",
+ "@mikro-orm/core": "7.2.1",
+ "jiti": "2.4.2",
+ "@next/env": "14.2.35"
+ },
+ "devDependencies": {
+ "@types/node": "22.18.6",
+ "@types/react": "18.3.3",
+ "@types/react-dom": "18.3.0",
+ "autoprefixer": "10.4.19",
+ "postcss": "8.4.39",
+ "tailwindcss": "3.4.6",
+ "tailwindcss-animate": "1.0.7"
+ }
+}
diff --git a/templates/nextjs-minimal/postcss.config.cjs b/templates/nextjs-minimal/postcss.config.cjs
new file mode 100644
index 000000000..e873f1a4f
--- /dev/null
+++ b/templates/nextjs-minimal/postcss.config.cjs
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/templates/nextjs-minimal/scripts/database.ts b/templates/nextjs-minimal/scripts/database.ts
new file mode 100644
index 000000000..54e692d76
--- /dev/null
+++ b/templates/nextjs-minimal/scripts/database.ts
@@ -0,0 +1,146 @@
+import { mkdir } from "node:fs/promises";
+import { dirname } from "node:path";
+import { resolveHackkitConfig, type HackkitConfig } from "@hackkit/config";
+import { createOrmOptions, seedRoles } from "@hackkit/core";
+import { MikroORM } from "@mikro-orm/core";
+import { SqliteDriver } from "@mikro-orm/sqlite";
+import { createJiti } from "jiti";
+
+const jiti = createJiti(import.meta.url);
+
+export type DatabaseCommand =
+ | { command: "generate"; name?: string; blank?: boolean }
+ | { command: "status" | "check" | "seed" | "reset" }
+ | { command: "migrate"; to?: string }
+ | { command: "rollback"; to?: string };
+
+/** Runs an explicit database operation. App startup never calls this function. */
+export async function runDatabaseCommand(
+ input: HackkitConfig,
+ request: DatabaseCommand,
+) {
+ const config = resolveHackkitConfig(input);
+ if (request.command === "reset") {
+ if (
+ !["development", "test"].includes(
+ process.env.NODE_ENV ?? "development",
+ )
+ ) {
+ throw new Error(
+ "db:reset is only available in development or tests.",
+ );
+ }
+ if (
+ config.database.driver !== SqliteDriver ||
+ !config.database.dbName
+ ) {
+ throw new Error("db:reset requires a local SQLite database.");
+ }
+ if (
+ /^[a-z][a-z\d+.-]*:/i.test(config.database.dbName) &&
+ config.database.dbName !== ":memory:"
+ ) {
+ throw new Error("db:reset requires a local SQLite path.");
+ }
+ }
+ if (
+ config.database.driver === SqliteDriver &&
+ config.database.dbName !== ":memory:" &&
+ config.database.dbName
+ ) {
+ await mkdir(dirname(config.database.dbName), { recursive: true });
+ }
+ const orm = await MikroORM.init({
+ ...createOrmOptions(config),
+ dynamicImportProvider: (id) => jiti.import(id),
+ });
+ try {
+ // MikroORM 7 initializes lazily. History operations must establish a
+ // connection first: native getPending can otherwise report all files
+ // as pending when a snapshot exists but the database is unreachable.
+ if (request.command !== "generate") await orm.connect();
+ const migrator = orm.migrator;
+ switch (request.command) {
+ case "generate": {
+ const migration = await migrator.create(
+ undefined,
+ request.blank,
+ false,
+ request.name,
+ );
+ return {
+ command: "generate" as const,
+ migration,
+ // SQLite table rebuilding also contains DROP TABLE. Review the
+ // complete migration; this list is a warning, not an SQL parser.
+ destructiveStatements: migration.diff.up.filter((sql) =>
+ /\bdrop\s+(?:table|column|schema)\b|\btruncate\b/i.test(
+ sql,
+ ),
+ ),
+ };
+ }
+ case "status":
+ case "check": {
+ // Native migrator history calls ensure its tracking table exists.
+ const executed = await migrator.getExecuted();
+ const pending = await migrator.getPending();
+ if (request.command === "status")
+ return { command: "status" as const, executed, pending };
+ // checkSchema compares entities to the committed snapshot. Separately
+ // compare the live database so a clean snapshot cannot hide drift.
+ const needsMigration = await migrator.checkSchema();
+ const schemaSql = await orm.schema.getUpdateSchemaSQL({
+ wrap: false,
+ });
+ return {
+ command: "check" as const,
+ executed,
+ pending,
+ needsMigration,
+ schemaSql,
+ ok:
+ !needsMigration &&
+ pending.length === 0 &&
+ schemaSql.trim() === "",
+ };
+ }
+ case "migrate":
+ return {
+ command: "migrate" as const,
+ migrations: await migrator.up(
+ request.to ? { to: request.to } : undefined,
+ ),
+ };
+ case "rollback":
+ return {
+ command: "rollback" as const,
+ migrations: await migrator.down(
+ request.to
+ ? { to: request.to === "0" ? 0 : request.to }
+ : undefined,
+ ),
+ };
+ case "reset":
+ await orm.schema.drop({ dropMigrationsTable: true });
+ await migrator.up();
+ return {
+ command: "reset" as const,
+ seed: await seedRoles({
+ em: orm.em.fork(),
+ roles: config.seedRoles,
+ }),
+ };
+ case "seed":
+ return {
+ command: "seed" as const,
+ seed: await seedRoles({
+ em: orm.em.fork(),
+ roles: config.seedRoles,
+ }),
+ };
+ }
+ } finally {
+ await orm.close();
+ }
+}
diff --git a/templates/nextjs-minimal/scripts/db.mjs b/templates/nextjs-minimal/scripts/db.mjs
new file mode 100644
index 000000000..ea42a00ac
--- /dev/null
+++ b/templates/nextjs-minimal/scripts/db.mjs
@@ -0,0 +1,66 @@
+import { parseArgs } from "node:util";
+import { writeFile } from "node:fs/promises";
+import { fileURLToPath } from "node:url";
+import { createJiti } from "jiti";
+import nextEnv from "@next/env";
+import { loadHackkitConfig } from "@hackkit/config";
+
+// Match Next's environment loading before evaluating hackkit.config.ts.
+nextEnv.loadEnvConfig(
+ process.cwd(),
+ process.env.NODE_ENV !== "production",
+ console,
+ true,
+);
+const jiti = createJiti(fileURLToPath(import.meta.url));
+const { runDatabaseCommand } = await jiti.import("./database.ts");
+
+try {
+ const { values, positionals } = parseArgs({
+ allowPositionals: true,
+ options: {
+ config: { type: "string", default: "hackkit.config.ts" },
+ output: { type: "string" },
+ name: { type: "string" },
+ blank: { type: "boolean", default: false },
+ to: { type: "string" },
+ },
+ });
+ const [command] = positionals;
+ const commands = [
+ "generate",
+ "status",
+ "check",
+ "migrate",
+ "rollback",
+ "reset",
+ "seed",
+ ];
+ if (positionals.length !== 1 || !commands.includes(command)) {
+ throw new Error(`Choose a database command: ${commands.join(", ")}.`);
+ }
+ if ((values.name !== undefined || values.blank) && command !== "generate") {
+ throw new Error("--name and --blank are only supported by generate.");
+ }
+ if (values.to !== undefined && !["migrate", "rollback"].includes(command)) {
+ throw new Error("--to is only supported by migrate and rollback.");
+ }
+ if (values.to !== undefined && !values.to.trim()) {
+ throw new Error("--to requires a migration name (or 0 for rollback).");
+ }
+ const config = await loadHackkitConfig(values.config);
+ const result = await runDatabaseCommand(config, { command, ...values });
+ // Native drivers can write diagnostics to stdout. A separate result file
+ // gives release jobs structured output without parsing their logs.
+ if (values.output) {
+ await writeFile(values.output, `${JSON.stringify(result, null, 2)}\n`);
+ }
+ console.log(JSON.stringify(result, null, 2));
+ if (result.command === "check" && !result.ok) process.exitCode = 1;
+} catch (error) {
+ // Print the operation's error without printing the config or connection URL.
+ console.error(
+ error instanceof Error ? error.message : "Database command failed.",
+ );
+ process.exitCode = 1;
+}
diff --git a/apps/web/tailwind.config.ts b/templates/nextjs-minimal/tailwind.config.ts
similarity index 100%
rename from apps/web/tailwind.config.ts
rename to templates/nextjs-minimal/tailwind.config.ts
diff --git a/templates/nextjs-minimal/tsconfig.json b/templates/nextjs-minimal/tsconfig.json
new file mode 100644
index 000000000..9fbd168e5
--- /dev/null
+++ b/templates/nextjs-minimal/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [{ "name": "next" }],
+ "paths": {
+ "@/*": ["./*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/tooling/check-client-bundle.mjs b/tooling/check-client-bundle.mjs
index 83cc3c0e7..3f459a734 100644
--- a/tooling/check-client-bundle.mjs
+++ b/tooling/check-client-bundle.mjs
@@ -1,34 +1,40 @@
import assert from "node:assert/strict";
import { createRequire } from "node:module";
import { resolve } from "node:path";
-const require = createRequire(resolve("packages/core/package.json"));
-const vitestRequire = createRequire(require.resolve("vitest"));
-const { build } = createRequire(vitestRequire.resolve("vite"))("esbuild");
-const result = await build({
- entryPoints: ["apps/web/app/providers.tsx"],
- bundle: true,
- platform: "browser",
- format: "esm",
- minify: true,
- write: false,
- metafile: true,
- logLevel: "silent",
-});
-const files = Object.keys(result.metafile.inputs);
-const forbidden = files.filter((file) =>
- /(?:@mikro-orm|better-auth|\/core\/(?:src|dist)\/(?:mikro|models|hackkit|plugins)|\/(?:endpoints|api|http-server|handler)\.js$)/.test(
- file,
- ),
-);
-assert.deepEqual(
- forbidden,
- [],
- "Server implementations entered the browser client bundle.",
-);
-console.log(
- JSON.stringify({
- browserBundleBytes: result.outputFiles[0].contents.length,
- modules: files.length,
- serverModules: forbidden.length,
- }),
-);
+const require = createRequire(resolve("e2e/package.json"));
+const { build } = require("esbuild");
+for (const template of [
+ "templates/nextjs-full",
+ "templates/nextjs-minimal",
+ "apps/demo",
+]) {
+ const result = await build({
+ entryPoints: [`${template}/app/providers.tsx`],
+ bundle: true,
+ platform: "browser",
+ format: "esm",
+ minify: true,
+ write: false,
+ metafile: true,
+ logLevel: "silent",
+ });
+ const files = Object.keys(result.metafile.inputs);
+ const forbidden = files.filter((file) =>
+ /(?:@mikro-orm|better-auth|\/core\/(?:src|dist)\/(?:mikro|models|hackkit|plugins)|\/(?:endpoints|api|http-server|handler)\.js$)/.test(
+ file,
+ ),
+ );
+ assert.deepEqual(
+ forbidden,
+ [],
+ "Server implementations entered the browser client bundle.",
+ );
+ console.log(
+ JSON.stringify({
+ template,
+ browserBundleBytes: result.outputFiles[0].contents.length,
+ modules: files.length,
+ serverModules: forbidden.length,
+ }),
+ );
+}
diff --git a/turbo.json b/turbo.json
index 3e4c602db..d4dfbfaab 100644
--- a/turbo.json
+++ b/turbo.json
@@ -1,86 +1,124 @@
{
- "$schema": "https://turbo.build/schema.json",
- "globalDependencies": ["**/.env.*local"],
- "globalEnv": [
- "AWS_ACCESS_KEY_ID",
- "AWS_REGION",
- "AWS_S3_BUCKET",
- "AWS_S3_ENDPOINT",
- "AWS_S3_REGION",
- "AWS_SECRET_ACCESS_KEY",
- "AWS_SES_ACCESS_KEY",
- "AWS_SES_EMAIL_FROM",
- "AWS_SES_SECRET_ACCESS_KEY",
- "BACKUP_CRON_SCHEDULE",
- "BACKUP_DATABASE_URL",
- "BETTER_AUTH_SECRET",
- "BETTER_AUTH_TRUSTED_ORIGINS",
- "BETTER_AUTH_URL",
- "BOT_API_URL",
- "CLERK_SECRET_KEY",
- "DATABASE_URL",
- "DISCORD_CLIENT_ID",
- "DISCORD_DEV_SERVER_ID",
- "DISCORD_DEV_VERIFY_CHANNEL_ID",
- "DISCORD_PROD_SERVER_ID",
- "DISCORD_PROD_VERIFY_CHANNEL_ID",
- "DISCORD_SECRET_TOKEN",
- "NODE_ENV",
- "INTERNAL_AUTH_KEY",
- "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY",
- "NEXT_PUBLIC_CLERK_SIGN_IN_URL",
- "NEXT_PUBLIC_CLERK_SIGN_UP_URL",
- "NEXT_PUBLIC_APP_URL",
- "GITHUB_CLIENT_ID",
- "GITHUB_CLIENT_SECRET",
- "GOOGLE_CLIENT_ID",
- "GOOGLE_CLIENT_SECRET",
- "HACKKIT_BLOB_ADAPTER",
- "HACKKIT_EMAIL_FROM",
- "HACKKIT_EMAIL_PROVIDER",
- "HACKKIT_EMAIL_REPLY_TO",
- "HACKKIT_LOCAL_BLOB_BASE_DIR",
- "HACKKIT_S3_ACCESS_KEY_ID",
- "HACKKIT_S3_BUCKET",
- "HACKKIT_S3_ENDPOINT",
- "HACKKIT_S3_REGION",
- "HACKKIT_S3_SECRET_ACCESS_KEY",
- "S3_ACCESS_KEY_ID",
- "S3_BUCKET",
- "S3_ENDPOINT",
- "S3_REGION",
- "S3_SECRET_ACCESS_KEY",
- "RESEND_API_KEY",
- "SMTP_HOST",
- "SMTP_PASSWORD",
- "SMTP_PORT",
- "SMTP_SECURE",
- "SMTP_USERNAME",
- "UPSTASH_REDIS_REST_TOKEN",
- "UPSTASH_REDIS_REST_URL",
- "TURSO_AUTH_TOKEN",
- "TURSO_DATABASE_URL"
+ "$schema": "https://turbo.build/schema.json",
+ "globalDependencies": [
+ "**/.env.*local"
+ ],
+ "globalEnv": [
+ "AWS_ACCESS_KEY_ID",
+ "AWS_REGION",
+ "AWS_S3_BUCKET",
+ "AWS_S3_ENDPOINT",
+ "AWS_S3_REGION",
+ "AWS_SECRET_ACCESS_KEY",
+ "AWS_SES_ACCESS_KEY",
+ "AWS_SES_EMAIL_FROM",
+ "AWS_SES_SECRET_ACCESS_KEY",
+ "BACKUP_CRON_SCHEDULE",
+ "BACKUP_DATABASE_URL",
+ "BETTER_AUTH_SECRET",
+ "BETTER_AUTH_TRUSTED_ORIGINS",
+ "BETTER_AUTH_URL",
+ "BOT_API_URL",
+ "CLERK_SECRET_KEY",
+ "DATABASE_URL",
+ "DISCORD_CLIENT_ID",
+ "DISCORD_DEV_SERVER_ID",
+ "DISCORD_DEV_VERIFY_CHANNEL_ID",
+ "DISCORD_PROD_SERVER_ID",
+ "DISCORD_PROD_VERIFY_CHANNEL_ID",
+ "DISCORD_SECRET_TOKEN",
+ "NODE_ENV",
+ "INTERNAL_AUTH_KEY",
+ "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY",
+ "NEXT_PUBLIC_CLERK_SIGN_IN_URL",
+ "NEXT_PUBLIC_CLERK_SIGN_UP_URL",
+ "NEXT_PUBLIC_APP_URL",
+ "GITHUB_CLIENT_ID",
+ "GITHUB_CLIENT_SECRET",
+ "GOOGLE_CLIENT_ID",
+ "GOOGLE_CLIENT_SECRET",
+ "HACKKIT_BLOB_ADAPTER",
+ "HACKKIT_EMAIL_FROM",
+ "HACKKIT_EMAIL_PROVIDER",
+ "HACKKIT_EMAIL_REPLY_TO",
+ "HACKKIT_LOCAL_BLOB_BASE_DIR",
+ "HACKKIT_MIGRATIONS_PATH",
+ "HACKKIT_S3_ACCESS_KEY_ID",
+ "HACKKIT_S3_BUCKET",
+ "HACKKIT_S3_ENDPOINT",
+ "HACKKIT_S3_REGION",
+ "HACKKIT_S3_SECRET_ACCESS_KEY",
+ "S3_ACCESS_KEY_ID",
+ "S3_BUCKET",
+ "S3_ENDPOINT",
+ "S3_REGION",
+ "S3_SECRET_ACCESS_KEY",
+ "RESEND_API_KEY",
+ "SMTP_HOST",
+ "SMTP_PASSWORD",
+ "SMTP_PORT",
+ "SMTP_SECURE",
+ "SMTP_USERNAME",
+ "UPSTASH_REDIS_REST_TOKEN",
+ "UPSTASH_REDIS_REST_URL",
+ "TURSO_AUTH_TOKEN",
+ "TURSO_DATABASE_URL"
+ ],
+ "tasks": {
+ "build": {
+ "dependsOn": [
+ "^build"
],
- "tasks": {
- "build": {
- "dependsOn": ["^build"],
- "outputs": ["dist/**", ".next/**", "!.next/cache/**"],
- "cache": true
- },
- "test": {
- "cache": true,
- "dependsOn": ["^build"]
- },
- "lint": {},
- "start": {
- "cache": false,
- "persistent": true,
- "dependsOn": ["^build"]
- },
- "dev": {
- "dependsOn": ["^build"],
- "cache": false,
- "persistent": true
- }
- }
+ "outputs": [
+ "dist/**",
+ ".next/**",
+ "!.next/cache/**",
+ "out/**",
+ "!dist/**/.dev.vars*",
+ "!dist/**/.env*"
+ ],
+ "cache": true
+ },
+ "test": {
+ "cache": true,
+ "dependsOn": [
+ "^build"
+ ]
+ },
+ "lint": {},
+ "start": {
+ "cache": false,
+ "persistent": true,
+ "dependsOn": [
+ "^build"
+ ]
+ },
+ "dev": {
+ "dependsOn": [
+ "^build"
+ ],
+ "cache": false,
+ "persistent": true
+ },
+ "typecheck": {
+ "dependsOn": [
+ "^build"
+ ],
+ "outputs": []
+ },
+ "@hackkit/e2e#test": {
+ "cache": false
+ },
+ "@hackkit/demo#build": {
+ "dependsOn": [
+ "^build"
+ ],
+ "outputs": [
+ "dist/**",
+ "!dist/**/.dev.vars*",
+ "!dist/**/.env*"
+ ],
+ "cache": false
+ }
+ }
}