webpage start

This commit is contained in:
2026-03-02 14:47:14 +01:00
parent 0856e154b9
commit 65d5ab71d7
59 changed files with 1889 additions and 1309 deletions

View File

@@ -1,18 +1,18 @@
{ {
"mcpServers": { "mcpServers": {
"context7": { "context7": {
"command": "npx", "command": "npx",
"args": ["-y", "@upstash/context7-mcp"] "args": ["-y", "@upstash/context7-mcp"]
}, },
"cloudflare-docs": { "cloudflare-docs": {
"url": "https://docs.mcp.cloudflare.com/sse" "url": "https://docs.mcp.cloudflare.com/sse"
}, },
"shadcn": { "shadcn": {
"command": "npx", "command": "npx",
"args": ["-y", "shadcn@latest", "mcp"] "args": ["-y", "shadcn@latest", "mcp"]
}, },
"better-auth": { "better-auth": {
"url": "https://mcp.inkeep.com/better-auth/mcp" "url": "https://mcp.inkeep.com/better-auth/mcp"
} }
} }
} }

View File

@@ -1,20 +1,20 @@
{ {
"mcpServers": { "mcpServers": {
"context7": { "context7": {
"command": "npx", "command": "npx",
"args": ["-y", "@upstash/context7-mcp"] "args": ["-y", "@upstash/context7-mcp"]
}, },
"cloudflare-docs": { "cloudflare-docs": {
"type": "sse", "type": "sse",
"url": "https://docs.mcp.cloudflare.com/sse" "url": "https://docs.mcp.cloudflare.com/sse"
}, },
"shadcn": { "shadcn": {
"command": "npx", "command": "npx",
"args": ["-y", "shadcn@latest", "mcp"] "args": ["-y", "shadcn@latest", "mcp"]
}, },
"better-auth": { "better-auth": {
"type": "http", "type": "http",
"url": "https://mcp.inkeep.com/better-auth/mcp" "url": "https://mcp.inkeep.com/better-auth/mcp"
} }
} }
} }

View File

@@ -1,24 +1,24 @@
{ {
"$schema": "https://ui.shadcn.com/schema.json", "$schema": "https://ui.shadcn.com/schema.json",
"style": "base-lyra", "style": "base-lyra",
"rsc": false, "rsc": false,
"tsx": true, "tsx": true,
"tailwind": { "tailwind": {
"config": "", "config": "",
"css": "src/index.css", "css": "src/index.css",
"baseColor": "neutral", "baseColor": "neutral",
"cssVariables": true, "cssVariables": true,
"prefix": "" "prefix": ""
}, },
"iconLibrary": "lucide", "iconLibrary": "lucide",
"aliases": { "aliases": {
"components": "@/components", "components": "@/components",
"utils": "@/lib/utils", "utils": "@/lib/utils",
"ui": "@/components/ui", "ui": "@/components/ui",
"lib": "@/lib", "lib": "@/lib",
"hooks": "@/hooks" "hooks": "@/hooks"
}, },
"menuColor": "default", "menuColor": "default",
"menuAccent": "subtle", "menuAccent": "subtle",
"registries": {} "registries": {}
} }

View File

@@ -1,62 +1,66 @@
{ {
"name": "web", "name": "web",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "vite build", "build": "vite build",
"serve": "vite preview", "serve": "vite preview",
"dev:bare": "vite dev" "dev:bare": "vite dev"
}, },
"dependencies": { "dependencies": {
"@base-ui/react": "^1.0.0", "@base-ui/react": "^1.0.0",
"@kk/api": "workspace:*", "@kk/api": "workspace:*",
"@kk/auth": "workspace:*", "@kk/auth": "workspace:*",
"@kk/env": "workspace:*", "@kk/env": "workspace:*",
"@libsql/client": "catalog:", "@libsql/client": "catalog:",
"@orpc/client": "catalog:", "@orpc/client": "catalog:",
"@orpc/openapi": "catalog:", "@orpc/openapi": "catalog:",
"@orpc/server": "catalog:", "@orpc/server": "catalog:",
"@orpc/tanstack-query": "^1.12.2", "@orpc/tanstack-query": "^1.12.2",
"@orpc/zod": "catalog:", "@orpc/zod": "catalog:",
"@tailwindcss/vite": "^4.1.8", "@react-three/drei": "^10.7.7",
"@tanstack/react-form": "^1.28.0", "@react-three/fiber": "^9.5.0",
"@tanstack/react-query": "^5.80.6", "@tailwindcss/vite": "^4.1.8",
"@tanstack/react-router": "^1.141.1", "@tanstack/react-form": "^1.28.0",
"@tanstack/react-router-with-query": "^1.130.17", "@tanstack/react-query": "^5.80.6",
"@tanstack/react-start": "^1.141.1", "@tanstack/react-router": "^1.141.1",
"@tanstack/router-plugin": "^1.141.1", "@tanstack/react-router-with-query": "^1.130.17",
"better-auth": "catalog:", "@tanstack/react-start": "^1.141.1",
"class-variance-authority": "^0.7.1", "@tanstack/router-plugin": "^1.141.1",
"clsx": "^2.1.1", "better-auth": "catalog:",
"dotenv": "catalog:", "class-variance-authority": "^0.7.1",
"libsql": "catalog:", "clsx": "^2.1.1",
"lucide-react": "^0.525.0", "dotenv": "catalog:",
"next-themes": "^0.4.6", "libsql": "catalog:",
"react": "19.2.3", "lucide-react": "^0.525.0",
"react-dom": "19.2.3", "next-themes": "^0.4.6",
"shadcn": "^3.6.2", "react": "19.2.3",
"sonner": "^2.0.3", "react-dom": "19.2.3",
"tailwind-merge": "^3.3.1", "shadcn": "^3.6.2",
"tailwindcss": "^4.1.3", "sonner": "^2.0.3",
"tw-animate-css": "^1.2.5", "tailwind-merge": "^3.3.1",
"vite-tsconfig-paths": "^5.1.4", "tailwindcss": "^4.1.3",
"zod": "catalog:" "three": "^0.183.1",
}, "tw-animate-css": "^1.2.5",
"devDependencies": { "vite-tsconfig-paths": "^5.1.4",
"@cloudflare/vite-plugin": "^1.17.1", "zod": "catalog:"
"@kk/config": "workspace:*", },
"@tanstack/react-query-devtools": "^5.91.1", "devDependencies": {
"@tanstack/react-router-devtools": "^1.141.1", "@cloudflare/vite-plugin": "^1.17.1",
"@testing-library/dom": "^10.4.0", "@kk/config": "workspace:*",
"@testing-library/react": "^16.2.0", "@tanstack/react-query-devtools": "^5.91.1",
"@types/react": "19.2.7", "@tanstack/react-router-devtools": "^1.141.1",
"@types/react-dom": "19.2.3", "@testing-library/dom": "^10.4.0",
"@vitejs/plugin-react": "^5.0.4", "@testing-library/react": "^16.2.0",
"alchemy": "catalog:", "@types/react": "19.2.7",
"jsdom": "^26.0.0", "@types/react-dom": "19.2.3",
"typescript": "catalog:", "@types/three": "^0.183.1",
"vite": "^7.0.2", "@vitejs/plugin-react": "^5.0.4",
"web-vitals": "^5.0.3", "alchemy": "catalog:",
"wrangler": "^4.54.0" "jsdom": "^26.0.0",
} "typescript": "catalog:",
"vite": "^7.0.2",
"web-vitals": "^5.0.3",
"wrangler": "^4.54.0"
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -0,0 +1,115 @@
import { Camera, Drama, Mic2, Music, Palette, PenTool } from "lucide-react";
const artForms = [
{
icon: Music,
title: "Muziek",
description:
"Van akoestische singer-songwriter sets tot volledige band optredens. Ontdek je sound en deel je muziek met een warm publiek.",
trajectory: "Muziek Traject",
color: "#d82560",
},
{
icon: Drama,
title: "Theater",
description:
"Monologen, sketches, improvisatie of mime. Het podium is van jou — breng karakters tot leven en vertel verhalen die raken.",
trajectory: "Theater Traject",
color: "#52979b",
},
{
icon: Palette,
title: "Beeldende Kunst",
description:
"Live schilderen, illustraties maken, of mixed media performances. Toon je creatieve proces terwijl het publiek toekijkt.",
trajectory: "Beeldende Kunst Traject",
color: "#d09035",
},
{
icon: PenTool,
title: "Woordkunst",
description:
"Poëzie, spoken word, storytelling of rap. Laat je woorden dansen en raak het publiek met de kracht van taal.",
trajectory: "Woordkunst Traject",
color: "#214e51",
},
{
icon: Camera,
title: "Dans",
description:
"Contemporary, ballet, hiphop of freestyle. Beweging vertelt verhalen die woorden niet kunnen vangen.",
trajectory: "Dans Traject",
color: "#d82560",
},
{
icon: Mic2,
title: "Comedy",
description:
"Stand-up, improv of cabaret. Maak het publiek aan het lachen met je unieke kijk op de wereld.",
trajectory: "Comedy Traject",
color: "#52979b",
},
];
export default function ArtForms() {
return (
<section className="snap-section relative z-25 min-h-screen w-full bg-[#f8f8f8] px-12 py-16">
<div className="mx-auto max-w-6xl">
<h2 className="mb-4 font-['Intro',sans-serif] text-5xl text-[#214e51]">
Kies Je Traject
</h2>
<p className="mb-12 max-w-2xl font-['Intro',sans-serif] text-gray-600 text-xl">
Kunstenkamp biedt trajecten aan voor verschillende kunstvormen. Ontdek
waar jouw passie ligt en ontwikkel je talent onder begeleiding van
ervaringsdeskundigen.
</p>
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{artForms.map((art) => {
const IconComponent = art.icon;
return (
<div
key={art.title}
className="group relative overflow-hidden bg-white p-8 transition-all hover:-translate-y-2 hover:shadow-xl"
>
{/* Color bar at top */}
<div
className="absolute top-0 left-0 h-1 w-full transition-all group-hover:h-2"
style={{ backgroundColor: art.color }}
/>
<div className="mb-4 flex items-center gap-4">
<div
className="flex h-14 w-14 items-center justify-center"
style={{ backgroundColor: art.color }}
>
<IconComponent className="h-7 w-7 text-white" />
</div>
<h3 className="font-['Intro',sans-serif] text-2xl text-gray-900">
{art.title}
</h3>
</div>
<p className="mb-6 font-['Intro',sans-serif] text-gray-600 leading-relaxed">
{art.description}
</p>
<div className="flex items-center justify-between border-gray-100 border-t pt-4">
<span
className="font-['Intro',sans-serif] font-medium text-sm"
style={{ color: art.color }}
>
{art.trajectory}
</span>
<span className="text-2xl text-gray-300 transition-all group-hover:translate-x-1 group-hover:text-gray-600">
</span>
</div>
</div>
);
})}
</div>
</div>
</section>
);
}

View File

@@ -4,11 +4,12 @@ import { useState } from "react";
export default function EventRegistrationForm() { export default function EventRegistrationForm() {
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
name: "", firstName: "",
lastName: "",
email: "", email: "",
phone: "", phone: "",
company: "", artForm: "",
dietaryRequirements: "", experience: "",
}); });
const handleSubmit = (e: React.FormEvent) => { const handleSubmit = (e: React.FormEvent) => {
@@ -27,85 +28,156 @@ export default function EventRegistrationForm() {
return ( return (
<section <section
style={{ id="registration"
minHeight: "100vh", className="snap-section relative z-30 min-h-screen w-full bg-[#214e51]/96 px-12 py-16"
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}
> >
<h2>Register for the Event</h2> <div className="mx-auto flex h-full max-w-6xl flex-col">
<h2 className="mb-2 font-['Intro',sans-serif] text-4xl text-white">
Schrijf je nu in!
</h2>
<p className="mb-12 max-w-3xl font-['Intro',sans-serif] text-white/80 text-xl">
Doet dit jouw creatieve geest borellen? Vul nog even dit formulier in
</p>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit} className="flex flex-1 flex-col">
<div> <div className="flex flex-col gap-8">
<label htmlFor="name">Full Name *</label> {/* Row 1: First Name + Last Name */}
<input <div className="grid grid-cols-1 gap-8 md:grid-cols-2">
type="text" <div className="flex flex-col gap-2">
id="name" <label
name="name" htmlFor="firstName"
value={formData.name} className="font-['Intro',sans-serif] text-2xl text-white"
onChange={handleChange} >
required Voornaam
placeholder="Enter your full name" </label>
/> <input
</div> type="text"
id="firstName"
name="firstName"
value={formData.firstName}
onChange={handleChange}
placeholder="Jouw voornaam"
className="border-white/30 border-b bg-transparent pb-2 font-['Intro',sans-serif] text-lg text-white placeholder:text-white/40 focus:border-white focus:outline-none"
/>
</div>
<div> <div className="flex flex-col gap-2">
<label htmlFor="email">Email Address *</label> <label
<input htmlFor="lastName"
type="email" className="font-['Intro',sans-serif] text-2xl text-white"
id="email" >
name="email" Achternaam
value={formData.email} </label>
onChange={handleChange} <input
required type="text"
placeholder="Enter your email" id="lastName"
/> name="lastName"
</div> value={formData.lastName}
onChange={handleChange}
placeholder="Jouw achternaam"
className="border-white/30 border-b bg-transparent pb-2 font-['Intro',sans-serif] text-lg text-white placeholder:text-white/40 focus:border-white focus:outline-none"
/>
</div>
</div>
<div> {/* Row 2: Email + Phone */}
<label htmlFor="phone">Phone Number</label> <div className="grid grid-cols-1 gap-8 md:grid-cols-2">
<input <div className="flex flex-col gap-2">
type="tel" <label
id="phone" htmlFor="email"
name="phone" className="font-['Intro',sans-serif] text-2xl text-white"
value={formData.phone} >
onChange={handleChange} E-mail
placeholder="Enter your phone number" </label>
/> <input
</div> type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="jouw@email.nl"
className="border-white/30 border-b bg-transparent pb-2 font-['Intro',sans-serif] text-lg text-white placeholder:text-white/40 focus:border-white focus:outline-none"
/>
</div>
<div> <div className="flex flex-col gap-2">
<label htmlFor="company">Company / Organization</label> <label
<input htmlFor="phone"
type="text" className="font-['Intro',sans-serif] text-2xl text-white"
id="company" >
name="company" Telefoon
value={formData.company} </label>
onChange={handleChange} <input
placeholder="Enter your company or organization" type="tel"
/> id="phone"
</div> name="phone"
value={formData.phone}
onChange={handleChange}
placeholder="06-12345678"
className="border-white/30 border-b bg-transparent pb-2 font-['Intro',sans-serif] text-lg text-white placeholder:text-white/40 focus:border-white focus:outline-none"
/>
</div>
</div>
<div> {/* Row 3: Art Form (full width) */}
<label htmlFor="dietaryRequirements"> <div className="flex flex-col gap-2">
Dietary Requirements / Special Requests <label
</label> htmlFor="artForm"
<textarea className="font-['Intro',sans-serif] text-2xl text-white"
id="dietaryRequirements" >
name="dietaryRequirements" Kunstvorm
value={formData.dietaryRequirements} </label>
onChange={handleChange} <input
rows={3} type="text"
placeholder="Any dietary restrictions or special requests?" id="artForm"
/> name="artForm"
</div> value={formData.artForm}
onChange={handleChange}
placeholder="Muziek, Theater, Dans, etc."
className="border-white/30 border-b bg-transparent pb-2 font-['Intro',sans-serif] text-lg text-white placeholder:text-white/40 focus:border-white focus:outline-none"
/>
</div>
<button type="submit">Submit Registration</button> {/* Row 4: Experience (full width) */}
<div className="grid grid-cols-1 gap-8 md:grid-cols-2">
<div className="flex flex-col gap-2">
<label
htmlFor="experience"
className="font-['Intro',sans-serif] text-2xl text-white"
>
Ervaring
</label>
<input
type="text"
id="experience"
name="experience"
value={formData.experience}
onChange={handleChange}
placeholder="Beginner / Gevorderd / Professional"
className="border-white/30 border-b bg-transparent pb-2 font-['Intro',sans-serif] text-lg text-white placeholder:text-white/40 focus:border-white focus:outline-none"
/>
</div>
</div>
</div>
<p>* Required fields</p> {/* Submit button */}
</form> <div className="mt-auto flex flex-col items-center gap-4 pt-12">
<button
type="submit"
className="bg-white px-12 py-4 font-['Intro',sans-serif] text-2xl text-[#214e51] transition-all hover:scale-105 hover:bg-gray-100"
>
Bevestigen
</button>
<p className="text-center font-['Intro',sans-serif] text-sm text-white/60">
Nu al een act / idee van wat jij graag zou willen brengen,{" "}
<span className="cursor-pointer underline hover:text-white">
klik HIER
</span>
</p>
</div>
</form>
</div>
</section> </section>
); );
} }

View File

@@ -1,13 +1,33 @@
export default function Footer() { export default function Footer() {
return ( return (
<footer> <footer className="snap-section relative z-40 flex h-[250px] flex-col items-center justify-center bg-[#d09035]">
<div> <div className="text-center">
<div>© 2024 My App. All rights reserved.</div> <h3 className="mb-4 font-['Intro',sans-serif] text-2xl text-white">
Kunstenkamp
</h3>
<p className="mb-6 font-['Intro',sans-serif] text-white/80">
Waar creativiteit tot leven komt
</p>
<div> <div className="flex items-center justify-center gap-8 font-['Intro',sans-serif] text-sm text-white/70">
<a href="/privacy">Privacy Policy</a> <a href="/privacy" className="transition-colors hover:text-white">
<a href="/terms">Terms of Service</a> Privacy Policy
<a href="/contact">Contact</a> </a>
<span className="text-white/40">|</span>
<a href="/terms" className="transition-colors hover:text-white">
Terms of Service
</a>
<span className="text-white/40">|</span>
<a href="/contact" className="transition-colors hover:text-white">
Contact
</a>
</div>
<div className="mt-6 font-['Intro',sans-serif] text-white/50 text-xs">
© 2026 Kunstenkamp. Alle rechten voorbehouden.
</div>
<div className="font-['Intro',sans-serif] text-white/50 text-xs">
<a href="https://zias.be">Gemaakt met door zias.be</a>
</div> </div>
</div> </div>
</footer> </footer>

View File

@@ -1,21 +1,164 @@
import { useEffect, useState } from "react";
export default function Hero() { export default function Hero() {
const [micVisible, setMicVisible] = useState(false);
useEffect(() => {
// Trigger entrance animation after component mounts
const timer = setTimeout(() => {
setMicVisible(true);
}, 100);
return () => clearTimeout(timer);
}, []);
const scrollToRegistration = () => {
const registrationSection = document.getElementById("registration");
if (registrationSection) {
registrationSection.scrollIntoView({ behavior: "smooth" });
}
};
return ( return (
<section <section className="snap-section relative h-screen w-full overflow-hidden bg-white">
style={{ {/* Desktop Layout - hidden on mobile */}
minHeight: "100vh", <div className="relative hidden h-full w-full flex-col gap-[10px] p-[10px] lg:flex">
display: "flex", {/* Desktop Microphone - positioned on top of top sections, under bottom sections */}
flexDirection: "column", <div
justifyContent: "center", className={`pointer-events-none absolute z-20 transition-all duration-1000 ease-out ${
alignItems: "center", micVisible
}} ? "translate-x-0 translate-y-0 opacity-100"
> : "translate-x-24 -translate-y-24 opacity-0"
<h1>Welcome to Our Event</h1> }`}
<p> style={{
Join us for an amazing experience. Register now to secure your spot. right: "5%",
</p> top: "0",
<div> width: "38%",
<button type="button">Register Now</button> }}
<button type="button">Learn More</button> >
<img
src="/assets/mic.png"
alt="Vintage microphone"
className="h-full w-full object-contain drop-shadow-2xl"
/>
</div>
{/* Top row - 2:1 ratio using flex */}
<div className="relative flex h-[65%] min-h-0 flex-shrink-0 gap-[10px]">
{/* Top Left - Magenta with title - under mic */}
<div className="relative z-10 flex min-w-0 flex-[2] flex-col justify-center bg-[#d82560] px-[5%] py-[5%]">
<h1 className="font-['Intro',sans-serif] font-normal text-[clamp(3rem,7vw,6rem)] text-white uppercase leading-[1]">
OPEN MIC
<br />
NIGHT
</h1>
<p className="mt-4 font-['Intro',sans-serif] font-normal text-[clamp(1.25rem,2.5vw,2.625rem)] text-white/90">
Ongedesemd brood
</p>
</div>
{/* Top Right - Teal - under mic */}
<div className="relative z-10 min-w-0 flex-1 bg-[#52979b]" />
</div>
{/* Bottom row - equal width */}
<div className="relative z-30 flex min-h-0 flex-1 gap-[10px]">
{/* Bottom Left - Mustard - above mic */}
<div className="relative flex flex-1 items-center bg-[#d09035] px-[3%]">
<p className="font-['Intro',sans-serif] font-normal text-[clamp(1.25rem,2.5vw,2.625rem)] text-white leading-tight">
Een kunstenkamp
<br />
initiatief
</p>
</div>
{/* Bottom Right - Dark Teal with date - above mic */}
<div className="relative flex flex-1 items-center justify-end bg-[#214e51]">
<p className="px-12 text-right font-['Intro',sans-serif] font-normal text-[clamp(2rem,5vw,6rem)] text-white uppercase leading-[1.1]">
VRIJDAG 18
<br />
april
</p>
</div>
</div>
{/* Desktop CTA Button - centered at bottom */}
<div className="absolute bottom-[10px] left-1/2 z-30 -translate-x-1/2">
<button
onClick={scrollToRegistration}
type="button"
className="bg-black px-[40px] py-[10px] font-['Intro',sans-serif] font-normal text-[30px] text-white transition-all hover:scale-105 hover:bg-gray-900"
>
Registreer nu!
</button>
</div>
</div>
{/* Mobile Responsive Layout */}
<div className="relative flex h-full w-full flex-col lg:hidden">
{/* Mobile: Single column stacked */}
<div className="flex flex-1 flex-col gap-[10px] overflow-hidden p-[10px]">
{/* Mobile Top - Magenta */}
<div className="relative z-10 flex flex-1 flex-col justify-center overflow-hidden bg-[#d82560] px-6 py-8">
<h1 className="font-['Intro',sans-serif] font-normal text-[15vw] text-white uppercase leading-[0.95]">
OPEN MIC
<br />
NIGHT
</h1>
<p className="mt-4 font-['Intro',sans-serif] font-normal text-[5vw] text-white/90">
Ongedesemd brood
</p>
{/* Mobile Microphone - positioned inside magenta section, clipped by overflow */}
<div
className={`pointer-events-none absolute z-10 transition-all duration-1000 ease-out ${
micVisible
? "translate-x-0 translate-y-0 opacity-100"
: "translate-x-12 -translate-y-12 opacity-0"
}`}
style={{
right: "-30%",
bottom: "-55%",
width: "70%",
height: "130%",
}}
>
<img
src="/assets/mic.png"
alt="Vintage microphone"
className="h-full w-full object-contain object-bottom drop-shadow-2xl"
/>
</div>
</div>
{/* Mobile Bottom Row - Mustard + Dark Teal */}
<div className="relative z-20 flex flex-1 gap-[10px]">
<div className="flex flex-1 items-center bg-[#d09035] px-4">
<p className="font-['Intro',sans-serif] font-normal text-[4vw] text-white leading-tight">
Een kunstenkamp
<br />
initiatief
</p>
</div>
<div className="flex flex-1 flex-col items-end justify-center bg-[#214e51] p-4">
<p className="text-right font-['Intro',sans-serif] font-normal text-[8vw] text-white uppercase leading-tight">
VRIJDAG
<br />
18 april
</p>
</div>
</div>
</div>
{/* Mobile CTA */}
<div className="px-[10px] pb-[10px]">
<button
onClick={scrollToRegistration}
type="button"
className="w-full bg-black py-3 font-['Intro',sans-serif] font-normal text-lg text-white transition-all hover:scale-105 hover:bg-gray-900"
>
Registreer nu!
</button>
</div>
</div> </div>
</section> </section>
); );

View File

@@ -1,47 +1,45 @@
const questions = [
{
question: "Wat is een open mic?",
answer:
"Een open mic is een podium waar iedereen zijn of haar talent kan tonen. Of je nu zingt, danst, een gedicht voordraagt of een instrument bespeelt — alle kunstvormen zijn welkom!",
},
{
question: "Wie mag er deelnemen?",
answer:
"Iedereen! Of je nu een doorgewinterde artiest bent of voor het eerst op een podium staat — de open mic night is er voor alle niveaus en ervaringen.",
},
{
question: "Hoelang mag mijn optreden duren?",
answer:
"Elke deelnemer krijgt 5-7 minuten podiumtijd. Zo houden we de avond dynamisch en krijgt iedereen een kans om te shinen.",
},
{
question: "Wat moet ik meenemen?",
answer:
"We zorgen voor geluidstechniek en een microfoon. Breng je eigen instrument mee als je dat nodig hebt. Vragen? Neem contact op via de registratie!",
},
];
export default function Info() { export default function Info() {
return ( return (
<section <section className="snap-section relative z-20 flex min-h-screen flex-col bg-[#d82560]/96 px-12 py-16">
style={{ <div className="mx-auto flex w-full max-w-6xl flex-1 flex-col justify-center gap-16">
minHeight: "100vh", {questions.map((item, idx) => (
display: "flex", <div
flexDirection: "column", key={item.question}
justifyContent: "center", className={`flex flex-col gap-4 ${
alignItems: "center", idx % 2 === 0 ? "items-start text-left" : "items-end text-right"
}} }`}
> >
<div> <h3 className="font-['Intro',sans-serif] text-4xl text-white">
<div> {item.question}
<h3>Event Details</h3> </h3>
<p> <p className="max-w-xl font-['Intro',sans-serif] text-white/80 text-xl">
Date: TBD {item.answer}
<br /> </p>
Location: TBD </div>
<br /> ))}
Duration: Full Day
</p>
</div>
<div>
<h3>What to Expect</h3>
<p>
Keynote speakers
<br />
Networking opportunities
<br />
Workshops & sessions
</p>
</div>
<div>
<h3>Who Should Attend</h3>
<p>
Industry professionals
<br />
Students & educators
<br />
Anyone interested
</p>
</div>
</div> </div>
</section> </section>
); );

View File

@@ -1,9 +1,9 @@
import { Loader2 } from "lucide-react"; import { Loader2 } from "lucide-react";
export default function Loader() { export default function Loader() {
return ( return (
<div className="flex h-full items-center justify-center pt-8"> <div className="flex h-full items-center justify-center pt-8">
<Loader2 className="animate-spin" /> <Loader2 className="animate-spin" />
</div> </div>
); );
} }

View File

@@ -1,58 +1,57 @@
import type { VariantProps } from "class-variance-authority";
import { Button as ButtonPrimitive } from "@base-ui/react/button"; import { Button as ButtonPrimitive } from "@base-ui/react/button";
import type { VariantProps } from "class-variance-authority";
import { cva } from "class-variance-authority"; import { cva } from "class-variance-authority";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
const buttonVariants = cva( const buttonVariants = cva(
"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-none border border-transparent bg-clip-padding text-xs font-medium focus-visible:ring-1 aria-invalid:ring-1 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", "group/button inline-flex shrink-0 select-none items-center justify-center whitespace-nowrap rounded-none border border-transparent bg-clip-padding font-medium text-xs outline-none transition-all focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
{ {
variants: { variants: {
variant: { variant: {
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
outline: outline:
"border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground", "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
secondary: secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
ghost: ghost:
"hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground", "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
destructive: destructive:
"bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30", "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 dark:hover:bg-destructive/30",
link: "text-primary underline-offset-4 hover:underline", link: "text-primary underline-offset-4 hover:underline",
}, },
size: { size: {
default: default:
"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
xs: "h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", xs: "h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
sm: "h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", sm: "h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3", lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
icon: "size-8", icon: "size-8",
"icon-xs": "size-6 rounded-none [&_svg:not([class*='size-'])]:size-3", "icon-xs": "size-6 rounded-none [&_svg:not([class*='size-'])]:size-3",
"icon-sm": "size-7 rounded-none", "icon-sm": "size-7 rounded-none",
"icon-lg": "size-9", "icon-lg": "size-9",
}, },
}, },
defaultVariants: { defaultVariants: {
variant: "default", variant: "default",
size: "default", size: "default",
}, },
}, },
); );
function Button({ function Button({
className, className,
variant = "default", variant = "default",
size = "default", size = "default",
...props ...props
}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) { }: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
return ( return (
<ButtonPrimitive <ButtonPrimitive
data-slot="button" data-slot="button"
className={cn(buttonVariants({ variant, size, className }))} className={cn(buttonVariants({ variant, size, className }))}
{...props} {...props}
/> />
); );
} }
export { Button, buttonVariants }; export { Button, buttonVariants };

View File

@@ -1,89 +1,103 @@
import * as React from "react"; import type * as React from "react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function Card({ function Card({
className, className,
size = "default", size = "default",
...props ...props
}: React.ComponentProps<"div"> & { size?: "default" | "sm" }) { }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
return ( return (
<div <div
data-slot="card" data-slot="card"
data-size={size} data-size={size}
className={cn( className={cn(
"ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-none py-4 text-xs/relaxed ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none group/card flex flex-col", "group/card flex flex-col gap-4 overflow-hidden rounded-none bg-card py-4 text-card-foreground text-xs/relaxed ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 has-data-[slot=card-footer]:pb-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none",
className, className,
)} )}
{...props} {...props}
/> />
); );
} }
function CardHeader({ className, ...props }: React.ComponentProps<"div">) { function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return ( return (
<div <div
data-slot="card-header" data-slot="card-header"
className={cn( className={cn(
"gap-1 rounded-none px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]", "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-none px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
className, className,
)} )}
{...props} {...props}
/> />
); );
} }
function CardTitle({ className, ...props }: React.ComponentProps<"div">) { function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
return ( return (
<div <div
data-slot="card-title" data-slot="card-title"
className={cn("text-sm font-medium group-data-[size=sm]/card:text-sm", className)} className={cn(
{...props} "font-medium text-sm group-data-[size=sm]/card:text-sm",
/> className,
); )}
{...props}
/>
);
} }
function CardDescription({ className, ...props }: React.ComponentProps<"div">) { function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
return ( return (
<div <div
data-slot="card-description" data-slot="card-description"
className={cn("text-muted-foreground text-xs/relaxed", className)} className={cn("text-muted-foreground text-xs/relaxed", className)}
{...props} {...props}
/> />
); );
} }
function CardAction({ className, ...props }: React.ComponentProps<"div">) { function CardAction({ className, ...props }: React.ComponentProps<"div">) {
return ( return (
<div <div
data-slot="card-action" data-slot="card-action"
className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)} className={cn(
{...props} "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
/> className,
); )}
{...props}
/>
);
} }
function CardContent({ className, ...props }: React.ComponentProps<"div">) { function CardContent({ className, ...props }: React.ComponentProps<"div">) {
return ( return (
<div <div
data-slot="card-content" data-slot="card-content"
className={cn("px-4 group-data-[size=sm]/card:px-3", className)} className={cn("px-4 group-data-[size=sm]/card:px-3", className)}
{...props} {...props}
/> />
); );
} }
function CardFooter({ className, ...props }: React.ComponentProps<"div">) { function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return ( return (
<div <div
data-slot="card-footer" data-slot="card-footer"
className={cn( className={cn(
"rounded-none border-t p-4 group-data-[size=sm]/card:p-3 flex items-center", "flex items-center rounded-none border-t p-4 group-data-[size=sm]/card:p-3",
className, className,
)} )}
{...props} {...props}
/> />
); );
} }
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent }; export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
};

View File

@@ -4,23 +4,23 @@ import { CheckIcon } from "lucide-react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) { function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {
return ( return (
<CheckboxPrimitive.Root <CheckboxPrimitive.Root
data-slot="checkbox" data-slot="checkbox"
className={cn( className={cn(
"border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-none border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-1 aria-invalid:ring-1 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50", "peer relative flex size-4 shrink-0 items-center justify-center rounded-none border border-input outline-none transition-colors after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 group-has-disabled/field:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:bg-input/30 dark:data-checked:bg-primary dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
className, className,
)} )}
{...props} {...props}
> >
<CheckboxPrimitive.Indicator <CheckboxPrimitive.Indicator
data-slot="checkbox-indicator" data-slot="checkbox-indicator"
className="[&>svg]:size-3.5 grid place-content-center text-current transition-none" className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
> >
<CheckIcon /> <CheckIcon />
</CheckboxPrimitive.Indicator> </CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root> </CheckboxPrimitive.Root>
); );
} }
export { Checkbox }; export { Checkbox };

View File

@@ -1,241 +1,262 @@
import { Menu as MenuPrimitive } from "@base-ui/react/menu"; import { Menu as MenuPrimitive } from "@base-ui/react/menu";
import { CheckIcon, ChevronRightIcon } from "lucide-react"; import { CheckIcon, ChevronRightIcon } from "lucide-react";
import * as React from "react"; import type * as React from "react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) { function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />; return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
} }
function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) { function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
return <MenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />; return <MenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
} }
function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) { function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
return <MenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />; return <MenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
} }
function DropdownMenuContent({ function DropdownMenuContent({
align = "start", align = "start",
alignOffset = 0, alignOffset = 0,
side = "bottom", side = "bottom",
sideOffset = 4, sideOffset = 4,
className, className,
...props ...props
}: MenuPrimitive.Popup.Props & }: MenuPrimitive.Popup.Props &
Pick<MenuPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">) { Pick<
return ( MenuPrimitive.Positioner.Props,
<MenuPrimitive.Portal> "align" | "alignOffset" | "side" | "sideOffset"
<MenuPrimitive.Positioner >) {
className="isolate z-50 outline-none" return (
align={align} <MenuPrimitive.Portal>
alignOffset={alignOffset} <MenuPrimitive.Positioner
side={side} className="isolate z-50 outline-none"
sideOffset={sideOffset} align={align}
> alignOffset={alignOffset}
<MenuPrimitive.Popup side={side}
data-slot="dropdown-menu-content" sideOffset={sideOffset}
className={cn( >
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-none shadow-md ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden", <MenuPrimitive.Popup
className, data-slot="dropdown-menu-content"
)} className={cn(
{...props} "data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-y-auto overflow-x-hidden rounded-none bg-popover text-popover-foreground shadow-md outline-none ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-open:animate-in data-closed:overflow-hidden",
/> className,
</MenuPrimitive.Positioner> )}
</MenuPrimitive.Portal> {...props}
); />
</MenuPrimitive.Positioner>
</MenuPrimitive.Portal>
);
} }
function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) { function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {
return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />; return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
} }
function DropdownMenuLabel({ function DropdownMenuLabel({
className, className,
inset, inset,
...props ...props
}: MenuPrimitive.GroupLabel.Props & { }: MenuPrimitive.GroupLabel.Props & {
inset?: boolean; inset?: boolean;
}) { }) {
return ( return (
<MenuPrimitive.GroupLabel <MenuPrimitive.GroupLabel
data-slot="dropdown-menu-label" data-slot="dropdown-menu-label"
data-inset={inset} data-inset={inset}
className={cn("text-muted-foreground px-2 py-2 text-xs data-[inset]:pl-8", className)} className={cn(
{...props} "px-2 py-2 text-muted-foreground text-xs data-[inset]:pl-8",
/> className,
); )}
{...props}
/>
);
} }
function DropdownMenuItem({ function DropdownMenuItem({
className, className,
inset, inset,
variant = "default", variant = "default",
...props ...props
}: MenuPrimitive.Item.Props & { }: MenuPrimitive.Item.Props & {
inset?: boolean; inset?: boolean;
variant?: "default" | "destructive"; variant?: "default" | "destructive";
}) { }) {
return ( return (
<MenuPrimitive.Item <MenuPrimitive.Item
data-slot="dropdown-menu-item" data-slot="dropdown-menu-item"
data-inset={inset} data-inset={inset}
data-variant={variant} data-variant={variant}
className={cn( className={cn(
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0", "group/dropdown-menu-item relative flex cursor-default select-none items-center gap-2 rounded-none px-2 py-2 text-xs outline-hidden focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-disabled:opacity-50 data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 data-[variant=destructive]:*:[svg]:text-destructive",
className, className,
)} )}
{...props} {...props}
/> />
); );
} }
function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) { function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />; return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />;
} }
function DropdownMenuSubTrigger({ function DropdownMenuSubTrigger({
className, className,
inset, inset,
children, children,
...props ...props
}: MenuPrimitive.SubmenuTrigger.Props & { }: MenuPrimitive.SubmenuTrigger.Props & {
inset?: boolean; inset?: boolean;
}) { }) {
return ( return (
<MenuPrimitive.SubmenuTrigger <MenuPrimitive.SubmenuTrigger
data-slot="dropdown-menu-sub-trigger" data-slot="dropdown-menu-sub-trigger"
data-inset={inset} data-inset={inset}
className={cn( className={cn(
"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs [&_svg:not([class*='size-'])]:size-4 flex cursor-default items-center outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0", "flex cursor-default select-none items-center gap-2 rounded-none px-2 py-2 text-xs outline-hidden focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-[inset]:pl-8 data-open:text-accent-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
className, className,
)} )}
{...props} {...props}
> >
{children} {children}
<ChevronRightIcon className="ml-auto" /> <ChevronRightIcon className="ml-auto" />
</MenuPrimitive.SubmenuTrigger> </MenuPrimitive.SubmenuTrigger>
); );
} }
function DropdownMenuSubContent({ function DropdownMenuSubContent({
align = "start", align = "start",
alignOffset = -3, alignOffset = -3,
side = "right", side = "right",
sideOffset = 0, sideOffset = 0,
className, className,
...props ...props
}: React.ComponentProps<typeof DropdownMenuContent>) { }: React.ComponentProps<typeof DropdownMenuContent>) {
return ( return (
<DropdownMenuContent <DropdownMenuContent
data-slot="dropdown-menu-sub-content" data-slot="dropdown-menu-sub-content"
className={cn( className={cn(
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-[96px] rounded-none shadow-lg ring-1 duration-100 w-auto", "data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 w-auto min-w-[96px] rounded-none bg-popover text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-open:animate-in",
className, className,
)} )}
align={align} align={align}
alignOffset={alignOffset} alignOffset={alignOffset}
side={side} side={side}
sideOffset={sideOffset} sideOffset={sideOffset}
{...props} {...props}
/> />
); );
} }
function DropdownMenuCheckboxItem({ function DropdownMenuCheckboxItem({
className, className,
children, children,
checked, checked,
...props ...props
}: MenuPrimitive.CheckboxItem.Props) { }: MenuPrimitive.CheckboxItem.Props) {
return ( return (
<MenuPrimitive.CheckboxItem <MenuPrimitive.CheckboxItem
data-slot="dropdown-menu-checkbox-item" data-slot="dropdown-menu-checkbox-item"
className={cn( className={cn(
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", "relative flex cursor-default select-none items-center gap-2 rounded-none py-2 pr-8 pl-2 text-xs outline-hidden focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
className, className,
)} )}
checked={checked} checked={checked}
{...props} {...props}
> >
<span <span
className="pointer-events-none absolute right-2 flex items-center justify-center pointer-events-none" className="pointer-events-none pointer-events-none absolute right-2 flex items-center justify-center"
data-slot="dropdown-menu-checkbox-item-indicator" data-slot="dropdown-menu-checkbox-item-indicator"
> >
<MenuPrimitive.CheckboxItemIndicator> <MenuPrimitive.CheckboxItemIndicator>
<CheckIcon /> <CheckIcon />
</MenuPrimitive.CheckboxItemIndicator> </MenuPrimitive.CheckboxItemIndicator>
</span> </span>
{children} {children}
</MenuPrimitive.CheckboxItem> </MenuPrimitive.CheckboxItem>
); );
} }
function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) { function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
return <MenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />; return (
<MenuPrimitive.RadioGroup
data-slot="dropdown-menu-radio-group"
{...props}
/>
);
} }
function DropdownMenuRadioItem({ className, children, ...props }: MenuPrimitive.RadioItem.Props) { function DropdownMenuRadioItem({
return ( className,
<MenuPrimitive.RadioItem children,
data-slot="dropdown-menu-radio-item" ...props
className={cn( }: MenuPrimitive.RadioItem.Props) {
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", return (
className, <MenuPrimitive.RadioItem
)} data-slot="dropdown-menu-radio-item"
{...props} className={cn(
> "relative flex cursor-default select-none items-center gap-2 rounded-none py-2 pr-8 pl-2 text-xs outline-hidden focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
<span className,
className="pointer-events-none absolute right-2 flex items-center justify-center pointer-events-none" )}
data-slot="dropdown-menu-radio-item-indicator" {...props}
> >
<MenuPrimitive.RadioItemIndicator> <span
<CheckIcon /> className="pointer-events-none pointer-events-none absolute right-2 flex items-center justify-center"
</MenuPrimitive.RadioItemIndicator> data-slot="dropdown-menu-radio-item-indicator"
</span> >
{children} <MenuPrimitive.RadioItemIndicator>
</MenuPrimitive.RadioItem> <CheckIcon />
); </MenuPrimitive.RadioItemIndicator>
</span>
{children}
</MenuPrimitive.RadioItem>
);
} }
function DropdownMenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) { function DropdownMenuSeparator({
return ( className,
<MenuPrimitive.Separator ...props
data-slot="dropdown-menu-separator" }: MenuPrimitive.Separator.Props) {
className={cn("bg-border -mx-1 h-px", className)} return (
{...props} <MenuPrimitive.Separator
/> data-slot="dropdown-menu-separator"
); className={cn("-mx-1 h-px bg-border", className)}
{...props}
/>
);
} }
function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">) { function DropdownMenuShortcut({
return ( className,
<span ...props
data-slot="dropdown-menu-shortcut" }: React.ComponentProps<"span">) {
className={cn( return (
"text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-xs tracking-widest", <span
className, data-slot="dropdown-menu-shortcut"
)} className={cn(
{...props} "ml-auto text-muted-foreground text-xs tracking-widest group-focus/dropdown-menu-item:text-accent-foreground",
/> className,
); )}
{...props}
/>
);
} }
export { export {
DropdownMenu, DropdownMenu,
DropdownMenuPortal, DropdownMenuPortal,
DropdownMenuTrigger, DropdownMenuTrigger,
DropdownMenuContent, DropdownMenuContent,
DropdownMenuGroup, DropdownMenuGroup,
DropdownMenuLabel, DropdownMenuLabel,
DropdownMenuItem, DropdownMenuItem,
DropdownMenuCheckboxItem, DropdownMenuCheckboxItem,
DropdownMenuRadioGroup, DropdownMenuRadioGroup,
DropdownMenuRadioItem, DropdownMenuRadioItem,
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuShortcut, DropdownMenuShortcut,
DropdownMenuSub, DropdownMenuSub,
DropdownMenuSubTrigger, DropdownMenuSubTrigger,
DropdownMenuSubContent, DropdownMenuSubContent,
}; };

View File

@@ -1,20 +1,20 @@
import { Input as InputPrimitive } from "@base-ui/react/input"; import { Input as InputPrimitive } from "@base-ui/react/input";
import * as React from "react"; import type * as React from "react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) { function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return ( return (
<InputPrimitive <InputPrimitive
type={type} type={type}
data-slot="input" data-slot="input"
className={cn( className={cn(
"dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-none border bg-transparent px-2.5 py-1 text-xs transition-colors file:h-6 file:text-xs file:font-medium focus-visible:ring-1 aria-invalid:ring-1 md:text-xs file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", "h-8 w-full min-w-0 rounded-none border border-input bg-transparent px-2.5 py-1 text-xs outline-none transition-colors file:inline-flex file:h-6 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-xs placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 md:text-xs dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 dark:disabled:bg-input/80",
className, className,
)} )}
{...props} {...props}
/> />
); );
} }
export { Input }; export { Input };

View File

@@ -1,20 +1,21 @@
"use client"; "use client";
import * as React from "react"; import type * as React from "react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function Label({ className, ...props }: React.ComponentProps<"label">) { function Label({ className, ...props }: React.ComponentProps<"label">) {
return ( return (
<label // biome-ignore lint/a11y/noLabelWithoutControl: This is a generic Label component - htmlFor will be provided when used
data-slot="label" <label
className={cn( data-slot="label"
"gap-2 text-xs leading-none group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed", className={cn(
className, "flex select-none items-center gap-2 text-xs leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50",
)} className,
{...props} )}
/> {...props}
); />
);
} }
export { Label }; export { Label };

View File

@@ -1,13 +1,16 @@
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) { function Skeleton({
return ( className,
<div ...props
data-slot="skeleton" }: React.HTMLAttributes<HTMLDivElement>) {
className={cn("bg-muted rounded-none animate-pulse", className)} return (
{...props} <div
/> data-slot="skeleton"
); className={cn("animate-pulse rounded-none bg-muted", className)}
{...props}
/>
);
} }
export { Skeleton }; export { Skeleton };

View File

@@ -1,45 +1,44 @@
import type { ToasterProps } from "sonner";
import { import {
CircleCheckIcon, CircleCheckIcon,
InfoIcon, InfoIcon,
Loader2Icon, Loader2Icon,
OctagonXIcon, OctagonXIcon,
TriangleAlertIcon, TriangleAlertIcon,
} from "lucide-react"; } from "lucide-react";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import type { ToasterProps } from "sonner";
import { Toaster as Sonner } from "sonner"; import { Toaster as Sonner } from "sonner";
const Toaster = ({ ...props }: ToasterProps) => { const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme(); const { theme = "system" } = useTheme();
return ( return (
<Sonner <Sonner
theme={theme as ToasterProps["theme"]} theme={theme as ToasterProps["theme"]}
className="toaster group" className="toaster group"
icons={{ icons={{
success: <CircleCheckIcon className="size-4" />, success: <CircleCheckIcon className="size-4" />,
info: <InfoIcon className="size-4" />, info: <InfoIcon className="size-4" />,
warning: <TriangleAlertIcon className="size-4" />, warning: <TriangleAlertIcon className="size-4" />,
error: <OctagonXIcon className="size-4" />, error: <OctagonXIcon className="size-4" />,
loading: <Loader2Icon className="size-4 animate-spin" />, loading: <Loader2Icon className="size-4 animate-spin" />,
}} }}
style={ style={
{ {
"--normal-bg": "var(--popover)", "--normal-bg": "var(--popover)",
"--normal-text": "var(--popover-foreground)", "--normal-text": "var(--popover-foreground)",
"--normal-border": "var(--border)", "--normal-border": "var(--border)",
"--border-radius": "var(--radius)", "--border-radius": "var(--radius)",
} as React.CSSProperties } as React.CSSProperties
} }
toastOptions={{ toastOptions={{
classNames: { classNames: {
toast: "cn-toast", toast: "cn-toast",
}, },
}} }}
{...props} {...props}
/> />
); );
}; };
export { Toaster }; export { Toaster };

View File

@@ -3,7 +3,7 @@ import { createServerFn } from "@tanstack/react-start";
import { authMiddleware } from "@/middleware/auth"; import { authMiddleware } from "@/middleware/auth";
export const getUser = createServerFn({ method: "GET" }) export const getUser = createServerFn({ method: "GET" })
.middleware([authMiddleware]) .middleware([authMiddleware])
.handler(async ({ context }) => { .handler(async ({ context }) => {
return context.session; return context.session;
}); });

View File

@@ -1 +1,63 @@
@import "tailwindcss"; @import "tailwindcss";
@import url("https://fonts.cdnfonts.com/css/intro");
/* Intro font family */
@font-face {
font-family: "Intro";
src: local("Intro"), local("Intro Regular");
font-weight: 400;
font-style: normal;
}
/* Smooth scrolling for the entire page */
html {
scroll-behavior: smooth;
}
/* Hide scrollbar but keep functionality */
html {
scrollbar-width: thin;
scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
}
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.2);
border-radius: 3px;
}
/* Sticky scroll container with snap points */
.sticky-scroll-container {
height: 400vh; /* 4 sections x 100vh */
position: relative;
}
.sticky-section {
position: sticky;
top: 0;
height: 100vh;
width: 100%;
}
/* Scroll snap for the whole page - mandatory snapping to closest section */
html {
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
}
.snap-section {
scroll-snap-align: start;
scroll-snap-stop: always;
}
/* Ensure snap works consistently in both directions */
.snap-section {
scroll-margin-top: 0;
}

View File

@@ -1,6 +1,6 @@
import { clsx, type ClassValue } from "clsx"; import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)); return twMerge(clsx(inputs));
} }

View File

@@ -1,11 +1,13 @@
import { auth } from "@kk/auth"; import { auth } from "@kk/auth";
import { createMiddleware } from "@tanstack/react-start"; import { createMiddleware } from "@tanstack/react-start";
export const authMiddleware = createMiddleware().server(async ({ next, request }) => { export const authMiddleware = createMiddleware().server(
const session = await auth.api.getSession({ async ({ next, request }) => {
headers: request.headers, const session = await auth.api.getSession({
}); headers: request.headers,
return next({ });
context: { session }, return next({
}); context: { session },
}); });
},
);

View File

@@ -7,22 +7,22 @@ import { routeTree } from "./routeTree.gen";
import { orpc, queryClient } from "./utils/orpc"; import { orpc, queryClient } from "./utils/orpc";
export const getRouter = () => { export const getRouter = () => {
const router = createTanStackRouter({ const router = createTanStackRouter({
routeTree, routeTree,
scrollRestoration: true, scrollRestoration: true,
defaultPreloadStaleTime: 0, defaultPreloadStaleTime: 0,
context: { orpc, queryClient }, context: { orpc, queryClient },
defaultPendingComponent: () => <Loader />, defaultPendingComponent: () => <Loader />,
defaultNotFoundComponent: () => <div>Not Found</div>, defaultNotFoundComponent: () => <div>Not Found</div>,
Wrap: ({ children }) => ( Wrap: ({ children }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider> <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
), ),
}); });
return router; return router;
}; };
declare module "@tanstack/react-router" { declare module "@tanstack/react-router" {
interface Register { interface Register {
router: ReturnType<typeof getRouter>; router: ReturnType<typeof getRouter>;
} }
} }

View File

@@ -2,14 +2,14 @@ import { auth } from "@kk/auth";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/api/auth/$")({ export const Route = createFileRoute("/api/auth/$")({
server: { server: {
handlers: { handlers: {
GET: ({ request }) => { GET: ({ request }) => {
return auth.handler(request); return auth.handler(request);
}, },
POST: ({ request }) => { POST: ({ request }) => {
return auth.handler(request); return auth.handler(request);
}, },
}, },
}, },
}); });

View File

@@ -8,51 +8,51 @@ import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
const rpcHandler = new RPCHandler(appRouter, { const rpcHandler = new RPCHandler(appRouter, {
interceptors: [ interceptors: [
onError((error) => { onError((error) => {
console.error(error); console.error(error);
}), }),
], ],
}); });
const apiHandler = new OpenAPIHandler(appRouter, { const apiHandler = new OpenAPIHandler(appRouter, {
plugins: [ plugins: [
new OpenAPIReferencePlugin({ new OpenAPIReferencePlugin({
schemaConverters: [new ZodToJsonSchemaConverter()], schemaConverters: [new ZodToJsonSchemaConverter()],
}), }),
], ],
interceptors: [ interceptors: [
onError((error) => { onError((error) => {
console.error(error); console.error(error);
}), }),
], ],
}); });
async function handle({ request }: { request: Request }) { async function handle({ request }: { request: Request }) {
const rpcResult = await rpcHandler.handle(request, { const rpcResult = await rpcHandler.handle(request, {
prefix: "/api/rpc", prefix: "/api/rpc",
context: await createContext({ req: request }), context: await createContext({ req: request }),
}); });
if (rpcResult.response) return rpcResult.response; if (rpcResult.response) return rpcResult.response;
const apiResult = await apiHandler.handle(request, { const apiResult = await apiHandler.handle(request, {
prefix: "/api/rpc/api-reference", prefix: "/api/rpc/api-reference",
context: await createContext({ req: request }), context: await createContext({ req: request }),
}); });
if (apiResult.response) return apiResult.response; if (apiResult.response) return apiResult.response;
return new Response("Not found", { status: 404 }); return new Response("Not found", { status: 404 });
} }
export const Route = createFileRoute("/api/rpc/$")({ export const Route = createFileRoute("/api/rpc/$")({
server: { server: {
handlers: { handlers: {
HEAD: handle, HEAD: handle,
GET: handle, GET: handle,
POST: handle, POST: handle,
PUT: handle, PUT: handle,
PATCH: handle, PATCH: handle,
DELETE: handle, DELETE: handle,
}, },
}, },
}); });

View File

@@ -1,5 +1,6 @@
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import ArtForms from "@/components/homepage/ArtForms";
import EventRegistrationForm from "@/components/homepage/EventRegistrationForm"; import EventRegistrationForm from "@/components/homepage/EventRegistrationForm";
import Footer from "@/components/homepage/Footer"; import Footer from "@/components/homepage/Footer";
import Hero from "@/components/homepage/Hero"; import Hero from "@/components/homepage/Hero";
@@ -11,11 +12,14 @@ export const Route = createFileRoute("/")({
function HomePage() { function HomePage() {
return ( return (
<main> <div className="relative">
<Hero /> <main className="relative">
<Info /> <Hero />
<EventRegistrationForm /> <Info />
<Footer /> <ArtForms />
</main> <EventRegistrationForm />
<Footer />
</main>
</div>
); );
} }

View File

@@ -1,9 +1,8 @@
import type { RouterClient } from "@orpc/server";
import { createContext } from "@kk/api/context"; import { createContext } from "@kk/api/context";
import { appRouter } from "@kk/api/routers/index"; import { appRouter } from "@kk/api/routers/index";
import { createORPCClient } from "@orpc/client"; import { createORPCClient } from "@orpc/client";
import { RPCLink } from "@orpc/client/fetch"; import { RPCLink } from "@orpc/client/fetch";
import type { RouterClient } from "@orpc/server";
import { createRouterClient } from "@orpc/server"; import { createRouterClient } from "@orpc/server";
import { createTanstackQueryUtils } from "@orpc/tanstack-query"; import { createTanstackQueryUtils } from "@orpc/tanstack-query";
import { QueryCache, QueryClient } from "@tanstack/react-query"; import { QueryCache, QueryClient } from "@tanstack/react-query";
@@ -12,39 +11,39 @@ import { getRequest } from "@tanstack/react-start/server";
import { toast } from "sonner"; import { toast } from "sonner";
export const queryClient = new QueryClient({ export const queryClient = new QueryClient({
queryCache: new QueryCache({ queryCache: new QueryCache({
onError: (error, query) => { onError: (error, query) => {
toast.error(`Error: ${error.message}`, { toast.error(`Error: ${error.message}`, {
action: { action: {
label: "retry", label: "retry",
onClick: query.invalidate, onClick: query.invalidate,
}, },
}); });
}, },
}), }),
}); });
const getORPCClient = createIsomorphicFn() const getORPCClient = createIsomorphicFn()
.server(() => .server(() =>
createRouterClient(appRouter, { createRouterClient(appRouter, {
context: async () => { context: async () => {
return createContext({ req: getRequest() }); return createContext({ req: getRequest() });
}, },
}), }),
) )
.client((): RouterClient<typeof appRouter> => { .client((): RouterClient<typeof appRouter> => {
const link = new RPCLink({ const link = new RPCLink({
url: `${window.location.origin}/api/rpc`, url: `${window.location.origin}/api/rpc`,
fetch(url, options) { fetch(url, options) {
return fetch(url, { return fetch(url, {
...options, ...options,
credentials: "include", credentials: "include",
}); });
}, },
}); });
return createORPCClient(link); return createORPCClient(link);
}); });
export const client: RouterClient<typeof appRouter> = getORPCClient(); export const client: RouterClient<typeof appRouter> = getORPCClient();

View File

@@ -1,28 +1,28 @@
{ {
"include": ["**/*.ts", "**/*.tsx"], "include": ["**/*.ts", "**/*.tsx"],
"compilerOptions": { "compilerOptions": {
"target": "ES2022", "target": "ES2022",
"jsx": "react-jsx", "jsx": "react-jsx",
"module": "ESNext", "module": "ESNext",
"lib": ["ES2022", "DOM", "DOM.Iterable"], "lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["vite/client"], "types": ["vite/client"],
/* Bundler mode */ /* Bundler mode */
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
"noEmit": true, "noEmit": true,
/* Linting */ /* Linting */
"skipLibCheck": true, "skipLibCheck": true,
"strict": true, "strict": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true, "noUncheckedSideEffectImports": true,
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"]
} }
} }
} }

View File

@@ -6,8 +6,14 @@ import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths"; import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({ export default defineConfig({
plugins: [tsconfigPaths(), tailwindcss(), tanstackStart(), viteReact(), alchemy()], plugins: [
server: { tsconfigPaths(),
port: 3001, tailwindcss(),
}, tanstackStart(),
viteReact(),
alchemy(),
],
server: {
port: 3001,
},
}); });

View File

@@ -1,76 +1,76 @@
{ {
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json", "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"vcs": { "vcs": {
"enabled": false, "enabled": false,
"clientKind": "git", "clientKind": "git",
"useIgnoreFile": false "useIgnoreFile": false
}, },
"files": { "files": {
"ignoreUnknown": false, "ignoreUnknown": false,
"includes": [ "includes": [
"**", "**",
"!**/.next", "!**/.next",
"!**/dist", "!**/dist",
"!**/.turbo", "!**/.turbo",
"!**/dev-dist", "!**/dev-dist",
"!**/.zed", "!**/.zed",
"!**/.vscode", "!**/.vscode",
"!**/routeTree.gen.ts", "!**/routeTree.gen.ts",
"!**/src-tauri", "!**/src-tauri",
"!**/.nuxt", "!**/.nuxt",
"!bts.jsonc", "!bts.jsonc",
"!**/.expo", "!**/.expo",
"!**/.wrangler", "!**/.wrangler",
"!**/.alchemy", "!**/.alchemy",
"!**/.svelte-kit", "!**/.svelte-kit",
"!**/wrangler.jsonc", "!**/wrangler.jsonc",
"!**/.source", "!**/.source",
"!**/convex/_generated" "!**/convex/_generated"
] ]
}, },
"formatter": { "formatter": {
"enabled": true, "enabled": true,
"indentStyle": "tab" "indentStyle": "tab"
}, },
"assist": { "actions": { "source": { "organizeImports": "on" } } }, "assist": { "actions": { "source": { "organizeImports": "on" } } },
"linter": { "linter": {
"enabled": true, "enabled": true,
"rules": { "rules": {
"recommended": true, "recommended": true,
"correctness": { "correctness": {
"useExhaustiveDependencies": "info" "useExhaustiveDependencies": "info"
}, },
"nursery": { "nursery": {
"useSortedClasses": { "useSortedClasses": {
"level": "warn", "level": "warn",
"fix": "safe", "fix": "safe",
"options": { "options": {
"functions": ["clsx", "cva", "cn"] "functions": ["clsx", "cva", "cn"]
} }
} }
}, },
"style": { "style": {
"noParameterAssign": "error", "noParameterAssign": "error",
"useAsConstAssertion": "error", "useAsConstAssertion": "error",
"useDefaultParameterLast": "error", "useDefaultParameterLast": "error",
"useEnumInitializers": "error", "useEnumInitializers": "error",
"useSelfClosingElements": "error", "useSelfClosingElements": "error",
"useSingleVarDeclarator": "error", "useSingleVarDeclarator": "error",
"noUnusedTemplateLiteral": "error", "noUnusedTemplateLiteral": "error",
"useNumberNamespace": "error", "useNumberNamespace": "error",
"noInferrableTypes": "error", "noInferrableTypes": "error",
"noUselessElse": "error" "noUselessElse": "error"
} }
} }
}, },
"javascript": { "javascript": {
"formatter": { "formatter": {
"quoteStyle": "double" "quoteStyle": "double"
} }
}, },
"css": { "css": {
"parser": { "parser": {
"tailwindDirectives": true "tailwindDirectives": true
} }
} }
} }

116
bun.lock
View File

@@ -31,6 +31,8 @@
"@orpc/server": "catalog:", "@orpc/server": "catalog:",
"@orpc/tanstack-query": "^1.12.2", "@orpc/tanstack-query": "^1.12.2",
"@orpc/zod": "catalog:", "@orpc/zod": "catalog:",
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@tailwindcss/vite": "^4.1.8", "@tailwindcss/vite": "^4.1.8",
"@tanstack/react-form": "^1.28.0", "@tanstack/react-form": "^1.28.0",
"@tanstack/react-query": "^5.80.6", "@tanstack/react-query": "^5.80.6",
@@ -51,6 +53,7 @@
"sonner": "^2.0.3", "sonner": "^2.0.3",
"tailwind-merge": "^3.3.1", "tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.3", "tailwindcss": "^4.1.3",
"three": "^0.183.1",
"tw-animate-css": "^1.2.5", "tw-animate-css": "^1.2.5",
"vite-tsconfig-paths": "^5.1.4", "vite-tsconfig-paths": "^5.1.4",
"zod": "catalog:", "zod": "catalog:",
@@ -64,6 +67,7 @@
"@testing-library/react": "^16.2.0", "@testing-library/react": "^16.2.0",
"@types/react": "19.2.7", "@types/react": "19.2.7",
"@types/react-dom": "19.2.3", "@types/react-dom": "19.2.3",
"@types/three": "^0.183.1",
"@vitejs/plugin-react": "^5.0.4", "@vitejs/plugin-react": "^5.0.4",
"alchemy": "catalog:", "alchemy": "catalog:",
"jsdom": "^26.0.0", "jsdom": "^26.0.0",
@@ -356,6 +360,8 @@
"@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="], "@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="],
"@dimforge/rapier3d-compat": ["@dimforge/rapier3d-compat@0.12.0", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.52.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.2", "which": "^4.0.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w=="], "@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.52.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.2", "which": "^4.0.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w=="],
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="], "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
@@ -544,8 +550,12 @@
"@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.22", "", { "os": "win32", "cpu": "x64" }, "sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA=="], "@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.22", "", { "os": "win32", "cpu": "x64" }, "sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA=="],
"@mediapipe/tasks-vision": ["@mediapipe/tasks-vision@0.10.17", "", {}, "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg=="],
"@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-qOdO524oPMkUsOJTrsH9vz/HN3B5pKyW+9zIW51A9kDMVe7ON70drz1ouoyoyOcfzc+oxhkQ6jWmbyKnlWmYqA=="], "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-qOdO524oPMkUsOJTrsH9vz/HN3B5pKyW+9zIW51A9kDMVe7ON70drz1ouoyoyOcfzc+oxhkQ6jWmbyKnlWmYqA=="],
"@monogrid/gainmap-js": ["@monogrid/gainmap-js@3.4.0", "", { "dependencies": { "promise-worker-transferable": "^1.0.4" }, "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg=="],
"@mswjs/interceptors": ["@mswjs/interceptors@0.41.3", "", { "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" } }, "sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA=="], "@mswjs/interceptors": ["@mswjs/interceptors@0.41.3", "", { "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" } }, "sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA=="],
"@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="], "@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="],
@@ -640,6 +650,10 @@
"@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="],
"@react-three/drei": ["@react-three/drei@10.7.7", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mediapipe/tasks-vision": "0.10.17", "@monogrid/gainmap-js": "^3.0.6", "@use-gesture/react": "^10.3.1", "camera-controls": "^3.1.0", "cross-env": "^7.0.3", "detect-gpu": "^5.0.56", "glsl-noise": "^0.0.0", "hls.js": "^1.5.17", "maath": "^0.10.8", "meshline": "^3.3.1", "stats-gl": "^2.2.8", "stats.js": "^0.17.0", "suspend-react": "^0.1.3", "three-mesh-bvh": "^0.8.3", "three-stdlib": "^2.35.6", "troika-three-text": "^0.52.4", "tunnel-rat": "^0.1.2", "use-sync-external-store": "^1.4.0", "utility-types": "^3.11.0", "zustand": "^5.0.1" }, "peerDependencies": { "@react-three/fiber": "^9.0.0", "react": "^19", "react-dom": "^19", "three": ">=0.159" }, "optionalPeers": ["react-dom"] }, "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ=="],
"@react-three/fiber": ["@react-three/fiber@9.5.0", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-use-measure": "^2.1.7", "scheduler": "^0.27.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": ">=19 <19.3", "react-dom": ">=19 <19.3", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA=="],
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
@@ -866,7 +880,7 @@
"@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.162.6", "", { "dependencies": { "@tanstack/router-core": "1.162.6" } }, "sha512-Ry/z1tMyEgAearn1dug3Whb/p1X86QErNV+trtDxf+r6Dzt636+eu0biiSuoQxDN7HQe417LB3IUhx4/uFrC2A=="], "@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.162.6", "", { "dependencies": { "@tanstack/router-core": "1.162.6" } }, "sha512-Ry/z1tMyEgAearn1dug3Whb/p1X86QErNV+trtDxf+r6Dzt636+eu0biiSuoQxDN7HQe417LB3IUhx4/uFrC2A=="],
"@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="], "@tanstack/store": ["@tanstack/store@0.9.1", "", {}, "sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg=="],
"@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.161.4", "", {}, "sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w=="], "@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.161.4", "", {}, "sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w=="],
@@ -876,6 +890,8 @@
"@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="], "@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="],
"@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="],
"@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="],
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
@@ -886,22 +902,40 @@
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
"@types/draco3d": ["@types/draco3d@1.4.10", "", {}, "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/node": ["@types/node@22.19.11", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w=="], "@types/node": ["@types/node@22.19.11", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w=="],
"@types/offscreencanvas": ["@types/offscreencanvas@2019.7.3", "", {}, "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A=="],
"@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="], "@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
"@types/react-reconciler": ["@types/react-reconciler@0.28.9", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="],
"@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="],
"@types/statuses": ["@types/statuses@2.0.6", "", {}, "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA=="], "@types/statuses": ["@types/statuses@2.0.6", "", {}, "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA=="],
"@types/three": ["@types/three@0.183.1", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": ">=0.5.17", "@webgpu/types": "*", "fflate": "~0.8.2", "meshoptimizer": "~1.0.1" } }, "sha512-f2Pu5Hrepfgavttdye3PsH5RWyY/AvdZQwIVhrc4uNtvF7nOWJacQKcoVJn0S4f0yYbmAE6AR+ve7xDcuYtMGw=="],
"@types/validate-npm-package-name": ["@types/validate-npm-package-name@4.0.2", "", {}, "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw=="], "@types/validate-npm-package-name": ["@types/validate-npm-package-name@4.0.2", "", {}, "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw=="],
"@types/webxr": ["@types/webxr@0.5.24", "", {}, "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg=="],
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
"@use-gesture/core": ["@use-gesture/core@10.3.1", "", {}, "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw=="],
"@use-gesture/react": ["@use-gesture/react@10.3.1", "", { "dependencies": { "@use-gesture/core": "10.3.1" }, "peerDependencies": { "react": ">= 16.8.0" } }, "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g=="],
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.4", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.4", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA=="],
"@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="],
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
"acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
@@ -934,6 +968,8 @@
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="], "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="],
"before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="], "before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="],
@@ -942,6 +978,8 @@
"better-call": ["better-call@1.1.8", "", { "dependencies": { "@better-auth/utils": "^0.3.0", "@better-fetch/fetch": "^1.1.4", "rou3": "^0.7.10", "set-cookie-parser": "^2.7.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw=="], "better-call": ["better-call@1.1.8", "", { "dependencies": { "@better-auth/utils": "^0.3.0", "@better-fetch/fetch": "^1.1.4", "rou3": "^0.7.10", "set-cookie-parser": "^2.7.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw=="],
"bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
"blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="],
@@ -958,6 +996,8 @@
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
@@ -970,6 +1010,8 @@
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
"camera-controls": ["camera-controls@3.1.2", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA=="],
"caniuse-lite": ["caniuse-lite@1.0.30001774", "", {}, "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA=="], "caniuse-lite": ["caniuse-lite@1.0.30001774", "", {}, "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA=="],
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
@@ -1018,6 +1060,8 @@
"cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="],
"cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
@@ -1054,6 +1098,8 @@
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
"detect-gpu": ["detect-gpu@5.0.70", "", { "dependencies": { "webgl-constants": "^1.1.1" } }, "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w=="],
"detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="], "detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="],
"diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], "diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="],
@@ -1070,6 +1116,8 @@
"dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="], "dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
"draco3d": ["draco3d@1.5.7", "", {}, "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ=="],
"drizzle-kit": ["drizzle-kit@0.31.9", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "esbuild-register": "^3.5.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-GViD3IgsXn7trFyBUUHyTFBpH/FsHTxYJ66qdbVggxef4UBPHRYxQaRzYLTuekYnk9i5FIEL9pbBIwMqX/Uwrg=="], "drizzle-kit": ["drizzle-kit@0.31.9", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "esbuild-register": "^3.5.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-GViD3IgsXn7trFyBUUHyTFBpH/FsHTxYJ66qdbVggxef4UBPHRYxQaRzYLTuekYnk9i5FIEL9pbBIwMqX/Uwrg=="],
"drizzle-orm": ["drizzle-orm@0.45.1", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA=="], "drizzle-orm": ["drizzle-orm@0.45.1", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA=="],
@@ -1150,6 +1198,8 @@
"fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="],
"fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="],
"figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="], "figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="],
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
@@ -1198,6 +1248,8 @@
"globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="], "globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="],
"glsl-noise": ["glsl-noise@0.0.0", "", {}, "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w=="],
"goober": ["goober@2.1.18", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw=="], "goober": ["goober@2.1.18", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
@@ -1216,6 +1268,8 @@
"headers-polyfill": ["headers-polyfill@4.0.3", "", {}, "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ=="], "headers-polyfill": ["headers-polyfill@4.0.3", "", {}, "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ=="],
"hls.js": ["hls.js@1.6.15", "", {}, "sha512-E3a5VwgXimGHwpRGV+WxRTKeSp2DW5DI5MWv34ulL3t5UNmyJWCQ1KmLEHbYzcfThfXG8amBL+fCYPneGHC4VA=="],
"hono": ["hono@4.12.2", "", {}, "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg=="], "hono": ["hono@4.12.2", "", {}, "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg=="],
"html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="], "html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="],
@@ -1232,6 +1286,8 @@
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
@@ -1272,7 +1328,7 @@
"is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="],
"is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], "is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="],
"is-regexp": ["is-regexp@3.1.0", "", {}, "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA=="], "is-regexp": ["is-regexp@3.1.0", "", {}, "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA=="],
@@ -1288,6 +1344,8 @@
"isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="], "isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="],
"its-fine": ["its-fine@2.0.0", "", { "dependencies": { "@types/react-reconciler": "^0.28.9" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng=="],
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
@@ -1364,6 +1422,8 @@
"lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
"maath": ["maath@0.10.8", "", { "peerDependencies": { "@types/three": ">=0.134.0", "three": ">=0.134.0" } }, "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g=="],
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
@@ -1376,6 +1436,10 @@
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
"meshline": ["meshline@3.3.1", "", { "peerDependencies": { "three": ">=0.137" } }, "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ=="],
"meshoptimizer": ["meshoptimizer@1.0.1", "", {}, "sha512-Vix+QlA1YYT3FwmBBZ+49cE5y/b+pRrcXKqGpS5ouh33d3lSp2PoTpCw19E0cKDFWalembrHnIaZetf27a+W2g=="],
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
@@ -1486,6 +1550,8 @@
"postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], "postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
"potpack": ["potpack@1.0.2", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="],
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="], "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
@@ -1498,6 +1564,8 @@
"promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="], "promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="],
"promise-worker-transferable": ["promise-worker-transferable@1.0.4", "", { "dependencies": { "is-promise": "^2.1.0", "lie": "^3.0.2" } }, "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw=="],
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
"proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="],
@@ -1524,6 +1592,8 @@
"react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="], "react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
"react-use-measure": ["react-use-measure@2.1.7", "", { "peerDependencies": { "react": ">=16.13", "react-dom": ">=16.13" }, "optionalPeers": ["react-dom"] }, "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg=="],
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
@@ -1614,6 +1684,10 @@
"srvx": ["srvx@0.11.7", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-p9qj9wkv/MqG1VoJpOsqXv1QcaVcYRk7ifsC6i3TEwDXFyugdhJN4J3KzQPZq2IJJ2ZCt7ASOB++85pEK38jRw=="], "srvx": ["srvx@0.11.7", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-p9qj9wkv/MqG1VoJpOsqXv1QcaVcYRk7ifsC6i3TEwDXFyugdhJN4J3KzQPZq2IJJ2ZCt7ASOB++85pEK38jRw=="],
"stats-gl": ["stats-gl@2.4.2", "", { "dependencies": { "@types/three": "*", "three": "^0.170.0" } }, "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ=="],
"stats.js": ["stats.js@0.17.0", "", {}, "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw=="],
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="], "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
@@ -1640,6 +1714,8 @@
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"suspend-react": ["suspend-react@0.1.3", "", { "peerDependencies": { "react": ">=17.0" } }, "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ=="],
"symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="], "symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
"tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="], "tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="],
@@ -1652,6 +1728,12 @@
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
"three": ["three@0.183.1", "", {}, "sha512-Psv6bbd3d/M/01MT2zZ+VmD0Vj2dbWTNhfe4CuSg7w5TuW96M3NOyCVuh9SZQ05CpGmD7NEcJhZw4GVjhCYxfQ=="],
"three-mesh-bvh": ["three-mesh-bvh@0.8.3", "", { "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg=="],
"three-stdlib": ["three-stdlib@2.36.1", "", { "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", "@types/webxr": "^0.5.2", "draco3d": "^1.4.1", "fflate": "^0.6.9", "potpack": "^1.0.1" }, "peerDependencies": { "three": ">=0.128.0" } }, "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg=="],
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
"tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="], "tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="],
@@ -1672,6 +1754,12 @@
"tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], "tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
"troika-three-text": ["troika-three-text@0.52.4", "", { "dependencies": { "bidi-js": "^1.0.2", "troika-three-utils": "^0.52.4", "troika-worker-utils": "^0.52.0", "webgl-sdf-generator": "1.1.1" }, "peerDependencies": { "three": ">=0.125.0" } }, "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg=="],
"troika-three-utils": ["troika-three-utils@0.52.4", "", { "peerDependencies": { "three": ">=0.125.0" } }, "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A=="],
"troika-worker-utils": ["troika-worker-utils@0.52.0", "", {}, "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw=="],
"ts-morph": ["ts-morph@26.0.0", "", { "dependencies": { "@ts-morph/common": "~0.27.0", "code-block-writer": "^13.0.3" } }, "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug=="], "ts-morph": ["ts-morph@26.0.0", "", { "dependencies": { "@ts-morph/common": "~0.27.0", "code-block-writer": "^13.0.3" } }, "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug=="],
"tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="], "tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
@@ -1682,6 +1770,8 @@
"tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="], "tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="],
"tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="],
"turbo": ["turbo@2.8.10", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.10", "turbo-darwin-arm64": "2.8.10", "turbo-linux-64": "2.8.10", "turbo-linux-arm64": "2.8.10", "turbo-windows-64": "2.8.10", "turbo-windows-arm64": "2.8.10" }, "bin": { "turbo": "bin/turbo" } }, "sha512-OxbzDES66+x7nnKGg2MwBA1ypVsZoDTLHpeaP4giyiHSixbsiTaMyeJqbEyvBdp5Cm28fc+8GG6RdQtic0ijwQ=="], "turbo": ["turbo@2.8.10", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.10", "turbo-darwin-arm64": "2.8.10", "turbo-linux-64": "2.8.10", "turbo-linux-arm64": "2.8.10", "turbo-windows-64": "2.8.10", "turbo-windows-arm64": "2.8.10" }, "bin": { "turbo": "bin/turbo" } }, "sha512-OxbzDES66+x7nnKGg2MwBA1ypVsZoDTLHpeaP4giyiHSixbsiTaMyeJqbEyvBdp5Cm28fc+8GG6RdQtic0ijwQ=="],
"turbo-darwin-64": ["turbo-darwin-64@2.8.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-A03fXh+B7S8mL3PbdhTd+0UsaGrhfyPkODvzBDpKRY7bbeac4MDFpJ7I+Slf2oSkCEeSvHKR7Z4U71uKRUfX7g=="], "turbo-darwin-64": ["turbo-darwin-64@2.8.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-A03fXh+B7S8mL3PbdhTd+0UsaGrhfyPkODvzBDpKRY7bbeac4MDFpJ7I+Slf2oSkCEeSvHKR7Z4U71uKRUfX7g=="],
@@ -1730,6 +1820,8 @@
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="],
"validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", {}, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="], "validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", {}, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="],
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
@@ -1748,6 +1840,10 @@
"web-vitals": ["web-vitals@5.1.0", "", {}, "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg=="], "web-vitals": ["web-vitals@5.1.0", "", {}, "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg=="],
"webgl-constants": ["webgl-constants@1.1.1", "", {}, "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="],
"webgl-sdf-generator": ["webgl-sdf-generator@1.1.1", "", {}, "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA=="],
"webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
@@ -1804,6 +1900,8 @@
"zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
"zustand": ["zustand@5.0.11", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg=="],
"@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
"@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
@@ -1858,9 +1956,11 @@
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@tanstack/form-core/@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="],
"@tanstack/react-router/@tanstack/react-store": ["@tanstack/react-store@0.9.1", "", { "dependencies": { "@tanstack/store": "0.9.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-YzJLnRvy5lIEFTLWBAZmcOjK3+2AepnBv/sr6NZmiqJvq7zTQggyK99Gw8fqYdMdHPQWXjz0epFKJXC+9V2xDA=="], "@tanstack/react-router/@tanstack/react-store": ["@tanstack/react-store@0.9.1", "", { "dependencies": { "@tanstack/store": "0.9.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-YzJLnRvy5lIEFTLWBAZmcOjK3+2AepnBv/sr6NZmiqJvq7zTQggyK99Gw8fqYdMdHPQWXjz0epFKJXC+9V2xDA=="],
"@tanstack/router-core/@tanstack/store": ["@tanstack/store@0.9.1", "", {}, "sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg=="], "@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="],
"@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
@@ -1932,6 +2032,8 @@
"restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
"router/is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
"router/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], "router/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
"shadcn/open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], "shadcn/open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="],
@@ -1944,14 +2046,20 @@
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"stats-gl/three": ["three@0.170.0", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="],
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
"three-stdlib/fflate": ["fflate@0.6.10", "", {}, "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg=="],
"tsx/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], "tsx/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
"tunnel-rat/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="],
"vite/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], "vite/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
"wrangler/@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.14.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20260218.0" }, "optionalPeers": ["workerd"] }, "sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg=="], "wrangler/@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.14.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20260218.0" }, "optionalPeers": ["workerd"] }, "sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg=="],
@@ -2046,8 +2154,6 @@
"@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], "@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
"@tanstack/react-router/@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.9.1", "", {}, "sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg=="],
"cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],

View File

@@ -1,27 +1,27 @@
{ {
"$schema": "https://opencode.ai/config.json", "$schema": "https://opencode.ai/config.json",
"mcp": { "mcp": {
"context7": { "context7": {
"type": "local", "type": "local",
"command": ["npx", "-y", "@upstash/context7-mcp"], "command": ["npx", "-y", "@upstash/context7-mcp"],
"enabled": true, "enabled": true,
"environment": {} "environment": {}
}, },
"cloudflare-docs": { "cloudflare-docs": {
"type": "remote", "type": "remote",
"url": "https://docs.mcp.cloudflare.com/sse", "url": "https://docs.mcp.cloudflare.com/sse",
"enabled": true "enabled": true
}, },
"shadcn": { "shadcn": {
"type": "local", "type": "local",
"command": ["npx", "-y", "shadcn@latest", "mcp"], "command": ["npx", "-y", "shadcn@latest", "mcp"],
"enabled": true, "enabled": true,
"environment": {} "environment": {}
}, },
"better-auth": { "better-auth": {
"type": "remote", "type": "remote",
"url": "https://mcp.inkeep.com/better-auth/mcp", "url": "https://mcp.inkeep.com/better-auth/mcp",
"enabled": true "enabled": true
} }
} }
} }

View File

@@ -1,54 +1,54 @@
{ {
"name": "kk", "name": "kk",
"private": true, "private": true,
"workspaces": { "workspaces": {
"packages": [ "packages": [
"apps/*", "apps/*",
"packages/*" "packages/*"
], ],
"catalog": { "catalog": {
"dotenv": "^17.2.2", "dotenv": "^17.2.2",
"zod": "^4.1.13", "zod": "^4.1.13",
"typescript": "^5", "typescript": "^5",
"@types/node": "^22.13.14", "@types/node": "^22.13.14",
"@libsql/client": "0.15.15", "@libsql/client": "0.15.15",
"libsql": "0.5.22", "libsql": "0.5.22",
"@orpc/server": "^1.12.2", "@orpc/server": "^1.12.2",
"@orpc/client": "^1.12.2", "@orpc/client": "^1.12.2",
"@orpc/openapi": "^1.12.2", "@orpc/openapi": "^1.12.2",
"@orpc/zod": "^1.12.2", "@orpc/zod": "^1.12.2",
"better-auth": "^1.4.18", "better-auth": "^1.4.18",
"alchemy": "^0.82.1" "alchemy": "^0.82.1"
} }
}, },
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "turbo dev", "dev": "turbo dev",
"build": "turbo build", "build": "turbo build",
"check-types": "turbo check-types", "check-types": "turbo check-types",
"dev:native": "turbo -F native dev", "dev:native": "turbo -F native dev",
"dev:web": "turbo -F web dev", "dev:web": "turbo -F web dev",
"db:push": "turbo -F @kk/db db:push", "db:push": "turbo -F @kk/db db:push",
"db:studio": "turbo -F @kk/db db:studio", "db:studio": "turbo -F @kk/db db:studio",
"db:generate": "turbo -F @kk/db db:generate", "db:generate": "turbo -F @kk/db db:generate",
"db:migrate": "turbo -F @kk/db db:migrate", "db:migrate": "turbo -F @kk/db db:migrate",
"db:local": "turbo -F @kk/db db:local", "db:local": "turbo -F @kk/db db:local",
"deploy": "turbo -F @kk/infra deploy", "deploy": "turbo -F @kk/infra deploy",
"destroy": "turbo -F @kk/infra destroy", "destroy": "turbo -F @kk/infra destroy",
"check": "biome check --write ." "check": "biome check --write ."
}, },
"dependencies": { "dependencies": {
"@kk/env": "workspace:*", "@kk/env": "workspace:*",
"dotenv": "catalog:", "dotenv": "catalog:",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^2.2.0", "@biomejs/biome": "^2.2.0",
"@cloudflare/workers-types": "^4.20251213.0", "@cloudflare/workers-types": "^4.20251213.0",
"@kk/config": "workspace:*", "@kk/config": "workspace:*",
"@types/node": "catalog:", "@types/node": "catalog:",
"turbo": "^2.6.3", "turbo": "^2.6.3",
"typescript": "catalog:" "typescript": "catalog:"
}, },
"packageManager": "bun@1.3.8" "packageManager": "bun@1.3.8"
} }

View File

@@ -1,28 +1,28 @@
{ {
"name": "@kk/api", "name": "@kk/api",
"type": "module", "type": "module",
"exports": { "exports": {
".": { ".": {
"default": "./src/index.ts" "default": "./src/index.ts"
}, },
"./*": { "./*": {
"default": "./src/*.ts" "default": "./src/*.ts"
} }
}, },
"scripts": {}, "scripts": {},
"dependencies": { "dependencies": {
"@kk/auth": "workspace:*", "@kk/auth": "workspace:*",
"@kk/db": "workspace:*", "@kk/db": "workspace:*",
"@kk/env": "workspace:*", "@kk/env": "workspace:*",
"@orpc/client": "catalog:", "@orpc/client": "catalog:",
"@orpc/openapi": "catalog:", "@orpc/openapi": "catalog:",
"@orpc/server": "catalog:", "@orpc/server": "catalog:",
"@orpc/zod": "catalog:", "@orpc/zod": "catalog:",
"dotenv": "catalog:", "dotenv": "catalog:",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@kk/config": "workspace:*", "@kk/config": "workspace:*",
"typescript": "catalog:" "typescript": "catalog:"
} }
} }

View File

@@ -1,12 +1,12 @@
import { auth } from "@kk/auth"; import { auth } from "@kk/auth";
export async function createContext({ req }: { req: Request }) { export async function createContext({ req }: { req: Request }) {
const session = await auth.api.getSession({ const session = await auth.api.getSession({
headers: req.headers, headers: req.headers,
}); });
return { return {
session, session,
}; };
} }
export type Context = Awaited<ReturnType<typeof createContext>>; export type Context = Awaited<ReturnType<typeof createContext>>;

View File

@@ -7,14 +7,14 @@ export const o = os.$context<Context>();
export const publicProcedure = o; export const publicProcedure = o;
const requireAuth = o.middleware(async ({ context, next }) => { const requireAuth = o.middleware(async ({ context, next }) => {
if (!context.session?.user) { if (!context.session?.user) {
throw new ORPCError("UNAUTHORIZED"); throw new ORPCError("UNAUTHORIZED");
} }
return next({ return next({
context: { context: {
session: context.session, session: context.session,
}, },
}); });
}); });
export const protectedProcedure = publicProcedure.use(requireAuth); export const protectedProcedure = publicProcedure.use(requireAuth);

View File

@@ -3,15 +3,15 @@ import type { RouterClient } from "@orpc/server";
import { protectedProcedure, publicProcedure } from "../index"; import { protectedProcedure, publicProcedure } from "../index";
export const appRouter = { export const appRouter = {
healthCheck: publicProcedure.handler(() => { healthCheck: publicProcedure.handler(() => {
return "OK"; return "OK";
}), }),
privateData: protectedProcedure.handler(({ context }) => { privateData: protectedProcedure.handler(({ context }) => {
return { return {
message: "This is private", message: "This is private",
user: context.session?.user, user: context.session?.user,
}; };
}), }),
}; };
export type AppRouter = typeof appRouter; export type AppRouter = typeof appRouter;
export type AppRouterClient = RouterClient<typeof appRouter>; export type AppRouterClient = RouterClient<typeof appRouter>;

View File

@@ -1,10 +1,10 @@
{ {
"extends": "@kk/config/tsconfig.base.json", "extends": "@kk/config/tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"sourceMap": true, "sourceMap": true,
"outDir": "dist", "outDir": "dist",
"composite": true "composite": true
} }
} }

View File

@@ -1,24 +1,24 @@
{ {
"name": "@kk/auth", "name": "@kk/auth",
"type": "module", "type": "module",
"exports": { "exports": {
".": { ".": {
"default": "./src/index.ts" "default": "./src/index.ts"
}, },
"./*": { "./*": {
"default": "./src/*.ts" "default": "./src/*.ts"
} }
}, },
"scripts": {}, "scripts": {},
"dependencies": { "dependencies": {
"@kk/db": "workspace:*", "@kk/db": "workspace:*",
"@kk/env": "workspace:*", "@kk/env": "workspace:*",
"better-auth": "catalog:", "better-auth": "catalog:",
"dotenv": "catalog:", "dotenv": "catalog:",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@kk/config": "workspace:*", "@kk/config": "workspace:*",
"typescript": "catalog:" "typescript": "catalog:"
} }
} }

View File

@@ -6,14 +6,14 @@ import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { tanstackStartCookies } from "better-auth/tanstack-start"; import { tanstackStartCookies } from "better-auth/tanstack-start";
export const auth = betterAuth({ export const auth = betterAuth({
database: drizzleAdapter(db, { database: drizzleAdapter(db, {
provider: "sqlite", provider: "sqlite",
schema: schema, schema: schema,
}), }),
trustedOrigins: [env.CORS_ORIGIN], trustedOrigins: [env.CORS_ORIGIN],
emailAndPassword: { emailAndPassword: {
enabled: true, enabled: true,
}, },
plugins: [tanstackStartCookies()], plugins: [tanstackStartCookies()],
}); });

View File

@@ -1,10 +1,10 @@
{ {
"extends": "@kk/config/tsconfig.base.json", "extends": "@kk/config/tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"sourceMap": true, "sourceMap": true,
"outDir": "dist", "outDir": "dist",
"composite": true "composite": true
} }
} }

View File

@@ -1,5 +1,5 @@
{ {
"name": "@kk/config", "name": "@kk/config",
"version": "0.0.0", "version": "0.0.0",
"private": true "private": true
} }

View File

@@ -1,22 +1,22 @@
{ {
"$schema": "https://json.schemastore.org/tsconfig", "$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": { "compilerOptions": {
"target": "ESNext", "target": "ESNext",
"module": "ESNext", "module": "ESNext",
"moduleResolution": "bundler", "moduleResolution": "bundler",
"lib": ["ESNext"], "lib": ["ESNext"],
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
"strict": true, "strict": true,
"skipLibCheck": true, "skipLibCheck": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"isolatedModules": true, "isolatedModules": true,
"noUncheckedIndexedAccess": true, "noUncheckedIndexedAccess": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"types": ["node", "@cloudflare/workers-types"] "types": ["node", "@cloudflare/workers-types"]
} }
} }

View File

@@ -2,14 +2,14 @@ import dotenv from "dotenv";
import { defineConfig } from "drizzle-kit"; import { defineConfig } from "drizzle-kit";
dotenv.config({ dotenv.config({
path: "../../apps/web/.env", path: "../../apps/web/.env",
}); });
export default defineConfig({ export default defineConfig({
schema: "./src/schema", schema: "./src/schema",
out: "./src/migrations", out: "./src/migrations",
dialect: "turso", dialect: "turso",
dbCredentials: { dbCredentials: {
url: process.env.DATABASE_URL || "", url: process.env.DATABASE_URL || "",
}, },
}); });

View File

@@ -1,32 +1,32 @@
{ {
"name": "@kk/db", "name": "@kk/db",
"type": "module", "type": "module",
"exports": { "exports": {
".": { ".": {
"default": "./src/index.ts" "default": "./src/index.ts"
}, },
"./*": { "./*": {
"default": "./src/*.ts" "default": "./src/*.ts"
} }
}, },
"scripts": { "scripts": {
"db:local": "turso dev --db-file local.db", "db:local": "turso dev --db-file local.db",
"db:push": "drizzle-kit push", "db:push": "drizzle-kit push",
"db:generate": "drizzle-kit generate", "db:generate": "drizzle-kit generate",
"db:studio": "drizzle-kit studio", "db:studio": "drizzle-kit studio",
"db:migrate": "drizzle-kit migrate" "db:migrate": "drizzle-kit migrate"
}, },
"dependencies": { "dependencies": {
"@kk/env": "workspace:*", "@kk/env": "workspace:*",
"@libsql/client": "catalog:", "@libsql/client": "catalog:",
"dotenv": "catalog:", "dotenv": "catalog:",
"drizzle-orm": "^0.45.1", "drizzle-orm": "^0.45.1",
"libsql": "catalog:", "libsql": "catalog:",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@kk/config": "workspace:*", "@kk/config": "workspace:*",
"drizzle-kit": "^0.31.8", "drizzle-kit": "^0.31.8",
"typescript": "catalog:" "typescript": "catalog:"
} }
} }

View File

@@ -5,7 +5,7 @@ import { drizzle } from "drizzle-orm/libsql";
import * as schema from "./schema"; import * as schema from "./schema";
const client = createClient({ const client = createClient({
url: env.DATABASE_URL, url: env.DATABASE_URL,
}); });
export const db = drizzle({ client, schema }); export const db = drizzle({ client, schema });

View File

@@ -1,105 +1,107 @@
import { relations, sql } from "drizzle-orm"; import { relations, sql } from "drizzle-orm";
import { sqliteTable, text, integer, index } from "drizzle-orm/sqlite-core"; import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", { export const user = sqliteTable("user", {
id: text("id").primaryKey(), id: text("id").primaryKey(),
name: text("name").notNull(), name: text("name").notNull(),
email: text("email").notNull().unique(), email: text("email").notNull().unique(),
emailVerified: integer("email_verified", { mode: "boolean" }).default(false).notNull(), emailVerified: integer("email_verified", { mode: "boolean" })
image: text("image"), .default(false)
createdAt: integer("created_at", { mode: "timestamp_ms" }) .notNull(),
.default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) image: text("image"),
.notNull(), createdAt: integer("created_at", { mode: "timestamp_ms" })
updatedAt: integer("updated_at", { mode: "timestamp_ms" }) .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
.default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) .notNull(),
.$onUpdate(() => /* @__PURE__ */ new Date()) updatedAt: integer("updated_at", { mode: "timestamp_ms" })
.notNull(), .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
.$onUpdate(() => /* @__PURE__ */ new Date())
.notNull(),
}); });
export const session = sqliteTable( export const session = sqliteTable(
"session", "session",
{ {
id: text("id").primaryKey(), id: text("id").primaryKey(),
expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(), expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
token: text("token").notNull().unique(), token: text("token").notNull().unique(),
createdAt: integer("created_at", { mode: "timestamp_ms" }) createdAt: integer("created_at", { mode: "timestamp_ms" })
.default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
.notNull(), .notNull(),
updatedAt: integer("updated_at", { mode: "timestamp_ms" }) updatedAt: integer("updated_at", { mode: "timestamp_ms" })
.$onUpdate(() => /* @__PURE__ */ new Date()) .$onUpdate(() => /* @__PURE__ */ new Date())
.notNull(), .notNull(),
ipAddress: text("ip_address"), ipAddress: text("ip_address"),
userAgent: text("user_agent"), userAgent: text("user_agent"),
userId: text("user_id") userId: text("user_id")
.notNull() .notNull()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
}, },
(table) => [index("session_userId_idx").on(table.userId)], (table) => [index("session_userId_idx").on(table.userId)],
); );
export const account = sqliteTable( export const account = sqliteTable(
"account", "account",
{ {
id: text("id").primaryKey(), id: text("id").primaryKey(),
accountId: text("account_id").notNull(), accountId: text("account_id").notNull(),
providerId: text("provider_id").notNull(), providerId: text("provider_id").notNull(),
userId: text("user_id") userId: text("user_id")
.notNull() .notNull()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
accessToken: text("access_token"), accessToken: text("access_token"),
refreshToken: text("refresh_token"), refreshToken: text("refresh_token"),
idToken: text("id_token"), idToken: text("id_token"),
accessTokenExpiresAt: integer("access_token_expires_at", { accessTokenExpiresAt: integer("access_token_expires_at", {
mode: "timestamp_ms", mode: "timestamp_ms",
}), }),
refreshTokenExpiresAt: integer("refresh_token_expires_at", { refreshTokenExpiresAt: integer("refresh_token_expires_at", {
mode: "timestamp_ms", mode: "timestamp_ms",
}), }),
scope: text("scope"), scope: text("scope"),
password: text("password"), password: text("password"),
createdAt: integer("created_at", { mode: "timestamp_ms" }) createdAt: integer("created_at", { mode: "timestamp_ms" })
.default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
.notNull(), .notNull(),
updatedAt: integer("updated_at", { mode: "timestamp_ms" }) updatedAt: integer("updated_at", { mode: "timestamp_ms" })
.$onUpdate(() => /* @__PURE__ */ new Date()) .$onUpdate(() => /* @__PURE__ */ new Date())
.notNull(), .notNull(),
}, },
(table) => [index("account_userId_idx").on(table.userId)], (table) => [index("account_userId_idx").on(table.userId)],
); );
export const verification = sqliteTable( export const verification = sqliteTable(
"verification", "verification",
{ {
id: text("id").primaryKey(), id: text("id").primaryKey(),
identifier: text("identifier").notNull(), identifier: text("identifier").notNull(),
value: text("value").notNull(), value: text("value").notNull(),
expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(), expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
createdAt: integer("created_at", { mode: "timestamp_ms" }) createdAt: integer("created_at", { mode: "timestamp_ms" })
.default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
.notNull(), .notNull(),
updatedAt: integer("updated_at", { mode: "timestamp_ms" }) updatedAt: integer("updated_at", { mode: "timestamp_ms" })
.default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
.$onUpdate(() => /* @__PURE__ */ new Date()) .$onUpdate(() => /* @__PURE__ */ new Date())
.notNull(), .notNull(),
}, },
(table) => [index("verification_identifier_idx").on(table.identifier)], (table) => [index("verification_identifier_idx").on(table.identifier)],
); );
export const userRelations = relations(user, ({ many }) => ({ export const userRelations = relations(user, ({ many }) => ({
sessions: many(session), sessions: many(session),
accounts: many(account), accounts: many(account),
})); }));
export const sessionRelations = relations(session, ({ one }) => ({ export const sessionRelations = relations(session, ({ one }) => ({
user: one(user, { user: one(user, {
fields: [session.userId], fields: [session.userId],
references: [user.id], references: [user.id],
}), }),
})); }));
export const accountRelations = relations(account, ({ one }) => ({ export const accountRelations = relations(account, ({ one }) => ({
user: one(user, { user: one(user, {
fields: [account.userId], fields: [account.userId],
references: [user.id], references: [user.id],
}), }),
})); }));

View File

@@ -1,2 +1 @@
export * from "./auth"; export * from "./auth";
export {};

View File

@@ -1,10 +1,10 @@
{ {
"extends": "@kk/config/tsconfig.base.json", "extends": "@kk/config/tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"sourceMap": true, "sourceMap": true,
"outDir": "dist", "outDir": "dist",
"composite": true "composite": true
} }
} }

View File

@@ -1,21 +1,21 @@
{ {
"name": "@kk/env", "name": "@kk/env",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"exports": { "exports": {
"./server": "./src/server.ts", "./server": "./src/server.ts",
"./web": "./src/web.ts" "./web": "./src/web.ts"
}, },
"dependencies": { "dependencies": {
"@t3-oss/env-core": "^0.13.1", "@t3-oss/env-core": "^0.13.1",
"dotenv": "catalog:", "dotenv": "catalog:",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@kk/config": "workspace:*", "@kk/config": "workspace:*",
"@kk/infra": "workspace:*", "@kk/infra": "workspace:*",
"@types/node": "catalog:", "@types/node": "catalog:",
"typescript": "catalog:" "typescript": "catalog:"
} }
} }

View File

@@ -3,13 +3,15 @@ import { createEnv } from "@t3-oss/env-core";
import { z } from "zod"; import { z } from "zod";
export const env = createEnv({ export const env = createEnv({
server: { server: {
DATABASE_URL: z.string().min(1), DATABASE_URL: z.string().min(1),
BETTER_AUTH_SECRET: z.string().min(32), BETTER_AUTH_SECRET: z.string().min(32),
BETTER_AUTH_URL: z.url(), BETTER_AUTH_URL: z.url(),
CORS_ORIGIN: z.url(), CORS_ORIGIN: z.url(),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"), NODE_ENV: z
}, .enum(["development", "production", "test"])
runtimeEnv: process.env, .default("development"),
emptyStringAsUndefined: true, },
runtimeEnv: process.env,
emptyStringAsUndefined: true,
}); });

View File

@@ -1,9 +1,9 @@
import { createEnv } from "@t3-oss/env-core"; import { createEnv } from "@t3-oss/env-core";
import { z } from "zod";
export const env = createEnv({ export const env = createEnv({
clientPrefix: "VITE_", clientPrefix: "VITE_",
client: {}, client: {},
runtimeEnv: (import.meta as any).env, // biome-ignore lint/suspicious/noExplicitAny: Vite's import.meta.env doesn't have proper types
emptyStringAsUndefined: true, runtimeEnv: (import.meta as any).env,
emptyStringAsUndefined: true,
}); });

View File

@@ -1,3 +1,3 @@
{ {
"extends": "@kk/config/tsconfig.base.json" "extends": "@kk/config/tsconfig.base.json"
} }

View File

@@ -7,14 +7,23 @@ config({ path: "../../apps/web/.env" });
const app = await alchemy("kk"); const app = await alchemy("kk");
// Helper function to get required env var
function getEnvVar(name: string): string {
const value = process.env[name];
if (!value) {
throw new Error(`Missing required environment variable: ${name}`);
}
return value;
}
export const web = await TanStackStart("web", { export const web = await TanStackStart("web", {
cwd: "../../apps/web", cwd: "../../apps/web",
bindings: { bindings: {
DATABASE_URL: alchemy.secret.env.DATABASE_URL!, DATABASE_URL: getEnvVar("DATABASE_URL"),
CORS_ORIGIN: alchemy.env.CORS_ORIGIN!, CORS_ORIGIN: getEnvVar("CORS_ORIGIN"),
BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!, BETTER_AUTH_SECRET: getEnvVar("BETTER_AUTH_SECRET"),
BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!, BETTER_AUTH_URL: getEnvVar("BETTER_AUTH_URL"),
}, },
}); });
console.log(`Web -> ${web.url}`); console.log(`Web -> ${web.url}`);

View File

@@ -1,19 +1,19 @@
{ {
"name": "@kk/infra", "name": "@kk/infra",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "alchemy dev", "dev": "alchemy dev",
"deploy": "alchemy deploy", "deploy": "alchemy deploy",
"destroy": "alchemy destroy" "destroy": "alchemy destroy"
}, },
"dependencies": { "dependencies": {
"dotenv": "catalog:", "dotenv": "catalog:",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@kk/config": "workspace:*", "@kk/config": "workspace:*",
"alchemy": "catalog:", "alchemy": "catalog:",
"typescript": "catalog:" "typescript": "catalog:"
} }
} }

View File

@@ -1,30 +1,30 @@
{ {
"version": 1, "version": 1,
"skills": { "skills": {
"better-auth-best-practices": { "better-auth-best-practices": {
"source": "better-auth/skills", "source": "better-auth/skills",
"sourceType": "github", "sourceType": "github",
"computedHash": "a24359053259e55a75972cab4bf0b0e37e1393bac5f3756ec2e3a7b4b3778d2a" "computedHash": "a24359053259e55a75972cab4bf0b0e37e1393bac5f3756ec2e3a7b4b3778d2a"
}, },
"turborepo": { "turborepo": {
"source": "vercel/turborepo", "source": "vercel/turborepo",
"sourceType": "github", "sourceType": "github",
"computedHash": "47e8b1424c901cd0f5530328cb7448c8828b19063997ea4a4b03164bbdc0fd39" "computedHash": "47e8b1424c901cd0f5530328cb7448c8828b19063997ea4a4b03164bbdc0fd39"
}, },
"vercel-composition-patterns": { "vercel-composition-patterns": {
"source": "vercel-labs/agent-skills", "source": "vercel-labs/agent-skills",
"sourceType": "github", "sourceType": "github",
"computedHash": "f98931159fa9c7fed043bcd18a891a46dcf89ababa38df13a4c5b7b30dc0ce07" "computedHash": "f98931159fa9c7fed043bcd18a891a46dcf89ababa38df13a4c5b7b30dc0ce07"
}, },
"vercel-react-best-practices": { "vercel-react-best-practices": {
"source": "vercel-labs/agent-skills", "source": "vercel-labs/agent-skills",
"sourceType": "github", "sourceType": "github",
"computedHash": "4365be772fd3b41994a72ad478472c6d680678e7f3859860ab010e9c46e48ee0" "computedHash": "4365be772fd3b41994a72ad478472c6d680678e7f3859860ab010e9c46e48ee0"
}, },
"web-design-guidelines": { "web-design-guidelines": {
"source": "vercel-labs/agent-skills", "source": "vercel-labs/agent-skills",
"sourceType": "github", "sourceType": "github",
"computedHash": "a6a44d5498f7e8f68289902f3dedfc6f38ae0cee1e96527c80724cf27f727c2a" "computedHash": "a6a44d5498f7e8f68289902f3dedfc6f38ae0cee1e96527c80724cf27f727c2a"
} }
} }
} }

View File

@@ -1,3 +1,3 @@
{ {
"extends": "@kk/config/tsconfig.base.json" "extends": "@kk/config/tsconfig.base.json"
} }

View File

@@ -1,44 +1,44 @@
{ {
"$schema": "https://turbo.build/schema.json", "$schema": "https://turbo.build/schema.json",
"ui": "tui", "ui": "tui",
"tasks": { "tasks": {
"build": { "build": {
"dependsOn": ["^build"], "dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"], "inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": ["dist/**"] "outputs": ["dist/**"]
}, },
"lint": { "lint": {
"dependsOn": ["^lint"] "dependsOn": ["^lint"]
}, },
"check-types": { "check-types": {
"dependsOn": ["^check-types"] "dependsOn": ["^check-types"]
}, },
"dev": { "dev": {
"cache": false, "cache": false,
"persistent": true "persistent": true
}, },
"db:push": { "db:push": {
"cache": false "cache": false
}, },
"db:generate": { "db:generate": {
"cache": false "cache": false
}, },
"db:migrate": { "db:migrate": {
"cache": false, "cache": false,
"persistent": true "persistent": true
}, },
"db:studio": { "db:studio": {
"cache": false, "cache": false,
"persistent": true "persistent": true
}, },
"db:local": { "db:local": {
"cache": false "cache": false
}, },
"deploy": { "deploy": {
"cache": false "cache": false
}, },
"destroy": { "destroy": {
"cache": false "cache": false
} }
} }
} }