Compare commits

..
77 changed files with 690 additions and 3421 deletions

1
.148
View file

@ -1 +0,0 @@
148

4
.dockerignore Normal file
View file

@ -0,0 +1,4 @@
.react-router
build
node_modules
README.md

View file

@ -1,38 +0,0 @@
on: [push]
jobs:
print-content:
runs-on: ubuntu-latest
steps:
- name: Run uname
run: uname -a
- name: checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install rsync
run: |
sudo apt-get update && sudo apt-get install -y rsync openssh-client
chown -R $(id -u):$(id -g) $GITHUB_WORKSPACE
- name: Setup SSH Key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
- name: Build
run: |
bun i
bun run build
- name: Deploy
run: |
rsync -avz --delete -e "ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no" "$GITHUB_WORKSPACE/dist/" imnyang@10.11.8.101:/var/static/imnya.ng/
- name: Cleanup
if: always()
run: |
rm -rf ~/.ssh/id_ed25519

26
.gitignore vendored
View file

@ -1,24 +1,6 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store .DS_Store
/node_modules/
# jetbrains setting folder # React Router
.idea/ /.react-router/
/build/

View file

@ -1,4 +0,0 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored
View file

@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

22
Dockerfile Normal file
View file

@ -0,0 +1,22 @@
FROM node:20-alpine AS development-dependencies-env
COPY . /app
WORKDIR /app
RUN npm ci
FROM node:20-alpine AS production-dependencies-env
COPY ./package.json package-lock.json /app/
WORKDIR /app
RUN npm ci --omit=dev
FROM node:20-alpine AS build-env
COPY . /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN npm run build
FROM node:20-alpine
COPY ./package.json package-lock.json /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["npm", "run", "start"]

25
Dockerfile.bun Normal file
View file

@ -0,0 +1,25 @@
FROM oven/bun:1 AS dependencies-env
COPY . /app
FROM dependencies-env AS development-dependencies-env
COPY ./package.json bun.lockb /app/
WORKDIR /app
RUN bun i --frozen-lockfile
FROM dependencies-env AS production-dependencies-env
COPY ./package.json bun.lockb /app/
WORKDIR /app
RUN bun i --production
FROM dependencies-env AS build-env
COPY ./package.json bun.lockb /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN bun run build
FROM dependencies-env
COPY ./package.json bun.lockb /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["bun", "run", "start"]

26
Dockerfile.pnpm Normal file
View file

@ -0,0 +1,26 @@
FROM node:20-alpine AS dependencies-env
RUN npm i -g pnpm
COPY . /app
FROM dependencies-env AS development-dependencies-env
COPY ./package.json pnpm-lock.yaml /app/
WORKDIR /app
RUN pnpm i --frozen-lockfile
FROM dependencies-env AS production-dependencies-env
COPY ./package.json pnpm-lock.yaml /app/
WORKDIR /app
RUN pnpm i --prod --frozen-lockfile
FROM dependencies-env AS build-env
COPY ./package.json pnpm-lock.yaml /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN pnpm build
FROM dependencies-env
COPY ./package.json pnpm-lock.yaml /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["pnpm", "start"]

115
README.md
View file

@ -1,43 +1,100 @@
# Astro Starter Kit: Minimal # Welcome to React Router!
```sh A modern, production-ready template for building full-stack React applications using React Router.
bun create astro@latest -- --template minimal
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/remix-run/react-router-templates/tree/main/default)
## Features
- 🚀 Server-side rendering
- ⚡️ Hot Module Replacement (HMR)
- 📦 Asset bundling and optimization
- 🔄 Data loading and mutations
- 🔒 TypeScript by default
- 🎉 TailwindCSS for styling
- 📖 [React Router docs](https://reactrouter.com/)
## Getting Started
### Installation
Install the dependencies:
```bash
npm install
``` ```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! ### Development
## 🚀 Project Structure Start the development server with HMR:
Inside of your Astro project, you'll see the following folders and files: ```bash
npm run dev
```text
/
├── public/
├── src/
│ └── pages/
│ └── index.astro
└── package.json
``` ```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. Your application will be available at `http://localhost:5173`.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. ## Building for Production
Any static assets, like images, can be placed in the `public/` directory. Create a production build:
## 🧞 Commands ```bash
npm run build
```
All commands are run from the root of the project, from a terminal: ## Deployment
| Command | Action | ### Docker Deployment
| :------------------------ | :----------------------------------------------- |
| `bun install` | Installs dependencies |
| `bun dev` | Starts local dev server at `localhost:4321` |
| `bun build` | Build your production site to `./dist/` |
| `bun preview` | Preview your build locally, before deploying |
| `bun astro ...` | Run CLI commands like `astro add`, `astro check` |
| `bun astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? This template includes three Dockerfiles optimized for different package managers:
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). - `Dockerfile` - for npm
- `Dockerfile.pnpm` - for pnpm
- `Dockerfile.bun` - for bun
To build and run using Docker:
```bash
# For npm
docker build -t my-app .
# For pnpm
docker build -f Dockerfile.pnpm -t my-app .
# For bun
docker build -f Dockerfile.bun -t my-app .
# Run the container
docker run -p 3000:3000 my-app
```
The containerized application can be deployed to any platform that supports Docker, including:
- AWS ECS
- Google Cloud Run
- Azure Container Apps
- Digital Ocean App Platform
- Fly.io
- Railway
### DIY Deployment
If you're familiar with deploying Node applications, the built-in app server is production-ready.
Make sure to deploy the output of `npm run build`
```
├── package.json
├── package-lock.json (or pnpm-lock.yaml, or bun.lockb)
├── build/
│ ├── client/ # Static assets
│ └── server/ # Server-side code
```
## Styling
This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.
---
Built with ❤️ using React Router.

9
app/app.css Normal file
View file

@ -0,0 +1,9 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
html, body {
background-color: #0a0a0a;
color-scheme: dark;
height: 100%;
}

View file

@ -0,0 +1,71 @@
import { useEffect, useRef } from "react";
const TABS = [
{ label: "Home" },
{ label: "Timeline" }
];
interface AnimatedTabsProps {
activeTab: string;
setActiveTab: (tab: string) => void;
}
export function AnimatedTabs({ activeTab, setActiveTab }: AnimatedTabsProps) {
const containerRef = useRef<HTMLDivElement>(null);
const activeTabRef = useRef<HTMLButtonElement>(null);
useEffect(() => {
const container = containerRef.current;
if (container && activeTab) {
const activeTabElement = activeTabRef.current;
if (activeTabElement) {
const { offsetLeft, offsetWidth } = activeTabElement;
const clipLeft = offsetLeft;
const clipRight = offsetLeft + offsetWidth;
container.style.clipPath = `inset(0 ${Number(100 - (clipRight / container.offsetWidth) * 100).toFixed()}% 0 ${Number((clipLeft / container.offsetWidth) * 100).toFixed()}% round 17px)`;
}
}
}, [activeTab, activeTabRef, containerRef]);
return (
<div className="relative mx-auto flex w-fit flex-col items-center rounded-full">
<div
ref={containerRef}
className="absolute z-10 w-full overflow-hidden [clip-path:inset(0px_75%_0px_0%_round_17px)] [transition:clip-path_0.25s_ease]"
>
<div className="relative flex w-full justify-center bg-white">
{TABS.map((tab, index) => (
<button
key={index}
onClick={() => setActiveTab(tab.label)}
className="flex h-8 items-center rounded-full p-3 text-sm font-medium text-black"
tabIndex={-1}
>
{tab.label}
</button>
))}
</div>
</div>
<div className="relative flex w-full justify-center">
{TABS.map(({ label }, index) => {
const isActive = activeTab === label;
return (
<button
key={index}
ref={isActive ? activeTabRef : null}
onClick={() => setActiveTab(label)}
className="flex h-8 items-center rounded-full p-3 text-sm font-medium text-neutral-300"
>
{label}
</button>
);
})}
</div>
</div>
);
}

View file

@ -0,0 +1,83 @@
/*
All rights reserved to NY0510 (As Known As NY64), 2024
https://github.com/NY0510/ny64.kr/blob/main/src/components/ProfileSection.tsx
*/
import { useState, useEffect } from 'react';
import { useMotionValue, motion, useMotionTemplate } from "framer-motion";
const birthday = new Date('2021-11-14');
export function TimeCounter() {
const mouseX = useMotionValue(0);
const mouseY = useMotionValue(0);
const background = useMotionTemplate`radial-gradient(200px circle at ${mouseX}px ${mouseY}px, rgba(38, 38, 38, 0.4), transparent 80%)`;
const [afterBirth, setAfterBirth] = useState<string>('');
const [tenThousands, setTenThousands] = useState<number>(0);
const [animate, setAnimate] = useState<boolean>(false);
useEffect(() => {
const interval = setInterval(() => {
const elapsed = new Date().getTime() - birthday.getTime();
setAfterBirth(elapsed.toLocaleString());
const newTenThousands = Math.floor(elapsed / 10000);
if (newTenThousands !== tenThousands) {
setTenThousands(newTenThousands);
setAnimate(true);
setTimeout(() => setAnimate(false), 200);
}
}, 1);
return () => clearInterval(interval);
}, [tenThousands]);
return (
<div
onMouseMove={(e) => {
const { left, top } = e.currentTarget.getBoundingClientRect();
mouseX.set(e.clientX - left);
mouseY.set(e.clientY - top);
}}
className="group relative w-full max-w-[350px] overflow-hidden rounded-xl bg-neutral-950"
title='암냥으로 활동한지'
>
<div className="absolute right-5 top-0 h-px w-80 bg-gradient-to-l from-transparent via-white/30 via-10% to-transparent" />
<motion.div
className="pointer-events-none absolute -inset-px rounded-xl opacity-0 transition duration-300 group-hover:opacity-100"
style={{
background: background,
}}
/>
<div className="relative flexflex-col gap-3 rounded-xl border border-white/10 px-4 py-5">
<div className="space-y-2">
<span> ~ </span>
<p className={`text-sm tabular-nums transition duration-200 ease-in-out ${animate ? 'text-neutral-100' : 'text-neutral-400'}`}>
{afterBirth} ms
</p>
</div>
</div>
</div>
);
/*
return (
<div className="group relative w-fit mx-auto grid overflow-hidden rounded-3xl px-6 py-3 shadow-[0_1000px_0_0_hsl(0_0%_20%)_inset] transition-colors duration-200">
<span>
<span className="spark mask-gradient absolute inset-0 h-[100%] w-[100%] animate-flip overflow-hidden rounded-3xl [mask:linear-gradient(white,_transparent_50%)] before:absolute before:aspect-square before:w-[200%] before:rotate-[-90deg] before:animate-rotate before:bg-[conic-gradient(from_0deg,transparent_0_340deg,white_360deg)] before:content-[''] before:[inset:0_auto_auto_50%] before:[translate:-50%_-15%]" />
</span>
<span className="backdrop absolute inset-px rounded-3xl bg-neutral-950 transition-colors duration-200" />
<span className="z-10 flex flex-col items-center gap-2">
<span> </span>
<span className={`tabular-nums transition duration-200 ease-in-out ${animate ? 'text-neutral-100' : 'text-neutral-400'}`}>
{afterBirth} ms
</span>
</span>
</div>
);*/
}

View file

@ -0,0 +1,52 @@
import { Link } from "react-router";
import { Link as LinkIcon } from "lucide-react";
const events = [
{ date: '2024-12-14', description: '2024 글로벌스타트업학교 K-청소년스타트업 경진대회 우수상 수상', category: "Award", link: "https://www.ncf.or.kr/projects/'2024-%EA%B8%80%EB%A1%9C%EB%B2%8C%EC%8A%A4%ED%83%80%ED%8A%B8%EC%97%85%ED%95%99%EA%B5%90-k-%EC%B2%AD%EC%86%8C%EB%85%84%EC%8A%A4%ED%83%80%ED%8A%B8%EC%97%85-%EA%B2%BD%EC%A7%84%EB%8C%80%ED%9A%8C'-%EC%B0%B8%EA%B0%80%EC%9E%90-%EB%AA%A8%EC%A7%91" },
{ date: '2024-12-07', description: '글로벌 스타트업 학교 팀 1위', category: "Award", link: 'https://blog.imnyang.xyz/blog/gss' },
{ date: '2024-12-07', description: '글로벌 스타트업 학교 개인 최우수상', category: "Award", link: 'https://blog.imnyang.xyz/blog/gss' },
{ date: '2024-08-18', description: '29회 해킹캠프 CTF 1위 (고민중독)', category: "Award", link: 'https://ctf.hackingcamp.org/' },
{ date: '2024-08-05', description: '29회 해킹캠프 선발', category: "Conference", link: 'https://hackingcamp.org/' },
{ date: '2024-08-01', description: '글로벌 스타트업 학교 2기 베트남 해외 연수 데모데이 대상 (1위)', category: "Award", link: 'http://ncf.or.kr' },
{ date: '2024-05-16', description: '글로벌 스타트업 학교 2기 합격', category: "Education", link: 'http://ncf.or.kr' },
{ date: '2024-05-11', description: 'LG AI 청소년 캠프 1기 LG 탐색상 수상', category: "Award", link: 'https://lgaiyouthcamp.or.kr/' },
{ date: '2024-05-11', description: 'LG AI 청소년 캠프 1기 수료', category: "Award", link: 'https://lgaiyouthcamp.or.kr/' },
{ date: '2024-04-22', description: '@isangjeong.today (인천상정중학교의 오늘 급식)', category: "Project", link: 'https://www.instagram.com/isangjeong.today/' },
{ date: '2024-03-24', description: 'Dreamhack #133', link: 'https://dreamhack.io/users/40116/wargame' },
{ date: '2024-03-24', description: 'Ubuntu Mirror [Not Working Now]', link: 'https://launchpad.net/ubuntu/+mirror/mirror.imnyang.xyz-release' },
{ date: '2024-03-24', description: '내 목소리로 AI Cover 만들기', category: "Project", link: 'https://colab.research.google.com/drive/1a4G4hD9huBeGRZhEL2HNDMpqSuf4y61k?usp=sharing' },
{ date: '2023-12-20', description: 'LG AI 청소년 캠프 1기 합격', category: "Education" },
{ date: '2023-11-14', description: '인천상정중학교 2023학년도 SW 문제 해결 활동 우수상(2위) 수여', category: "Award" },
{ date: '2023-11-01', description: '블로그 시작', link: 'https://blog.imnyang.xyz', category: "Project" },
{ date: '2023-09-02', description: '선린인터넷고등학교 제6회 소프트웨어나늠축제 Layer7 부서 과정 이수' },
{ date: '2023-07-24', description: '한국정보기술연구원이 주도하는 사이버 가디언즈 보안캠프 수료' },
{ date: '2023-05-15', description: '한국 코드페어 예선 진출' },
{ date: '2022-12-20', description: '2022 SW영재 창작대회 은상 수상'},
{ date: '2022-09-27', description: '2022 삼성 주니어 SW 창작대회 본선 진출' },
{ date: '2022-05-23', description: '2022학년도 석정초SW영재학급 첫 수업' },
{ date: '2022-07-26', description: '제 14회 맑은하늘 맑은웃음 공모전에서 맑은웃음상 수여' },
{ date: '2021-11-14', description: 'Become a ZEPETO Creator 이수' },
{ date: '2021-05-19', description: '소프트웨어와 전자신문이 주관한 소프트웨어재단 꿈찾기 캠프 이수' },
{ date: '2018-01-27', description: '제4회 맑은하늘 맑은웃음 어린이 문예공모전에서 위닉스상(2위) 수여' },
];
export default function TimelineComponents() {
return (
<div className="timeline text-white text-left">
{events.map((event, index) => (
<div key={index} className="flex flex-col gap-2 mb-3">
<p className="tabular-nums text-base text-gray-400">{event.date}</p>
<div className="flex items-center">
{event.link && (
<Link to={event.link} className="flex gap-2 text-base">
<span className="text-base">{event.description}</span>
<LinkIcon width={18} />
</Link>)
}
{!event.link && <span className="text-base">{event.description}</span>}
</div>
</div>
))}
</div>
);
}

76
app/root.tsx Normal file
View file

@ -0,0 +1,76 @@
import {
isRouteErrorResponse,
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "react-router";
import type { Route } from "./+types/root";
import stylesheet from "./app.css?url";
export const links: Route.LinksFunction = () => [
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
{
rel: "preconnect",
href: "https://fonts.gstatic.com",
crossOrigin: "anonymous",
},
{
rel: "stylesheet",
href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap",
},
{ rel: "stylesheet", href: stylesheet },
];
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
let message = "Oops!";
let details = "An unexpected error occurred.";
let stack: string | undefined;
if (isRouteErrorResponse(error)) {
message = error.status === 404 ? "404" : "Error";
details =
error.status === 404
? "The requested page could not be found."
: error.statusText || details;
} else if (import.meta.env.DEV && error && error instanceof Error) {
details = error.message;
stack = error.stack;
}
return (
<main className="pt-16 p-4 container mx-auto">
<h1>{message}</h1>
<p>{details}</p>
{stack && (
<pre className="w-full p-4 overflow-x-auto">
<code>{stack}</code>
</pre>
)}
</main>
);
}

6
app/routes.ts Normal file
View file

@ -0,0 +1,6 @@
import { type RouteConfig, index, route } from "@react-router/dev/routes";
export default [
index("routes/home.tsx"),
route("timeline", "./routes/timeline.tsx"),
] satisfies RouteConfig;

46
app/routes/home.tsx Normal file
View file

@ -0,0 +1,46 @@
import type { Route } from "./+types/home";
import React, { useState } from "react";
import { Link, useNavigate } from "react-router";
import { AnimatedTabs } from "~/components/AnimatedTabs";
import { TimeCounter } from "~/components/TimeCounter";
export function meta({}: Route.MetaArgs) {
return [
{ title: "New React Router App" },
{ name: "description", content: "Welcome to React Router!" },
];
}
export default function Home() {
const [activeTab, setActiveTab] = useState("Home");
const ref = React.useRef(null);
const navigate = useNavigate();
React.useEffect(() => {
if (activeTab === "Timeline") {
navigate("/timeline");
}
}, [activeTab, navigate]);
return (
<div ref={ref} className="flex flex-col w-full items-center">
<header className="w-full md:w-2/5 h-auto flex flex-row justify-between p-5">
<Link to="/" accessKey="h" title="💕 Alt + H" className="text-2xl">💕</Link>
<div className="flex items-center">
<AnimatedTabs activeTab={activeTab} setActiveTab={setActiveTab} />
</div>
</header>
<div id="top" className="w-auto text-center flex items-center justify-center flex-col gap-4">
<img src="https://f.imnya.ng/profile/34b47ba35448cc74a659bcec443c3fbc.webp" alt="imnyang" width={200} height={200} className="rounded-full" />
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="text-sm text-neutral-400">@imnyang</p>
</div>
<TimeCounter />
<h2 className="text-xl">{`Tab: ${activeTab}`}</h2>
</div>
</div>
);
}

51
app/routes/timeline.tsx Normal file
View file

@ -0,0 +1,51 @@
import type { Route } from "./+types/home";
import React, { useState } from "react";
import { Link, useNavigate } from "react-router";
import { AnimatedTabs } from "~/components/AnimatedTabs";
import { TimeCounter } from "~/components/TimeCounter";
import TimelineComponents from "~/components/TimelineComponents";
export function meta({}: Route.MetaArgs) {
return [
{ title: "New React Router App" },
{ name: "description", content: "Welcome to React Router!" },
];
}
export default function Timeline() {
const [activeTab, setActiveTab] = useState("Timeline");
const ref = React.useRef(null);
const navigate = useNavigate();
React.useEffect(() => {
if (activeTab === "Home") {
navigate("/");
}
}, [activeTab, navigate]);
return (
<div ref={ref} className="flex flex-col w-full items-center">
<header className="w-full md:w-2/5 h-auto flex flex-row justify-between p-5">
<Link to="/" accessKey="h" title="💕 Alt + H" className="text-2xl">💕</Link>
<div className="flex items-center">
<AnimatedTabs activeTab={activeTab} setActiveTab={setActiveTab} />
</div>
</header>
<div id="top" className="w-auto text-center flex items-center justify-center flex-col gap-4">
<img src="https://f.imnya.ng/profile/34b47ba35448cc74a659bcec443c3fbc.webp" alt="imnyang" width={200} height={200} className="rounded-full" />
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="text-sm text-neutral-400">@imnyang</p>
</div>
<TimeCounter />
<br />
<h1 className="text-2xl font-bold">Timeline</h1>
<br/>
<TimelineComponents />
</div>
</div>
);
}

6
app/utils/cn.ts Normal file
View file

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

View file

@ -1,10 +0,0 @@
// @ts-check
import { defineConfig } from "astro/config";
import tailwindcss from "@tailwindcss/vite";
// https://astro.build/config
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});

View file

@ -1,34 +0,0 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"includes": ["**", "!!**/dist"]
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}

698
bun.lock
View file

@ -1,698 +0,0 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "imnya-ng",
"dependencies": {
"@sun-typeface/suit": "^2.0.5",
"astro": "7.3.1",
"clsx": "^2.1.1",
"three": "^0.186.0",
},
"devDependencies": {
"@biomejs/biome": "2.5.12",
"@tailwindcss/vite": "^4.3.3",
"@types/three": "^0.185.4",
"tailwindcss": "^4.3.3",
},
},
},
"overrides": {
"@types/react": "19.2.2",
"@types/react-dom": "19.2.2",
},
"packages": {
"@astrojs/compiler-binding": ["@astrojs/compiler-binding@0.4.0", "", { "optionalDependencies": { "@astrojs/compiler-binding-darwin-arm64": "0.4.0", "@astrojs/compiler-binding-darwin-x64": "0.4.0", "@astrojs/compiler-binding-linux-arm64-gnu": "0.4.0", "@astrojs/compiler-binding-linux-arm64-musl": "0.4.0", "@astrojs/compiler-binding-linux-x64-gnu": "0.4.0", "@astrojs/compiler-binding-linux-x64-musl": "0.4.0", "@astrojs/compiler-binding-wasm32-wasi": "0.4.0", "@astrojs/compiler-binding-win32-arm64-msvc": "0.4.0", "@astrojs/compiler-binding-win32-x64-msvc": "0.4.0" } }, "sha512-x2RjDUuWfwLNtc3mjAdSRInwqh/rqbLar9cm/5FOMbHvmYZB7yfKewzSclAxWjIZsypJDXv1lhaP2WG+P8TK3g=="],
"@astrojs/compiler-binding-darwin-arm64": ["@astrojs/compiler-binding-darwin-arm64@0.4.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ZVUwHundaQyFNjE6uoa0usaC0WOCitDCLS/4mdb4rOiJXwVUuKJBMxI5WMzXLWmamsXtK/Z//ifLXvV5Yeh4Hw=="],
"@astrojs/compiler-binding-darwin-x64": ["@astrojs/compiler-binding-darwin-x64@0.4.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-FI6G8AY8u6fR1SI/QRR5yGMwtvZwP34CDmZpZ5HwJGa50UM1VISTLhqkhV4a476pmgd25X1Aur2dqw6hUnrlKA=="],
"@astrojs/compiler-binding-linux-arm64-gnu": ["@astrojs/compiler-binding-linux-arm64-gnu@0.4.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-lB9gLFJK7m82EnjaU8nlRBEfcwGNeHidW3sSjODTUjMNaoewVuUz9fwwdY5M4jiSXIqWLH3yl6TX8FTDKA74Sw=="],
"@astrojs/compiler-binding-linux-arm64-musl": ["@astrojs/compiler-binding-linux-arm64-musl@0.4.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-HPbvWqbxFxyaoQJhLxCaSjtYBx9KBo7JGVzEFZCmMl968a2PsSH0UfiODYgYPXofTOIsIH2aoCcrHXML0IA3ig=="],
"@astrojs/compiler-binding-linux-x64-gnu": ["@astrojs/compiler-binding-linux-x64-gnu@0.4.0", "", { "os": "linux", "cpu": "x64" }, "sha512-tQKolMxoJ/+0AmLWm1PmJ/i+z3i10ZU1bNuVjEDulCf48azEMtUNjTZgHJ5MPtpYRNc7dlETr8QujUfduzoC7Q=="],
"@astrojs/compiler-binding-linux-x64-musl": ["@astrojs/compiler-binding-linux-x64-musl@0.4.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5v5YymudsxMHp3NBLCS8BUlu5CRqeLtWD9cKS/4nIhIEHCbpz9okmVV6I0HWqmBAPhWYcDa3vw/vltYPrOQCTA=="],
"@astrojs/compiler-binding-wasm32-wasi": ["@astrojs/compiler-binding-wasm32-wasi@0.4.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.2.2" }, "cpu": "none" }, "sha512-m/phuH3x3PREvv1OnkM44NoPh4MatUadix1fB1u5SvMLCyDTUZykDJbKnWf1cjnYmHdlB8HcjTjl6JrCqAIXcw=="],
"@astrojs/compiler-binding-win32-arm64-msvc": ["@astrojs/compiler-binding-win32-arm64-msvc@0.4.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-B9zYf3okEY83kM8gydlpH2BHP00w4ifxPqlYlWrgTwuD6wnkrJDCwBlgy1q31cERjCJRXN1lrE2VmkLvFjv/6g=="],
"@astrojs/compiler-binding-win32-x64-msvc": ["@astrojs/compiler-binding-win32-x64-msvc@0.4.0", "", { "os": "win32", "cpu": "x64" }, "sha512-zB0Nrv0dGc0zZWPGDRmmETTPhDRqyZjAjk+gWMlVrJX5U89obpB3VUUE1ZiHxOCN5LQojeLK6O8L/dnoHolvNQ=="],
"@astrojs/compiler-rs": ["@astrojs/compiler-rs@0.4.0", "", { "dependencies": { "@astrojs/compiler-binding": "0.4.0" } }, "sha512-koVikeon1kreEy+/JzLQRy3vzHHQVOjycs4degg4vFufKApZOwMZvSSAEztYNhmcQVfNVsVZZI4cEge3cexAbQ=="],
"@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.11.0", "", { "dependencies": { "@types/hast": "^3.0.4", "@types/mdast": "^4.0.4", "js-yaml": "^4.3.0", "picomatch": "^4.0.4", "retext-smartypants": "^6.2.0", "shiki": "^4.0.2", "smol-toml": "^1.6.0", "unified": "^11.0.5" } }, "sha512-3rzxJ+xbo0+8YyqOzLziIN32wmsHdCjEVz2sGOpRxJ+Ben/KiLph4ItxBy1abEL+E8fkRzqjg0rfXmaHJGw9JA=="],
"@astrojs/markdown-satteri": ["@astrojs/markdown-satteri@0.4.0", "", { "dependencies": { "@astrojs/internal-helpers": "0.11.0", "@astrojs/prism": "4.0.2", "github-slugger": "^2.0.0", "satteri": "^0.10.3" } }, "sha512-wykOOW9KsUVcZweOpY/CeXpdKcCKZy6fQbdcteWFuI75+sQCiqxYM7VKsGa5b+aGl3cYQscFY37rsbbyal5MRw=="],
"@astrojs/prism": ["@astrojs/prism@4.0.2", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA=="],
"@astrojs/telemetry": ["@astrojs/telemetry@3.3.3", "", { "dependencies": { "ci-info": "^4.4.0", "dset": "^3.1.4", "is-docker": "^4.0.0", "package-manager-detector": "^1.6.0" } }, "sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ=="],
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="],
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="],
"@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="],
"@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="],
"@biomejs/biome": ["@biomejs/biome@2.5.12", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.12", "@biomejs/cli-darwin-x64": "2.5.12", "@biomejs/cli-linux-arm64": "2.5.12", "@biomejs/cli-linux-arm64-musl": "2.5.12", "@biomejs/cli-linux-x64": "2.5.12", "@biomejs/cli-linux-x64-musl": "2.5.12", "@biomejs/cli-win32-arm64": "2.5.12", "@biomejs/cli-win32-x64": "2.5.12" }, "bin": { "biome": "bin/biome" } }, "sha512-Lw4VHZRebrReBBnlHa12JQjnIBm3JJAA55PDB9LbBVBF0q4RYphm6KfmIjqtPhf61MxZ5Q9KoK8R8x+7per5Aw=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lCRY1rwgNeWNgTr4DI/u6ZwXTRwRLHAvbaio1YLLGS+4r1nhvB2ssyPqIpfUSmRveNfv0fn/N58C7CAdK2XVrg=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-vhPgwnh+6tN3ArdAXuET99xaNbFt7CG82Bqn+omHVLC5xdVx45JsYjGPmUIGNzjDek5XdNCP1HKksK7fn8+3bQ=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-2gp8aVwXYKdAtmBfRFCUuyDMcfN1ahHqUkGfLYrZlNRFmryMATLVvJgWKvyA8wu4Rwn5OSxM1UcUmOuOFNGeBQ=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-couHYjFLL5uuI8ne6zhT7KwEsXo5YP7ry/2xmEqah7qanu0YmfDi3mwJg47YXSuv/NpZj22CZzcRH/5c4gjPSQ=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.12", "", { "os": "linux", "cpu": "x64" }, "sha512-SnvOs3TSTiuia4SQOUNe1aWC9RT4+YkjcKnOhL/nsKOV0k5ycgBkDzF0lUxKn1V7Q8CLTRq6iV23ZAivHomRoA=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.12", "", { "os": "linux", "cpu": "x64" }, "sha512-8A0oDW58/w9f/PQNYuq0sGUZtGtGrkNF4Z6n0PUoXpLCshi85vtKTv1XSznQawhdE4MXJ8ufpzHXyLFe87M/+w=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-b9vtoZFsuZt1pdjNwJvXl0f+BpayRzV008uS2+JpmwIKdSE2qdu4A/l04FESwLoou5g2E/Qlec0xwJydZplH+A=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.12", "", { "os": "win32", "cpu": "x64" }, "sha512-B1R/l+CwEpKFSuqiwePzPNRk1EiJN8kc0UhdafNz6MZN9v5OFP9HYP1irptvWzHrwVI4blVNGMbxc5zt70m3IA=="],
"@bruits/satteri-darwin-arm64": ["@bruits/satteri-darwin-arm64@0.10.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA=="],
"@bruits/satteri-darwin-x64": ["@bruits/satteri-darwin-x64@0.10.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-IjnLe3nKspq6qaeqGgjT7MT8VrTV74yWRlaag7ZdNsI8TDAYZ0iPxMCo+9KQZHUk5EyVB+reBI/PFWL5KuFw9Q=="],
"@bruits/satteri-linux-arm64-gnu": ["@bruits/satteri-linux-arm64-gnu@0.10.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-glkYXZCJywjP13v67eAyAMSJdF+ncvEbYvgi/wOtffL9tQ27lr/zsyzUfgs+ovjJ9d8JNQKiXeiArJcX8PJL9w=="],
"@bruits/satteri-linux-arm64-musl": ["@bruits/satteri-linux-arm64-musl@0.10.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-yWdgG1g17Nh2QyGVlFUxGRa3FEFwiMcpZEyMNWkbM3deC94cmVc+/i9OuyFpdKuWo3GkgoCtYVOoxk1uCnCZIA=="],
"@bruits/satteri-linux-x64-gnu": ["@bruits/satteri-linux-x64-gnu@0.10.5", "", { "os": "linux", "cpu": "x64" }, "sha512-FVaLoPT1fBgGl0J+AYebyyXJYBachGl8Oyyrf1lye4RTqCB4S0Gwkj1uM9RJyThUOvx5VUmAT1CnNh1SFHA+kw=="],
"@bruits/satteri-linux-x64-musl": ["@bruits/satteri-linux-x64-musl@0.10.5", "", { "os": "linux", "cpu": "x64" }, "sha512-EHpVAx2bqW3GINHTKkljtxVfQmVDGWIuwOYOP5YghTj+0PkBa2o8oKPRtQ9Kbsr1Fye8jtUcDjhwj2jMNugZKg=="],
"@bruits/satteri-wasm32-wasi": ["@bruits/satteri-wasm32-wasi@0.10.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.2.3" }, "cpu": "none" }, "sha512-ypz8c/Zmipxp4IoeDa228Gstv6TLzVmNs3yC6wKCoNSOjx1iwpgzu87Y3hTkXFdwChVGU85qeUDuOIarGUZQLw=="],
"@bruits/satteri-win32-arm64-msvc": ["@bruits/satteri-win32-arm64-msvc@0.10.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-siTV88nb0LRqNpkL2gXboqCwVdq95sLtzMHS1/3eONV2gLbB3NAK46wmSMvCO/yquBvI2lvaFIfd8P12ecsxBw=="],
"@bruits/satteri-win32-x64-msvc": ["@bruits/satteri-win32-x64-msvc@0.10.5", "", { "os": "win32", "cpu": "x64" }, "sha512-C3IfPvfvMXmlzBxaMPKFS1XiuV9pu2mC7YqkPk7PSvTgPZ8gbdASIpHpztDLvTTQjqZ0z1Ol8tK5X+V6XXC0wQ=="],
"@capsizecss/unpack": ["@capsizecss/unpack@4.0.0", "", { "dependencies": { "fontkitten": "^1.0.0" } }, "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA=="],
"@clack/core": ["@clack/core@1.4.0", "", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-7Wctjq6f7c1CPz8sPpkwUnz8yRgVANkpNupb81q432FjcJg4l+Sw7XANdNSdWfAKq0IHI0JTcUeK5dxs/HrGPw=="],
"@clack/prompts": ["@clack/prompts@1.5.0", "", { "dependencies": { "@clack/core": "1.4.0", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-wKh+wTjmrUoUdkZg8KpJO5X+p9PWV+KE9mePseq9UYWkukgTKsGS47RRL2HstwVcvDQH+PenrPJWII8+MfiiyA=="],
"@dimforge/rapier3d-compat": ["@dimforge/rapier3d-compat@0.12.0", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
"@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="],
"@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="],
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="],
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="],
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="],
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="],
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA=="],
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.3" }, "os": "darwin", "cpu": "x64" }, "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw=="],
"@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.4", "", { "dependencies": { "@img/sharp-wasm32": "0.35.4" }, "os": "freebsd" }, "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA=="],
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg=="],
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw=="],
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA=="],
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A=="],
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w=="],
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.3", "", { "os": "linux", "cpu": "none" }, "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ=="],
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q=="],
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA=="],
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw=="],
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw=="],
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.3" }, "os": "linux", "cpu": "arm" }, "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A=="],
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.3" }, "os": "linux", "cpu": "arm64" }, "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ=="],
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ=="],
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.3" }, "os": "linux", "cpu": "none" }, "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA=="],
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.3" }, "os": "linux", "cpu": "s390x" }, "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ=="],
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.3" }, "os": "linux", "cpu": "x64" }, "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA=="],
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" }, "os": "linux", "cpu": "arm64" }, "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA=="],
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.3" }, "os": "linux", "cpu": "x64" }, "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg=="],
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.4", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA=="],
"@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.4", "", { "dependencies": { "@img/sharp-wasm32": "0.35.4" }, "cpu": "none" }, "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA=="],
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw=="],
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw=="],
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.4", "", { "os": "win32", "cpu": "x64" }, "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="],
"@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
"@oxc-project/types": ["@oxc-project/types@0.137.0", "", {}, "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA=="],
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.3", "", { "os": "android", "cpu": "arm64" }, "sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g=="],
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw=="],
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw=="],
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw=="],
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.3", "", { "os": "linux", "cpu": "arm" }, "sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg=="],
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA=="],
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w=="],
"@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw=="],
"@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA=="],
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.3", "", { "os": "linux", "cpu": "x64" }, "sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg=="],
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.3", "", { "os": "linux", "cpu": "x64" }, "sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g=="],
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.3", "", { "os": "none", "cpu": "arm64" }, "sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ=="],
"@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.3", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg=="],
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g=="],
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.3", "", { "os": "win32", "cpu": "x64" }, "sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA=="],
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="],
"@shikijs/core": ["@shikijs/core@4.1.0", "", { "dependencies": { "@shikijs/primitive": "4.1.0", "@shikijs/types": "4.1.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-jLJtSJeuFffqX6/inRE1zqU5aFv2hrszvYgq3OjbAgFRZiWv7abKMDdQzYxuSDfmUPQozZvI/kuy6VMTvnvqTQ=="],
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.1.0", "", { "dependencies": { "@shikijs/types": "4.1.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.6" } }, "sha512-YquhawCUgaBfhsS72e2Y/dI59gCBNPHu3fEO/tvLaXrTssxZrY5ddjtNLTwndrMgPo8b3IscE+xoICDzpTmlFQ=="],
"@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.1.0", "", { "dependencies": { "@shikijs/types": "4.1.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-axLpjVs45YBvvINa+dJF+NPW+KtFkNXsFr4SDw2BMj9GdeMnGxVB9PQb2xXlJYovslt/nz6giedAyOANkfc7hg=="],
"@shikijs/langs": ["@shikijs/langs@4.1.0", "", { "dependencies": { "@shikijs/types": "4.1.0" } }, "sha512-nwOMruEkbgdZfQ/b8CgpNBVOpvG1k0N5tbmgiFeqsan401+x3ILqlzZJowSla4Agmq4hG2Uf2wh5jLTEhR8VSg=="],
"@shikijs/primitive": ["@shikijs/primitive@4.1.0", "", { "dependencies": { "@shikijs/types": "4.1.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zx2/2Uwj2q9X3KSyYREEhXO23xBw5WUhP4orK2lE4r+t9JGITmEe0JH+wPmJhqHpOT2bRRs6lAL945+LDvOAGw=="],
"@shikijs/themes": ["@shikijs/themes@4.1.0", "", { "dependencies": { "@shikijs/types": "4.1.0" } }, "sha512-emCcTnUM7yO2wltYbaxm+yLvcCI4+h8XBKc4KmJ7EZUXoSGjcCHifkI//R4OFit9ewpg7H2/9tjOuXrT2v/Knw=="],
"@shikijs/types": ["@shikijs/types@4.1.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3EQWX54fMpniOrDblzAhiwiJwpiTMW6+B9DWyUd9ska483tbayFYuw47UxwuPknI31bKnySfVQ/QW+jFL4rFdA=="],
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
"@sun-typeface/suit": ["@sun-typeface/suit@2.0.5", "", {}, "sha512-NJ0hxmQgDjDBFkocQ7rxx3wPahJbj3uATfXudN3oj6hh/rAedElhdYBbsSwz4qJsdjac6aW6cqK6R1bpsNGOaQ=="],
"@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="],
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.3", "", { "os": "android", "cpu": "arm64" }, "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw=="],
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw=="],
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw=="],
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw=="],
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ=="],
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w=="],
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA=="],
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w=="],
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.3", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ=="],
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ=="],
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="],
"@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="],
"@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="],
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="],
"@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
"@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="],
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
"@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="],
"@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="],
"@types/three": ["@types/three@0.185.4", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": ">=0.5.17", "fflate": "~0.8.2", "meshoptimizer": "~1.1.1" } }, "sha512-gAsBIC07NIFrxjbf7tH2t71c38uulFfk/RFoC7FNBSjMRAQ8J1x/RBvusX0N5PJouaYFJawXQqfCQ0RKUx/1nA=="],
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
"@types/webxr": ["@types/webxr@0.5.24", "", {}, "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg=="],
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.1", "", {}, "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ=="],
"am-i-vibing": ["am-i-vibing@0.4.0", "", { "dependencies": { "process-ancestry": "^0.1.0" }, "bin": { "am-i-vibing": "dist/cli.mjs" } }, "sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg=="],
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
"astro": ["astro@7.3.1", "", { "dependencies": { "@astrojs/compiler-rs": "^0.4.0", "@astrojs/internal-helpers": "0.11.0", "@astrojs/markdown-satteri": "0.4.0", "@astrojs/telemetry": "3.3.3", "@capsizecss/unpack": "^4.0.0", "@clack/prompts": "^1.1.0", "@oslojs/encoding": "^1.1.0", "am-i-vibing": "^0.4.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", "cookie": "^2.0.1", "devalue": "^5.8.1", "diff": "^9.0.0", "dset": "^3.1.4", "es-module-lexer": "^2.0.0", "esbuild": "^0.28.0", "find-proc": "0.1.0", "flattie": "^1.1.1", "fontace": "~0.4.1", "get-tsconfig": "5.0.0-beta.4", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "js-yaml": "^4.3.0", "jsonc-parser": "^3.3.1", "magic-string": "^1.0.0", "magicast": "^0.5.2", "mrmime": "^2.0.1", "neotraverse": "^1.0.1", "obug": "^2.1.1", "p-limit": "^7.3.0", "p-queue": "^9.1.0", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.4", "semver": "^7.7.4", "shiki": "^4.0.2", "smol-toml": "^1.6.0", "svgo": "^4.0.1", "tinyclip": "^0.1.12", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15", "ultrahtml": "^1.6.0", "unifont": "~0.7.5", "unstorage": "^1.17.5", "vite": "^8.0.13", "vitefu": "^1.1.2", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", "zod": "^4.5.4" }, "optionalDependencies": { "sharp": "^0.35.4" }, "peerDependencies": { "@astrojs/markdown-remark": "^7.3.0" }, "optionalPeers": ["@astrojs/markdown-remark"], "bin": { "astro": "./bin/astro.mjs" } }, "sha512-A/bJYHtc6n0UAdROY9W948fW6lX0pnUA+JWKW+IGCXRyDIGN2MsXC0OlS8onZGJjr+sv8htemwOc9W5PBRXCkw=="],
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
"character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="],
"character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="],
"chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="],
"ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="],
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
"commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
"common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="],
"cookie": ["cookie@2.0.1", "", {}, "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w=="],
"cookie-es": ["cookie-es@1.2.3", "", {}, "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw=="],
"crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="],
"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-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="],
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
"csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="],
"defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="],
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
"destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"devalue": ["devalue@5.8.1", "", {}, "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw=="],
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
"diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="],
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
"dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="],
"enhanced-resolve": ["enhanced-resolve@5.24.5", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A=="],
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="],
"esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="],
"eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="],
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
"fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="],
"fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="],
"fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="],
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
"fflate": ["fflate@0.8.3", "", {}, "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA=="],
"find-proc": ["find-proc@0.1.0", "", {}, "sha512-OaOpEYv2PiQ7SQ5LIrl+deA1XaWcxEjnpM6VuWXTUvn+teIXxeFTLDmu18/zDQpFmHN4o3oDBX+BT0AGwEhemg=="],
"flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="],
"fontace": ["fontace@0.4.1", "", { "dependencies": { "fontkitten": "^1.0.2" } }, "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw=="],
"fontkitten": ["fontkitten@1.0.3", "", { "dependencies": { "tiny-inflate": "^1.0.3" } }, "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"get-tsconfig": ["get-tsconfig@5.0.0-beta.4", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ=="],
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="],
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
"hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
"html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="],
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
"http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="],
"iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="],
"is-docker": ["is-docker@4.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA=="],
"is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
"jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="],
"js-yaml": ["js-yaml@4.3.2", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA=="],
"jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="],
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
"lru-cache": ["lru-cache@11.5.1", "", {}, "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A=="],
"magic-string": ["magic-string@1.2.3", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g=="],
"magicast": ["magicast@0.5.3", "", { "dependencies": { "@babel/parser": "^7.29.3", "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw=="],
"mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="],
"mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="],
"meshoptimizer": ["meshoptimizer@1.1.1", "", {}, "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g=="],
"micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="],
"micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="],
"micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="],
"micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="],
"micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="],
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
"nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="],
"neotraverse": ["neotraverse@1.0.1", "", {}, "sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w=="],
"nlcst-to-string": ["nlcst-to-string@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0" } }, "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA=="],
"node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
"node-mock-http": ["node-mock-http@1.0.4", "", {}, "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
"obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="],
"ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="],
"ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
"oniguruma-parser": ["oniguruma-parser@0.12.2", "", {}, "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw=="],
"oniguruma-to-es": ["oniguruma-to-es@4.3.6", "", { "dependencies": { "oniguruma-parser": "^0.12.2", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA=="],
"p-limit": ["p-limit@7.3.0", "", { "dependencies": { "yocto-queue": "^1.2.1" } }, "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw=="],
"p-queue": ["p-queue@9.3.0", "", { "dependencies": { "eventemitter3": "^5.0.4", "p-timeout": "^7.0.0" } }, "sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang=="],
"p-timeout": ["p-timeout@7.0.1", "", {}, "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg=="],
"package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
"piccolore": ["piccolore@0.1.3", "", {}, "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw=="],
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
"postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="],
"prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
"process-ancestry": ["process-ancestry@0.1.0", "", {}, "sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg=="],
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
"radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="],
"readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
"regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="],
"regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="],
"regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="],
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
"retext-smartypants": ["retext-smartypants@6.2.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "nlcst-to-string": "^4.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ=="],
"rolldown": ["rolldown@1.1.3", "", { "dependencies": { "@oxc-project/types": "=0.137.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.3", "@rolldown/binding-darwin-arm64": "1.1.3", "@rolldown/binding-darwin-x64": "1.1.3", "@rolldown/binding-freebsd-x64": "1.1.3", "@rolldown/binding-linux-arm-gnueabihf": "1.1.3", "@rolldown/binding-linux-arm64-gnu": "1.1.3", "@rolldown/binding-linux-arm64-musl": "1.1.3", "@rolldown/binding-linux-ppc64-gnu": "1.1.3", "@rolldown/binding-linux-s390x-gnu": "1.1.3", "@rolldown/binding-linux-x64-gnu": "1.1.3", "@rolldown/binding-linux-x64-musl": "1.1.3", "@rolldown/binding-openharmony-arm64": "1.1.3", "@rolldown/binding-wasm32-wasi": "1.1.3", "@rolldown/binding-win32-arm64-msvc": "1.1.3", "@rolldown/binding-win32-x64-msvc": "1.1.3" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g=="],
"satteri": ["satteri@0.10.5", "", { "dependencies": { "@types/estree-jsx": "^1.0.5", "@types/hast": "^3.0.5", "@types/mdast": "^4.0.4", "@types/unist": "^3.0.3" }, "optionalDependencies": { "@bruits/satteri-darwin-arm64": "0.10.5", "@bruits/satteri-darwin-x64": "0.10.5", "@bruits/satteri-linux-arm64-gnu": "0.10.5", "@bruits/satteri-linux-arm64-musl": "0.10.5", "@bruits/satteri-linux-x64-gnu": "0.10.5", "@bruits/satteri-linux-x64-musl": "0.10.5", "@bruits/satteri-wasm32-wasi": "0.10.5", "@bruits/satteri-win32-arm64-msvc": "0.10.5", "@bruits/satteri-win32-x64-msvc": "0.10.5" } }, "sha512-Ao1LKpAEa9Wdg0otgbVKViZHEq9ebdXe4DMrp3s9vQAU0HNIuHnFEuMuOcm0ZIXyV0Yzxj91NvhLpvXZJO/5ZQ=="],
"sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="],
"semver": ["semver@7.8.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg=="],
"sharp": ["sharp@0.35.4", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.4", "@img/sharp-darwin-x64": "0.35.4", "@img/sharp-freebsd-wasm32": "0.35.4", "@img/sharp-libvips-darwin-arm64": "1.3.3", "@img/sharp-libvips-darwin-x64": "1.3.3", "@img/sharp-libvips-linux-arm": "1.3.3", "@img/sharp-libvips-linux-arm64": "1.3.3", "@img/sharp-libvips-linux-ppc64": "1.3.3", "@img/sharp-libvips-linux-riscv64": "1.3.3", "@img/sharp-libvips-linux-s390x": "1.3.3", "@img/sharp-libvips-linux-x64": "1.3.3", "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", "@img/sharp-libvips-linuxmusl-x64": "1.3.3", "@img/sharp-linux-arm": "0.35.4", "@img/sharp-linux-arm64": "0.35.4", "@img/sharp-linux-ppc64": "0.35.4", "@img/sharp-linux-riscv64": "0.35.4", "@img/sharp-linux-s390x": "0.35.4", "@img/sharp-linux-x64": "0.35.4", "@img/sharp-linuxmusl-arm64": "0.35.4", "@img/sharp-linuxmusl-x64": "0.35.4", "@img/sharp-webcontainers-wasm32": "0.35.4", "@img/sharp-win32-arm64": "0.35.4", "@img/sharp-win32-ia32": "0.35.4", "@img/sharp-win32-x64": "0.35.4" } }, "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA=="],
"shiki": ["shiki@4.1.0", "", { "dependencies": { "@shikijs/core": "4.1.0", "@shikijs/engine-javascript": "4.1.0", "@shikijs/engine-oniguruma": "4.1.0", "@shikijs/langs": "4.1.0", "@shikijs/themes": "4.1.0", "@shikijs/types": "4.1.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-l/ABZPUR5v70jI10EzqfMS/I96vjSGv2y0ihUV+WYFzv0EfvW4s54m0Lg8wCrrL+2IkwBzFTuxkZjPf8b2NX9Q=="],
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
"smol-toml": ["smol-toml@1.6.1", "", {}, "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
"space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="],
"stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="],
"svgo": ["svgo@4.0.1", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.5.0" }, "bin": "./bin/svgo.js" }, "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w=="],
"tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="],
"tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="],
"three": ["three@0.186.0", "", {}, "sha512-cr/fIM2ddMSVbYVgkfD4jLJv7Fh/8ZTjvo+7gQeSVGUZHxpx9FDwoL5iC7hUz/LiRA8wMbqfnb90xKfm1/HHkQ=="],
"tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
"tinyclip": ["tinyclip@0.1.13", "", {}, "sha512-8OqlXQ35euK9+e7L68u8UwcODxkHoIkjbGsgXuARKNyQ5G6xt8nw1YPeMbxMLgCPFkToU+UEK5j05t2t8edKpQ=="],
"tinyexec": ["tinyexec@1.2.3", "", {}, "sha512-g62dB+w1/OEFnPvmX0yd/HnetYITOL+1nJW7kitOycOeAvmbWC/nu0fwmmQ/kupNojqExzyC/T++pST/jRJ2mQ=="],
"tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
"trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="],
"ultrahtml": ["ultrahtml@1.6.0", "", {}, "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw=="],
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
"undici": ["undici@8.10.2", "", {}, "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ=="],
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
"unifont": ["unifont@0.7.5", "", { "dependencies": { "css-tree": "^3.1.0", "ohash": "^2.0.11", "undici": "^8.0.0" } }, "sha512-ULe/Cs+ZIsq+dcFofNkhqielCrUJnb5mr+Yc4EBM2VlL+6OZR6+cjtI2mT1bJvRBrVncqHAbLURxmPLcCXzWMg=="],
"unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
"unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
"unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="],
"unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
"unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="],
"unstorage": ["unstorage@1.17.5", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.10", "lru-cache": "^11.2.7", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg=="],
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
"vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
"vite": ["vite@8.1.0", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", "rolldown": "~1.1.2", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q=="],
"vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="],
"xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="],
"yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="],
"yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="],
"zod": ["zod@4.5.4", "", {}, "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA=="],
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"@astrojs/compiler-binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q=="],
"@bruits/satteri-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q=="],
"@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
"@tailwindcss/node/magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="],
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="],
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
"csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="],
"satteri/@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="],
"sharp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
"csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
}
}

BIN
bun.lockb Executable file

Binary file not shown.

5
next-env.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.

View file

@ -1,30 +1,36 @@
{ {
"name": "imnya-ng", "name": "imnyang",
"type": "module", "private": true,
"version": "0.0.1", "type": "module",
"engines": { "scripts": {
"node": ">=22.12.0" "build": "cross-env NODE_ENV=production react-router build",
}, "dev": "react-router dev",
"scripts": { "start": "cross-env NODE_ENV=production react-router-serve ./build/server/index.js",
"dev": "astro dev", "typecheck": "react-router typegen && tsc"
"build": "astro build", },
"preview": "astro preview", "dependencies": {
"astro": "astro" "@react-router/node": "^7.1.1",
}, "@react-router/serve": "^7.1.1",
"dependencies": { "clsx": "^2.1.1",
"@sun-typeface/suit": "^2.0.5", "framer-motion": "^11.15.0",
"astro": "7.3.1", "isbot": "^5.1.17",
"clsx": "^2.1.1", "lucide-react": "^0.469.0",
"three": "^0.186.0" "react": "^19.0.0",
}, "react-dom": "^19.0.0",
"devDependencies": { "react-router": "^7.1.1",
"@biomejs/biome": "2.5.12", "tailwind-merge": "^2.6.0"
"@tailwindcss/vite": "^4.3.3", },
"@types/three": "^0.185.4", "devDependencies": {
"tailwindcss": "^4.3.3" "@react-router/dev": "^7.1.1",
}, "@types/node": "^20",
"overrides": { "@types/react": "^19.0.1",
"@types/react": "19.2.2", "@types/react-dom": "^19.0.1",
"@types/react-dom": "19.2.2" "autoprefixer": "^10.4.20",
} "cross-env": "^7.0.3",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.16",
"typescript": "^5.7.2",
"vite": "^5.4.11",
"vite-tsconfig-paths": "^5.1.4"
}
} }

View file

@ -1,29 +0,0 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.7713 3.51756C13.8249 3.23082 13.977 2.97183 14.2014 2.78546C14.4258 2.59909 14.7084 2.49707 15.0001 2.49707C15.2918 2.49707 15.5743 2.59909 15.7987 2.78546C16.0231 2.97183 16.1753 3.23082 16.2288 3.51756L17.5426 10.4651C17.6359 10.959 17.8759 11.4133 18.2314 11.7688C18.5868 12.1242 19.0411 12.3643 19.5351 12.4576L26.4826 13.7713C26.7693 13.8249 27.0283 13.977 27.2147 14.2014C27.401 14.4258 27.5031 14.7084 27.5031 15.0001C27.5031 15.2918 27.401 15.5743 27.2147 15.7987C27.0283 16.0231 26.7693 16.1753 26.4826 16.2288L19.5351 17.5426C19.0411 17.6359 18.5868 17.8759 18.2314 18.2314C17.8759 18.5868 17.6359 19.0411 17.5426 19.5351L16.2288 26.4826C16.1753 26.7693 16.0231 27.0283 15.7987 27.2147C15.5743 27.401 15.2918 27.5031 15.0001 27.5031C14.7084 27.5031 14.4258 27.401 14.2014 27.2147C13.977 27.0283 13.8249 26.7693 13.7713 26.4826L12.4576 19.5351C12.3643 19.0411 12.1242 18.5868 11.7688 18.2314C11.4133 17.8759 10.959 17.6359 10.4651 17.5426L3.51756 16.2288C3.23082 16.1753 2.97183 16.0231 2.78546 15.7987C2.59909 15.5743 2.49707 15.2918 2.49707 15.0001C2.49707 14.7084 2.59909 14.4258 2.78546 14.2014C2.97183 13.977 3.23082 13.8249 3.51756 13.7713L10.4651 12.4576C10.959 12.3643 11.4133 12.1242 11.7688 11.7688C12.1242 11.4133 12.3643 10.959 12.4576 10.4651L13.7713 3.51756Z" fill="url(#paint0_linear_35_40)"/>
<path d="M25.0001 2.50006V7.50006V2.50006Z" fill="url(#paint1_linear_35_40)"/>
<path d="M27.5001 5.00006H22.5001H27.5001Z" fill="url(#paint2_linear_35_40)"/>
<path d="M5.00006 27.5001C6.38078 27.5001 7.50006 26.3808 7.50006 25.0001C7.50006 23.6194 6.38078 22.5001 5.00006 22.5001C3.61935 22.5001 2.50006 23.6194 2.50006 25.0001C2.50006 26.3808 3.61935 27.5001 5.00006 27.5001Z" fill="url(#paint3_linear_35_40)"/>
<path d="M25.0001 2.50006V7.50006M27.5001 5.00006H22.5001M13.7713 3.51756C13.8249 3.23082 13.977 2.97183 14.2014 2.78546C14.4258 2.59909 14.7084 2.49707 15.0001 2.49707C15.2918 2.49707 15.5743 2.59909 15.7987 2.78546C16.0231 2.97183 16.1753 3.23082 16.2288 3.51756L17.5426 10.4651C17.6359 10.959 17.8759 11.4133 18.2314 11.7688C18.5868 12.1242 19.0411 12.3643 19.5351 12.4576L26.4826 13.7713C26.7693 13.8249 27.0283 13.977 27.2147 14.2014C27.401 14.4258 27.5031 14.7084 27.5031 15.0001C27.5031 15.2918 27.401 15.5743 27.2147 15.7987C27.0283 16.0231 26.7693 16.1753 26.4826 16.2288L19.5351 17.5426C19.0411 17.6359 18.5868 17.8759 18.2314 18.2314C17.8759 18.5868 17.6359 19.0411 17.5426 19.5351L16.2288 26.4826C16.1753 26.7693 16.0231 27.0283 15.7987 27.2147C15.5743 27.401 15.2918 27.5031 15.0001 27.5031C14.7084 27.5031 14.4258 27.401 14.2014 27.2147C13.977 27.0283 13.8249 26.7693 13.7713 26.4826L12.4576 19.5351C12.3643 19.0411 12.1242 18.5868 11.7688 18.2314C11.4133 17.8759 10.959 17.6359 10.4651 17.5426L3.51756 16.2288C3.23082 16.1753 2.97183 16.0231 2.78546 15.7987C2.59909 15.5743 2.49707 15.2918 2.49707 15.0001C2.49707 14.7084 2.59909 14.4258 2.78546 14.2014C2.97183 13.977 3.23082 13.8249 3.51756 13.7713L10.4651 12.4576C10.959 12.3643 11.4133 12.1242 11.7688 11.7688C12.1242 11.4133 12.3643 10.959 12.4576 10.4651L13.7713 3.51756ZM7.50006 25.0001C7.50006 26.3808 6.38078 27.5001 5.00006 27.5001C3.61935 27.5001 2.50006 26.3808 2.50006 25.0001C2.50006 23.6194 3.61935 22.5001 5.00006 22.5001C6.38078 22.5001 7.50006 23.6194 7.50006 25.0001Z" stroke="url(#paint4_linear_35_40)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<linearGradient id="paint0_linear_35_40" x1="2" y1="2" x2="28" y2="28" gradientUnits="userSpaceOnUse">
<stop stop-color="#E8BEFF"/>
<stop offset="1" stop-color="#8E5FFF"/>
</linearGradient>
<linearGradient id="paint1_linear_35_40" x1="2" y1="2" x2="28" y2="28" gradientUnits="userSpaceOnUse">
<stop stop-color="#E8BEFF"/>
<stop offset="1" stop-color="#8E5FFF"/>
</linearGradient>
<linearGradient id="paint2_linear_35_40" x1="2" y1="2" x2="28" y2="28" gradientUnits="userSpaceOnUse">
<stop stop-color="#E8BEFF"/>
<stop offset="1" stop-color="#8E5FFF"/>
</linearGradient>
<linearGradient id="paint3_linear_35_40" x1="2" y1="2" x2="28" y2="28" gradientUnits="userSpaceOnUse">
<stop stop-color="#E8BEFF"/>
<stop offset="1" stop-color="#8E5FFF"/>
</linearGradient>
<linearGradient id="paint4_linear_35_40" x1="2" y1="2" x2="28" y2="28" gradientUnits="userSpaceOnUse">
<stop stop-color="#E8BEFF"/>
<stop offset="1" stop-color="#8E5FFF"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

View file

@ -1,9 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="20.0049" height="20.0049" viewBox="0 0 20.0049 20.0049" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group">
<path id="Vector" d="M3.84244 2.12244C-0.509561 5.52452 -1.27963 11.8104 2.12244 16.1624C5.52452 20.5145 11.8104 21.2845 16.1624 17.8825C20.5144 14.4804 21.2846 8.19445 17.8824 3.84244C14.4804 -0.50956 8.19444 -1.27963 3.84244 2.12244Z" fill="#0B192B"/>
<path id="Vector_2" opacity="0.35" d="M5.96911 4.15762C6.14042 4.00564 6.33486 3.88475 6.54426 3.80004C6.68012 3.70562 6.82646 3.62887 6.97999 3.57152C7.14349 3.48379 7.31769 3.42005 7.49766 3.38212C7.68044 3.28735 7.87587 3.22227 8.07719 3.18912C8.21214 3.14077 8.35157 3.1076 8.49312 3.09019C8.61151 3.05892 8.73234 3.03907 8.85409 3.03089C8.99391 3.00205 9.13617 2.98887 9.27851 2.99159C9.47989 2.95852 9.68476 2.95777 9.88604 2.98937C10.1089 2.96309 10.3343 2.97614 10.5527 3.02797C10.7153 3.02887 10.8772 3.05055 11.0346 3.09252C11.2167 3.11517 11.3948 3.16397 11.5639 3.23755C11.8878 3.28215 12.1958 3.40969 12.4605 3.60882C12.7252 3.80797 12.9385 4.07257 13.0814 4.37914C13.2243 4.68572 13.2924 5.0248 13.2797 5.36632C13.2669 5.70784 13.1738 6.04122 13.0084 6.3369C12.7645 6.77269 12.3778 7.10179 11.9203 7.26286C11.4629 7.42394 10.9658 7.40602 10.5217 7.21245C10.4433 7.2016 10.3656 7.18594 10.289 7.16557C10.2195 7.15687 10.1504 7.14436 10.0822 7.12806C9.98562 7.12764 9.88926 7.11979 9.79386 7.1046C9.70654 7.115 9.61871 7.11936 9.53092 7.11762C9.47044 7.12781 9.40966 7.13489 9.34857 7.13892C9.29651 7.14959 9.24392 7.15827 9.19131 7.1648C9.13202 7.18044 9.07211 7.19324 9.01156 7.2032C8.92839 7.233 8.84349 7.25707 8.75736 7.27524C8.68637 7.31209 8.61341 7.34456 8.53881 7.37246C8.47629 7.40591 8.41216 7.43594 8.34667 7.46242C8.26606 7.51842 8.18171 7.56827 8.09427 7.61159C8.02722 7.67126 7.95647 7.72619 7.88249 7.77606C7.83752 7.81959 7.79064 7.86112 7.74214 7.90006C7.70467 7.93944 7.66547 7.97721 7.62517 8.01339C7.59011 8.05422 7.55359 8.09344 7.51559 8.13105C7.46577 8.19545 7.41237 8.25672 7.35566 8.31455C7.31514 8.38575 7.27062 8.45439 7.22237 8.52012C7.18721 8.58369 7.14891 8.6453 7.10761 8.70472C7.06904 8.79742 7.02404 8.88709 6.97297 8.973C6.94759 9.061 6.91671 9.14721 6.88051 9.23104C6.86527 9.29289 6.84749 9.35437 6.82691 9.41464C6.81589 9.46877 6.80292 9.52262 6.78756 9.57589C6.74456 9.8566 6.64694 10.1254 6.50074 10.3656C6.35454 10.6059 6.16287 10.8125 5.93759 10.9726C5.71232 11.1327 5.45824 11.243 5.19107 11.2966C4.92389 11.3502 4.64932 11.346 4.38432 11.2842C4.11934 11.2225 3.86959 11.1044 3.65051 10.9375C3.43144 10.7705 3.24772 10.5582 3.11071 10.3136C2.97371 10.069 2.88632 9.79734 2.85399 9.51547C2.82166 9.2336 2.84504 8.9475 2.92272 8.67487C2.94202 8.54885 2.97234 8.4249 3.01327 8.30455C3.04314 8.15892 3.08774 8.01697 3.14634 7.88107C3.19686 7.67456 3.27722 7.47715 3.38467 7.2957C3.44959 7.07112 3.55021 6.85939 3.68229 6.66941C3.74741 6.51314 3.83056 6.3657 3.92987 6.23039C4.02181 6.06402 4.13519 5.91157 4.26679 5.77734C4.36082 5.6123 4.47607 5.46149 4.60931 5.3291C4.68616 5.22989 4.77149 5.13817 4.86422 5.0551C4.94602 4.96009 5.03594 4.87305 5.13284 4.79509C5.23362 4.68957 5.34486 4.59555 5.46464 4.51465C5.61447 4.36955 5.78454 4.24914 5.96894 4.15759L5.96911 4.15762Z" fill="#E65836"/>
<path id="Vector_3" d="M6.24429 11.4535C7.09794 10.7321 7.20632 9.45646 6.48637 8.60422C5.76642 7.75199 4.49076 7.64591 3.63711 8.36727C2.78346 9.08866 2.67507 10.3643 3.39502 11.2165C4.11497 12.0688 5.39064 12.1749 6.24429 11.4535Z" fill="#E65836"/>
<path id="Vector_4" opacity="0.35" d="M7.82567 12.8515C8.08254 12.7149 8.36447 12.6383 8.65189 12.6269C8.93931 12.6155 9.22534 12.6696 9.49014 12.7854C9.56832 12.7962 9.64579 12.8119 9.72216 12.8322C9.79187 12.8409 9.86109 12.8534 9.92951 12.8697C10.0262 12.8702 10.1227 12.878 10.2182 12.893C10.3055 12.8827 10.3932 12.8784 10.4809 12.8802C10.5413 12.8701 10.602 12.863 10.663 12.8589C10.7152 12.8482 10.7676 12.8395 10.8202 12.8331C10.8794 12.8175 10.9391 12.8047 10.9995 12.7948C11.0828 12.7649 11.1679 12.7407 11.2543 12.7225C11.3251 12.6858 11.3978 12.6535 11.4722 12.6257C11.5349 12.5921 11.5992 12.562 11.6648 12.5355C11.7455 12.4794 11.83 12.4295 11.9175 12.3861C11.9845 12.3266 12.0552 12.2717 12.1291 12.2218C12.1741 12.1782 12.2209 12.1369 12.2693 12.0979C12.3068 12.0585 12.3458 12.0207 12.3862 11.9846C12.4213 11.9438 12.4578 11.9046 12.4957 11.867C12.5456 11.8025 12.5991 11.7412 12.6559 11.6833C12.6963 11.6123 12.7407 11.5439 12.7888 11.4782C12.824 11.4145 12.8624 11.3528 12.9038 11.2932C12.9424 11.2004 12.9874 11.1106 13.0385 11.0246C13.0639 10.9366 13.0948 10.8504 13.131 10.7666C13.146 10.7046 13.1639 10.6435 13.1843 10.5832C13.1955 10.5289 13.2086 10.4752 13.2237 10.4219C13.3049 9.88759 13.5827 9.40659 13.9976 9.08167C14.0258 9.05961 14.0547 9.03822 14.0843 9.01752C14.4243 8.77919 14.8257 8.65579 15.234 8.66414C15.6423 8.67249 16.0376 8.81219 16.366 9.0642C16.6944 9.31622 16.9399 9.66829 17.0692 10.0725C17.1986 10.4767 17.2052 10.9133 17.0886 11.323C17.0692 11.4491 17.0389 11.5731 16.9981 11.6935C16.9682 11.839 16.9236 11.9809 16.8651 12.1167C16.8146 12.3233 16.7342 12.5208 16.6267 12.7023C16.5617 12.9271 16.4609 13.139 16.3287 13.3291C16.2638 13.4849 16.1809 13.632 16.0819 13.767C15.9899 13.9337 15.8764 14.0864 15.7446 14.2209C15.6505 14.386 15.5351 14.537 15.4017 14.6694C15.325 14.7684 15.2399 14.8598 15.1474 14.9427C15.0655 15.0377 14.9756 15.1248 14.8787 15.2028C14.7779 15.3083 14.6666 15.4023 14.5468 15.4832C14.397 15.6284 14.2269 15.7488 14.0425 15.8404C13.871 15.9925 13.6764 16.1135 13.4668 16.1983C13.3313 16.2924 13.1853 16.369 13.0322 16.4262C12.8685 16.5141 12.6941 16.5779 12.5139 16.6159C12.3309 16.7108 12.1352 16.776 11.9335 16.8091C11.7989 16.8573 11.6598 16.8903 11.5187 16.9076C11.4002 16.9388 11.2794 16.9588 11.1576 16.9671C11.0179 16.996 10.8757 17.0091 10.7334 17.0065C10.5319 17.0396 10.3269 17.0403 10.1256 17.0086C9.90251 17.035 9.67696 17.022 9.45846 16.9698C9.29614 16.969 9.13462 16.9475 8.97752 16.9055C8.79522 16.883 8.61691 16.8341 8.44764 16.7605C8.02719 16.703 7.63609 16.5063 7.33164 16.199C7.02721 15.8917 6.82542 15.4901 6.75587 15.0531C6.68634 14.616 6.75267 14.1664 6.94519 13.7702C7.13771 13.374 7.44629 13.0521 7.82567 12.8515Z" fill="#7DABFF"/>
<path id="Vector_5" d="M16.3749 11.6303C17.2286 10.909 17.3369 9.6333 16.6169 8.78107C15.897 7.92884 14.6213 7.82275 13.7677 8.54414C12.914 9.2655 12.8056 10.5412 13.5256 11.3934C14.2456 12.2456 15.5212 12.3517 16.3749 11.6303Z" fill="#7DABFF"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View file

@ -1,5 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="13" height="24" viewBox="0 0 13 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 2085664223">
<path id="-" d="M13 13H1V11H13V13Z" fill="black"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 255 B

View file

@ -1,22 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="20" height="11" viewBox="0 0 20 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group 664 1" clip-path="url(#clip0_0_9)">
<path id="Vector" d="M5.018 0.625758L6.5517 2.10178L5.90152 2.72754L4.36781 1.25152L1.7602 3.76107H4.24978V4.64606H1.7602L4.36781 7.15562L5.90152 5.6796L6.5517 6.30535L5.018 7.78138L4.36781 8.40713L3.71759 7.78138L0.650211 4.82932L0 4.20357L0.650211 3.57781L3.71759 0.625758L4.36781 0L5.018 0.625758Z" fill="black"/>
<path id="Vector_2" fill-rule="evenodd" clip-rule="evenodd" d="M13.2544 4.20357L16.3218 1.25153L18.6996 3.53985H20L16.972 0.625765L16.3218 0L15.6716 0.625765L12.6042 3.57781L11.954 4.20357L12.6042 4.82932L15.6716 7.78138L16.3218 8.40713L16.972 7.78138L20 4.8673H18.6996L16.3218 7.15562L13.2544 4.20357Z" fill="black"/>
<path id="Vector_3" fill-rule="evenodd" clip-rule="evenodd" d="M10.3448 1.25153L7.27741 4.20357L8.25611 5.14547L11.3235 2.19343L10.3448 1.25153ZM12.5287 2.10179L12.6239 2.19342L8.90633 5.77123L10.3448 7.15562L10.844 6.67518L11.4942 7.30094L10.995 7.78138L10.3448 8.40713L9.69459 7.78138L6.62722 4.82932L5.977 4.20357L6.62722 3.57781L9.69459 0.625765L10.3448 0L10.995 0.625765L11.9737 1.56766L12.5287 2.10179Z" fill="black"/>
<path id="Vector_4" d="M1.65638 10.0178L1.36777 9.74006L1.07915 10.0178L1.36777 10.2956L1.65638 10.0178Z" fill="black"/>
<path id="Vector_5" d="M4.06008 10.0179L3.64526 9.61858L3.23044 10.0179L3.64526 10.4171L4.06008 10.0179Z" stroke="black" stroke-width="0.1"/>
<path id="Vector_6" d="M16.7695 10.0179L16.3547 9.61858L15.9398 10.0179L16.3547 10.4171L16.7695 10.0179Z" stroke="black" stroke-width="0.1"/>
<path id="Vector_7" d="M18.9208 10.0178L18.6322 9.74006L18.3436 10.0178L18.6322 10.2956L18.9208 10.0178Z" fill="black"/>
<path id="Vector_8" d="M13.7408 10.7922C13.6275 10.7922 13.527 10.7689 13.4392 10.7224C13.3515 10.6758 13.2831 10.6113 13.234 10.5289C13.185 10.4458 13.1604 10.3526 13.1604 10.2496C13.1604 10.1452 13.1846 10.0517 13.233 9.96927C13.282 9.88683 13.3491 9.82264 13.434 9.77676C13.519 9.73023 13.6151 9.70695 13.7221 9.70695C13.8286 9.70695 13.9229 9.73023 14.0051 9.77676C14.088 9.82264 14.1522 9.88683 14.1979 9.96927C14.2441 10.0517 14.2673 10.1452 14.2673 10.2496C14.2673 10.2775 14.2649 10.3081 14.26 10.3414H13.3335V10.1249H13.9833L13.9678 10.1558C13.9678 10.1146 13.9574 10.0777 13.9367 10.0451C13.9166 10.0119 13.888 9.9859 13.8507 9.96728C13.8133 9.94799 13.7705 9.93834 13.7221 9.93834C13.671 9.93834 13.6247 9.94966 13.5833 9.97227C13.5425 9.99423 13.5104 10.0255 13.4869 10.066C13.4641 10.1059 13.4527 10.1521 13.4527 10.2047V10.2855C13.4527 10.3394 13.4651 10.3872 13.49 10.4291C13.5149 10.4704 13.5494 10.5026 13.5936 10.5259C13.6379 10.5491 13.6873 10.5608 13.7419 10.5608C13.7971 10.5608 13.8441 10.5495 13.8828 10.5269C13.9215 10.5043 13.9512 10.473 13.9719 10.4331L14.2279 10.5239C14.1844 10.6077 14.1208 10.6735 14.0372 10.7214C13.9536 10.7686 13.8548 10.7922 13.7408 10.7922Z" fill="black"/>
<path id="Vector_9" d="M12.1551 9.31992H12.4495V10.7643H12.1551V9.31992Z" fill="black"/>
<path id="Vector_10" d="M11.1686 10.2496C11.1686 10.3706 11.1531 10.4714 11.122 10.5518C11.0909 10.6323 11.0456 10.6925 10.9862 10.7324C10.9275 10.7723 10.8556 10.7922 10.7706 10.7922C10.6753 10.7922 10.5896 10.7686 10.5136 10.7214C10.4376 10.6742 10.3782 10.6093 10.3354 10.5269C10.2926 10.4437 10.2711 10.3513 10.2711 10.2496C10.2711 10.1472 10.2926 10.0547 10.3354 9.97227C10.3782 9.88982 10.4376 9.82499 10.5136 9.77775C10.5896 9.73055 10.6753 9.70695 10.7706 9.70695C10.8556 9.70695 10.9275 9.72688 10.9862 9.76679C11.0456 9.80602 11.0909 9.86622 11.122 9.94735C11.1531 10.0278 11.1686 10.1285 11.1686 10.2496L11.0629 9.87551H11.1935V10.6236H11.0629L11.1686 10.2496ZM10.8359 10.5329C10.8877 10.5329 10.934 10.5209 10.9748 10.497C11.0156 10.4724 11.0473 10.4388 11.0701 10.3962C11.093 10.353 11.1043 10.3041 11.1043 10.2496C11.1043 10.1944 11.093 10.1455 11.0701 10.1029C11.0473 10.0597 11.0156 10.0261 10.9748 10.0022C10.934 9.97825 10.8877 9.96628 10.8359 9.96628C10.7841 9.96628 10.7378 9.97825 10.6971 10.0022C10.657 10.0261 10.6252 10.0597 10.6017 10.1029C10.5789 10.1455 10.5675 10.1944 10.5675 10.2496C10.5675 10.3034 10.5789 10.352 10.6017 10.3952C10.6252 10.4384 10.657 10.4724 10.6971 10.497C10.7378 10.5209 10.7841 10.5329 10.8359 10.5329ZM11.0961 10.7643V10.5568L11.1427 10.2496L11.0961 9.97625V9.73486H11.3904V10.7643H11.0961Z" fill="black"/>
<path id="Vector_11" d="M8.54456 9.73486H8.83889V10.7643H8.54456V9.73486ZM9.26585 10.2017C9.26585 10.1266 9.24826 10.0687 9.213 10.0281C9.17844 9.9869 9.12974 9.96628 9.06689 9.96628C9.02404 9.96628 8.98537 9.97661 8.95081 9.99722C8.91626 10.0172 8.88896 10.0484 8.86893 10.091C8.84889 10.1329 8.83889 10.1858 8.83889 10.2496L8.8057 10.0581V9.88747H8.87204L8.8057 10.0581C8.8057 9.98889 8.82126 9.92805 8.85237 9.87551C8.88415 9.82232 8.928 9.7811 8.98396 9.75184C9.03993 9.7219 9.10385 9.70695 9.1757 9.70695C9.25585 9.70695 9.32459 9.72489 9.38193 9.76081C9.43996 9.79673 9.48419 9.84824 9.51459 9.91541C9.545 9.98191 9.56019 10.0614 9.56019 10.1538V10.7643H9.26585V10.2017Z" fill="black"/>
<path id="Vector_12" d="M7.48537 9.73486H7.7797V10.7643H7.48537V9.73486ZM7.63252 9.58324C7.60007 9.58324 7.57037 9.57594 7.54341 9.56131C7.51715 9.54668 7.49607 9.52707 7.48018 9.50247C7.465 9.47719 7.45741 9.44893 7.45741 9.41767C7.45741 9.38642 7.465 9.35815 7.48018 9.33288C7.49607 9.30696 7.51715 9.28699 7.54341 9.27304C7.57037 9.25908 7.60007 9.25207 7.63252 9.25207C7.6657 9.25207 7.69574 9.25908 7.7227 9.27304C7.74963 9.28699 7.77037 9.30696 7.78489 9.33288C7.80007 9.35815 7.80767 9.38642 7.80767 9.41767C7.80767 9.44893 7.80007 9.47719 7.78489 9.50247C7.77037 9.52707 7.74963 9.54668 7.7227 9.56131C7.69574 9.57594 7.6657 9.58324 7.63252 9.58324Z" fill="black"/>
<path id="Vector_13" d="M5.79196 9.31992H6.0987V10.7643H5.79196V9.31992ZM6.09456 9.31992H6.74748V9.59723H6.09456V9.31992ZM6.09456 9.92741H6.68115V10.1887H6.09456V9.92741Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_0_9">
<rect width="20" height="11" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

View file

@ -1,9 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 2085664221">
<g id="Vector" opacity="0.8">
<path d="M12.8003 11.7172C12.8003 11.7172 6.00206 12.561 6.07298 8.80549C6.15643 4.37508 10.9842 0.94513 14.7785 0C14.7785 0 10.5187 0.778 7.63218 2.68806C4.74565 4.59812 2.41699 7.25939 2.41699 9.51128C2.41699 11.7632 4.76949 12.8545 5.83994 13.0362C6.91039 13.2178 9.14547 13.332 12.8003 11.7172Z" fill="#00A15D"/>
<path d="M3.05347 24C3.05347 24 8.94334 21.9286 13.6215 17.7906C18.2997 13.6525 19.1371 7.27126 9.50897 9.10154C9.50897 9.10154 13.4475 7.50536 16.2917 7.50536C19.1359 7.50536 22.417 8.02946 22.417 11.2509C22.4194 15.6295 13.9195 23.5405 3.05347 24Z" fill="#0167AC"/>
<path d="M20.3158 1.75341C20.9434 2.81559 20.4481 4.2429 19.2096 4.94111C17.971 5.63933 16.4589 5.34526 15.8313 4.28308C15.2037 3.2209 15.7216 1.83145 16.9369 1.09537C17.9943 0.454805 19.6882 0.691233 20.3158 1.75341Z" fill="#F05A20"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,10 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 2085664225">
<g id="Vector" opacity="0.8">
<path d="M22 18.884V22L13.6048 9.56749L13.5498 6.16145L22 18.884Z" fill="#3F3F3F"/>
<path d="M13.6046 9.56749L10.3533 14.3112V11.1837L13.5496 6.16145L13.6046 9.56749Z" fill="black"/>
<path d="M5.00838 16.4022L9.58168 15.4368L9.3296 15.8043L4.61106 17.2037H2L11.3471 2L12.603 4.3573L5.79958 15.1473L5.00838 16.4022Z" fill="black"/>
<path d="M10.3533 14.3112L9.58168 15.4368L5.00838 16.4022L5.79958 15.1473L10.3533 14.3112Z" fill="#3F3F3F"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 679 B

View file

@ -1,5 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="13" height="2" viewBox="0 0 13 2" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 2085664223">
<path id="-" d="M12.792 2H0.791992V0H12.792V2Z" fill="black"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 265 B

View file

@ -1,3 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="12.375" height="3.9375" viewBox="0 0 12.375 3.9375" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="~" d="M8.50781 3.9375C8.10156 3.9375 7.73047 3.88281 7.39453 3.77344C7.05859 3.66406 6.76562 3.53516 6.51562 3.38672C6.26562 3.23828 5.96875 3.04688 5.625 2.8125C5.25 2.53125 4.9375 2.32812 4.6875 2.20312C4.4375 2.07812 4.16406 2.01562 3.86719 2.01562C3.53906 2.01562 3.20703 2.13281 2.87109 2.36719C2.53516 2.60156 2.09375 3.04688 1.54688 3.70312L0 2.41406C0.125 2.25781 0.328125 2.02344 0.609375 1.71094C1 1.30469 1.36328 0.976562 1.69922 0.726562C2.03516 0.476562 2.37891 0.292969 2.73047 0.175781C3.08203 0.0585938 3.46094 0 3.86719 0C4.27344 0 4.64453 0.0507812 4.98047 0.152344C5.31641 0.253906 5.61328 0.378906 5.87109 0.527344C6.12891 0.675781 6.42188 0.875 6.75 1.125C7.14062 1.39062 7.46094 1.58984 7.71094 1.72266C7.96094 1.85547 8.22656 1.92188 8.50781 1.92188C8.83594 1.92188 9.16797 1.80078 9.50391 1.55859C9.83984 1.31641 10.2812 0.875 10.8281 0.234375L12.375 1.52344C12.2656 1.66406 12.0625 1.89844 11.7656 2.22656C11.3906 2.61719 11.0312 2.9375 10.6875 3.1875C10.3438 3.4375 9.99609 3.625 9.64453 3.75C9.29297 3.875 8.91406 3.9375 8.50781 3.9375Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,9 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 2085664220">
<g id="Vector" opacity="0.8">
<path d="M12.3833 11.7172C12.3833 11.7172 5.58507 12.561 5.65599 8.80549C5.73944 4.37508 10.5672 0.94513 14.3615 0C14.3615 0 10.1017 0.778 7.21518 2.68806C4.32865 4.59812 2 7.25939 2 9.51128C2 11.7632 4.35249 12.8545 5.42295 13.0362C6.4934 13.2178 8.72848 13.332 12.3833 11.7172Z" fill="#00A15D"/>
<path d="M2.63647 24C2.63647 24 8.52635 21.9286 13.2045 17.7906C17.8827 13.6525 18.7201 7.27126 9.09198 9.10154C9.09198 9.10154 13.0305 7.50536 15.8747 7.50536C18.7189 7.50536 22 8.02946 22 11.2509C22.0024 15.6295 13.5025 23.5405 2.63647 24Z" fill="#0167AC"/>
<path d="M19.8988 1.75341C20.5264 2.81559 20.0311 4.2429 18.7926 4.94111C17.554 5.63933 16.0419 5.34526 15.4143 4.28308C14.7867 3.2209 15.3046 1.83145 16.5199 1.09537C17.5773 0.454805 19.2712 0.691233 19.8988 1.75341Z" fill="#F05A20"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

View file

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve" width="512" height="512">
<g>
<path d="M20.317,4.37c-1.53-0.702-3.17-1.219-4.885-1.515c-0.031-0.006-0.062,0.009-0.079,0.037 c-0.211,0.375-0.445,0.865-0.608,1.249c-1.845-0.276-3.68-0.276-5.487,0C9.095,3.748,8.852,3.267,8.641,2.892 C8.624,2.864,8.593,2.85,8.562,2.855C6.848,3.15,5.208,3.667,3.677,4.37C3.664,4.375,3.652,4.385,3.645,4.397 c-3.111,4.648-3.964,9.182-3.546,13.66c0.002,0.022,0.014,0.043,0.031,0.056c2.053,1.508,4.041,2.423,5.993,3.029 c0.031,0.01,0.064-0.002,0.084-0.028c0.462-0.63,0.873-1.295,1.226-1.994c0.021-0.041,0.001-0.09-0.042-0.106 c-0.653-0.248-1.274-0.55-1.872-0.892c-0.047-0.028-0.051-0.095-0.008-0.128c0.126-0.094,0.252-0.192,0.372-0.291 c0.022-0.018,0.052-0.022,0.078-0.01c3.928,1.793,8.18,1.793,12.061,0c0.026-0.012,0.056-0.009,0.079,0.01 c0.12,0.099,0.246,0.198,0.373,0.292c0.044,0.032,0.041,0.1-0.007,0.128c-0.598,0.349-1.219,0.645-1.873,0.891 c-0.043,0.016-0.061,0.066-0.041,0.107c0.36,0.698,0.772,1.363,1.225,1.993c0.019,0.027,0.053,0.038,0.084,0.029 c1.961-0.607,3.95-1.522,6.002-3.029c0.018-0.013,0.029-0.033,0.031-0.055c0.5-5.177-0.838-9.674-3.548-13.66 C20.342,4.385,20.33,4.375,20.317,4.37z M8.02,15.331c-1.183,0-2.157-1.086-2.157-2.419s0.955-2.419,2.157-2.419 c1.211,0,2.176,1.095,2.157,2.419C10.177,14.246,9.221,15.331,8.02,15.331z M15.995,15.331c-1.182,0-2.157-1.086-2.157-2.419 s0.955-2.419,2.157-2.419c1.211,0,2.176,1.095,2.157,2.419C18.152,14.246,17.206,15.331,15.995,15.331z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,3 +0,0 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M56.7937 84.9688C44.4187 83.4688 35.7 74.5625 35.7 63.0313C35.7 58.3438 37.3875 53.2813 40.2 49.9063C38.9812 46.8125 39.1687 40.25 40.575 37.5313C44.325 37.0625 49.3875 39.0313 52.3875 41.75C55.95 40.625 59.7 40.0625 64.2937 40.0625C68.8875 40.0625 72.6375 40.625 76.0125 41.6563C78.9187 39.0313 84.075 37.0625 87.825 37.5313C89.1375 40.0625 89.325 46.625 88.1062 49.8125C91.1062 53.375 92.7 58.1563 92.7 63.0313C92.7 74.5625 83.9812 83.2813 71.4187 84.875C74.6062 86.9375 76.7625 91.4375 76.7625 96.5938L76.7625 106.344C76.7625 109.156 79.1062 110.75 81.9187 109.625C98.8875 103.156 112.2 86.1875 112.2 65.1875C112.2 38.6563 90.6375 17 64.1062 17C37.575 17 16.2 38.6562 16.2 65.1875C16.2 86 29.4187 103.25 47.2312 109.719C49.7625 110.656 52.2 108.969 52.2 106.438L52.2 98.9375C50.8875 99.5 49.2 99.875 47.7 99.875C41.5125 99.875 37.8562 96.5 35.2312 90.2188C34.2 87.6875 33.075 86.1875 30.9187 85.9063C29.7937 85.8125 29.4187 85.3438 29.4187 84.7813C29.4187 83.6563 31.2937 82.8125 33.1687 82.8125C35.8875 82.8125 38.2312 84.5 40.6687 87.9688C42.5437 90.6875 44.5125 91.9063 46.8562 91.9063C49.2 91.9063 50.7 91.0625 52.8562 88.9063C54.45 87.3125 55.6687 85.9063 56.7937 84.9688Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path
style="fill:#000000"
d="M256,49.471c67.266,0,75.233.257,101.8,1.469,24.562,1.121,37.9,5.224,46.778,8.674a78.052,78.052,0,0,1,28.966,18.845,78.052,78.052,0,0,1,18.845,28.966c3.45,8.877,7.554,22.216,8.674,46.778,1.212,26.565,1.469,34.532,1.469,101.8s-0.257,75.233-1.469,101.8c-1.121,24.562-5.225,37.9-8.674,46.778a83.427,83.427,0,0,1-47.811,47.811c-8.877,3.45-22.216,7.554-46.778,8.674-26.56,1.212-34.527,1.469-101.8,1.469s-75.237-.257-101.8-1.469c-24.562-1.121-37.9-5.225-46.778-8.674a78.051,78.051,0,0,1-28.966-18.845,78.053,78.053,0,0,1-18.845-28.966c-3.45-8.877-7.554-22.216-8.674-46.778-1.212-26.564-1.469-34.532-1.469-101.8s0.257-75.233,1.469-101.8c1.121-24.562,5.224-37.9,8.674-46.778A78.052,78.052,0,0,1,78.458,78.458a78.053,78.053,0,0,1,28.966-18.845c8.877-3.45,22.216-7.554,46.778-8.674,26.565-1.212,34.532-1.469,101.8-1.469m0-45.391c-68.418,0-77,.29-103.866,1.516-26.815,1.224-45.127,5.482-61.151,11.71a123.488,123.488,0,0,0-44.62,29.057A123.488,123.488,0,0,0,17.3,90.982C11.077,107.007,6.819,125.319,5.6,152.134,4.369,179,4.079,187.582,4.079,256S4.369,333,5.6,359.866c1.224,26.815,5.482,45.127,11.71,61.151a123.489,123.489,0,0,0,29.057,44.62,123.486,123.486,0,0,0,44.62,29.057c16.025,6.228,34.337,10.486,61.151,11.71,26.87,1.226,35.449,1.516,103.866,1.516s77-.29,103.866-1.516c26.815-1.224,45.127-5.482,61.151-11.71a128.817,128.817,0,0,0,73.677-73.677c6.228-16.025,10.486-34.337,11.71-61.151,1.226-26.87,1.516-35.449,1.516-103.866s-0.29-77-1.516-103.866c-1.224-26.815-5.482-45.127-11.71-61.151a123.486,123.486,0,0,0-29.057-44.62A123.487,123.487,0,0,0,421.018,17.3C404.993,11.077,386.681,6.819,359.866,5.6,333,4.369,324.418,4.079,256,4.079h0Z"/>
<path
style="fill:#000000"
d="M256,126.635A129.365,129.365,0,1,0,385.365,256,129.365,129.365,0,0,0,256,126.635Zm0,213.338A83.973,83.973,0,1,1,339.974,256,83.974,83.974,0,0,1,256,339.973Z"/>
<circle
style="fill:#000000"
cx="390.476" cy="121.524" r="30.23"/>
</svg>

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

View file

@ -1,16 +0,0 @@
<svg width="114" height="114" viewBox="0 0 114 114" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M111.78 51.8875L62.0349 2.1486C59.1727 -0.7162 54.5267 -0.7162 51.6609 2.1486L41.3319 12.4786L54.4339 25.5806C57.4798 24.5522 60.971 25.2417 63.3978 27.669C65.8372 30.1114 66.5218 33.6324 65.4676 36.6885L78.0956 49.3165C81.1507 48.2637 84.6756 48.9439 87.1151 51.3877C90.5257 54.7973 90.5257 60.3222 87.1151 63.7327C83.704 67.1443 78.1791 67.1443 74.7661 63.7327C72.2016 61.1662 71.5673 57.3982 72.8662 54.2385L61.0892 42.4615L61.0882 73.4525C61.9197 73.8641 62.7044 74.4135 63.3973 75.1034C66.8069 78.5126 66.8069 84.0365 63.3973 87.4514C59.9867 90.8605 54.4593 90.8605 51.0523 87.4514C47.6422 84.0368 47.6422 78.5129 51.0523 75.1034C51.895 74.2622 52.8702 73.6254 53.9107 73.1986V41.9196C52.8697 41.4946 51.8957 40.8626 51.0517 40.0146C48.4687 37.4336 47.8466 33.6426 49.1713 30.4707L36.2553 17.5527L2.14928 51.6577C-0.716425 54.5247 -0.716425 59.1707 2.14928 62.0357L51.8913 111.775C54.7551 114.639 59.3995 114.639 62.2673 111.775L111.779 62.2707C114.644 59.4045 114.644 54.7571 111.779 51.8917" fill="url(#paint0_linear_372_6)"/>
<defs>
<linearGradient id="paint0_linear_372_6" x1="0" y1="0" x2="114" y2="114" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFB5C9"/>
<stop offset="0.125" stop-color="#FFB8C7"/>
<stop offset="0.25" stop-color="#FFBCC4"/>
<stop offset="0.375" stop-color="#FFBFC2"/>
<stop offset="0.5" stop-color="#FFC3BF"/>
<stop offset="0.625" stop-color="#FFC6BD"/>
<stop offset="0.75" stop-color="#FFC9BA"/>
<stop offset="0.875" stop-color="#FFCDB8"/>
<stop offset="1" stop-color="#FFD0B5"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View file

@ -1 +0,0 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Steam</title><path d="M11.979 0C5.678 0 .511 4.86.022 11.037l6.432 2.658c.545-.371 1.203-.59 1.912-.59.063 0 .125.004.188.006l2.861-4.142V8.91c0-2.495 2.028-4.524 4.524-4.524 2.494 0 4.524 2.031 4.524 4.527s-2.03 4.525-4.524 4.525h-.105l-4.076 2.911c0 .052.004.105.004.159 0 1.875-1.515 3.396-3.39 3.396-1.635 0-3.016-1.173-3.331-2.727L.436 15.27C1.862 20.307 6.486 24 11.979 24c6.627 0 11.999-5.373 11.999-12S18.605 0 11.979 0zM7.54 18.21l-1.473-.61c.262.543.714.999 1.314 1.25 1.297.539 2.793-.076 3.332-1.375.263-.63.264-1.319.005-1.949s-.75-1.121-1.377-1.383c-.624-.26-1.29-.249-1.878-.03l1.523.63c.956.4 1.409 1.5 1.009 2.455-.397.957-1.497 1.41-2.454 1.012H7.54zm11.415-9.303c0-1.662-1.353-3.015-3.015-3.015-1.665 0-3.015 1.353-3.015 3.015 0 1.665 1.35 3.015 3.015 3.015 1.663 0 3.015-1.35 3.015-3.015zm-5.273-.005c0-1.252 1.013-2.266 2.265-2.266 1.249 0 2.266 1.014 2.266 2.266 0 1.251-1.017 2.265-2.266 2.265-1.253 0-2.265-1.014-2.265-2.265z"/></svg>

Before

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1 +0,0 @@
<svg fill="#000000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>VRChat</title><path d="M22.732 6.767H1.268A1.27 1.27 0 0 0 0 8.035v5.296c0 .7.57 1.268 1.268 1.268h18.594l1.725 2.22c.215.275.443.415.68.415.153 0 .296-.06.403-.167.128-.129.193-.308.193-.536l-.002-1.939A1.27 1.27 0 0 0 24 13.331V8.035c0-.7-.569-1.269-1.268-1.269Zm.8 6.564a.8.8 0 0 1-.8.801h-.34v.031l.004 2.371c0 .155-.05.233-.129.233s-.19-.079-.31-.235l-1.866-2.4H1.268a.8.8 0 0 1-.8-.8V8.064a.8.8 0 0 1 .8-.8h21.464a.8.8 0 0 1 .8.8v5.266ZM4.444 8.573c-.127 0-.225.041-.254.15l-.877 3.129-.883-3.128c-.03-.11-.127-.15-.254-.15-.202 0-.473.126-.473.311 0 .012.005.035.011.058l1.114 3.63c.058.173.265.254.485.254s.433-.08.484-.254l1.109-3.63c.005-.023.011-.04.011-.058 0-.179-.27-.312-.473-.312Zm2.925 2.36c.433-.132.757-.49.757-1.153 0-.918-.612-1.207-1.368-1.207H5.614a.234.234 0 0 0-.242.231v3.752c0 .156.184.237.374.237s.376-.081.376-.237V11.05h.484l.82 1.593c.058.115.156.179.26.179.219 0 .467-.203.467-.393a.155.155 0 0 0-.028-.092l-.756-1.403Zm-.61-.473h-.636V9.231h.635c.375 0 .618.162.618.618s-.242.612-.618.612Zm10.056.826h1.004l-.502-1.772-.502 1.772Zm4.684-3.095H9.366a.8.8 0 0 0-.8.8v3.383a.8.8 0 0 0 .8.8h12.132a.8.8 0 0 0 .8-.8V8.992a.8.8 0 0 0-.8-.801Zm-10.946 3.977c.525 0 .571-.374.589-.617.011-.179.173-.236.369-.236.26 0 .38.075.38.369 0 .698-.57 1.142-1.379 1.142-.727 0-1.327-.357-1.327-1.322v-1.61c0-.963.606-1.322 1.333-1.322.802 0 1.374.427 1.374 1.097 0 .3-.121.37-.375.37-.214 0-.37-.064-.375-.238-.012-.178-.052-.57-.6-.57-.387 0-.606.213-.606.663v1.61c0 .45.219.664.617.664Zm4.703.388c0 .156-.19.237-.375.237s-.375-.081-.375-.237V10.9h-1.299v1.656c0 .156-.19.237-.375.237s-.375-.081-.375-.237V8.804c0-.161.185-.23.375-.23s.375.069.375.23v1.507h1.299V8.804c0-.161.185-.23.375-.23s.375.069.375.23v3.752Zm3.198.236c-.127 0-.225-.04-.254-.15l-.22-.768h-1.322l-.219.768c-.029.11-.127.15-.254.15-.202 0-.473-.127-.473-.311 0-.012.006-.035.012-.058l1.114-3.63c.051-.173.265-.254.478-.254s.433.08.485.254l1.114 3.63c.006.023.012.04.012.058 0 .179-.272.311-.473.311Zm2.989-3.543h-.843v3.306c0 .156-.19.237-.375.237s-.375-.081-.375-.237V9.25h-.848c-.15 0-.237-.157-.237-.34 0-.162.075-.336.237-.336h2.44c.162 0 .238.173.238.335 0 .18-.087.34-.237.34Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

View file

@ -1,9 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="93.2438" height="130.333" viewBox="0 0 93.2438 130.333" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="Vector 9" opacity="0.8" d="M0.134946 107.562L62.0301 0.499498C62.4189 -0.173014 63.3926 -0.164787 63.7699 0.514198L66.8764 6.10337C67.0233 6.36771 67.2819 6.55136 67.5799 6.60293L73.4547 7.61956L79.6478 8.69127C79.7492 8.70881 79.8472 8.74187 79.9384 8.7893L92.7048 15.4239C93.2048 15.6838 93.3915 16.3053 93.1173 16.7977L30.1904 129.819C29.9013 130.339 29.2259 130.493 28.7403 130.15L16.029 121.185C15.8996 121.093 15.7937 120.973 15.72 120.832L10.9287 111.708C10.7928 111.449 10.5505 111.263 10.2655 111.198L0.778585 109.037C0.121886 108.888 -0.202153 108.145 0.134946 107.562Z" fill="url(#paint0_linear_0_6)"/>
<defs>
<linearGradient id="paint0_linear_0_6" x1="46.537" y1="-1.02762" x2="46.537" y2="130.791" gradientUnits="userSpaceOnUse">
<stop stop-color="#F1C8FF"/>
<stop offset="1" stop-color="#FF92AD"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 KiB

7
react-router.config.ts Normal file
View file

@ -0,0 +1,7 @@
import type { Config } from "@react-router/dev/config";
export default {
// Config options...
// Server-side render by default, to enable SPA mode set this to `false`
ssr: true,
} satisfies Config;

View file

@ -1,489 +0,0 @@
---
import AboutRow from "@/components/AboutRow.astro";
const cards = [
{ src: "/about/cards/0.avif", alt: "활동 사진 카드" },
{ src: "/about/cards/1.avif", alt: "활동 사진 카드" },
{ src: "/about/cards/2.avif", alt: "활동 일러스트 카드" },
{ src: "/about/cards/3.avif", alt: "활동 일러스트 카드" },
{ src: "/about/cards/4.avif", alt: "활동 사진 카드" },
];
---
<section
id="about"
data-node-id="4:104"
class="min-h-[calc(100svh-64px)] snap-start bg-background text-foreground"
aria-labelledby="about-title"
>
<div class="grid min-h-full grid-cols-1 lg:grid-cols-[45fr_55fr]">
<div
class="relative z-10 flex flex-col justify-center px-6 py-16 sm:px-10 lg:px-[clamp(52px,5.208vw,100px)] lg:py-[clamp(58px,9.26vh,100px)]"
>
<h2 id="about-title" class="max-w-xl text-3xl font-semibold tracking-tight sm:text-4xl">
About<span class="text-foreground/35" aria-hidden="true">.</span>
</h2>
<p class="mt-6 max-w-lg text-base leading-8 text-foreground">
안녕하세요. 정보보안과 소프트웨어 엔지니어링을 공부하는 암냥입니다.<br/>
새로운 기술을 배우고, 머릿속의 아이디어를 실제로 작동하는 것으로<br/>
만드는 일을 좋아해요.
</p>
<section class="mt-16" aria-labelledby="experience-title">
<div class="mb-5 flex items-baseline justify-between gap-4">
<h3 id="experience-title" class="text-sm font-semibold tracking-wide">지금까지</h3>
</div>
<div class="flex flex-col gap-[0.55em]">
<AboutRow year="2026" connector="wave">
<img
class="h-[1em] w-[1em] shrink-0"
src="/about/layer7-mark.svg"
alt=""
aria-hidden="true"
/>
<span>선린인터넷고등학교 정보보안 동아리</span>
<img
class="h-[1em] w-[1em] shrink-0 [filter:var(--mono-filter)]"
src="/about/layer7-wordmark.svg"
alt=""
aria-hidden="true"
/>
<span>Layer7</span>
</AboutRow>
<AboutRow year="2026" connector="wave">
<img
class="h-[1em] w-[1em] shrink-0"
src="/about/sunrin.svg"
alt=""
aria-hidden="true"
/>
<span>선린인터넷고등학교 정보보호과</span>
</AboutRow>
<AboutRow year="2026" connector="line">
<img
class="h-[1em] w-[1em] shrink-0 object-contain"
src="/about/adofai.svg"
alt=""
aria-hidden="true"
/>
<span>ADOFAI.gg Development Team</span>
</AboutRow>
<AboutRow year="2025" connector="line">
<img
class="h-[1em] w-[1em] shrink-0 object-contain"
src="/about/whitehat.avif"
alt=""
aria-hidden="true"
/>
<span>화이트햇스쿨 3기 이수</span>
</AboutRow>
</div>
</section>
<div class="mt-8 flex flex-row items-center text-sm text-foreground/60">
<a
href="#experience"
class="flex flex-row items-center underline underline-offset-4 hover:text-foreground"
><span>전체 타임라인 보기</span>
<svg
aria-hidden="true"
class="h-4 text-foreground/40"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M7 17 17 7"></path>
<path d="M7 7h10v10"></path>
</svg></a
>
</div>
</div>
<div class="about-card-panel order-last min-h-[min(100vw,540px)] overflow-hidden bg-muted lg:sticky lg:top-0 lg:order-none lg:h-[calc(100svh-64px)] lg:min-h-0" aria-label="활동 사진 선택">
<div class="about-card-stage" data-card-stage>
<canvas class="about-card-canvas" data-card-canvas aria-hidden="true"></canvas>
<div class="about-card-access" role="group" aria-label="활동 카드 선택">
{cards.map((card, index) => (
<button
type="button"
aria-label={`활동 카드 ${index + 1} 선택`}
aria-pressed="false"
data-card-control={index}
data-card-src={card.src}
>
{card.alt}
</button>
))}
</div>
<button class="about-card-flip" type="button" data-card-flip aria-label="선택한 카드 앞뒷면 전환" hidden>
<span aria-hidden="true">↻</span>
</button>
</div>
</div>
</div>
</section>
<script>
import * as THREE from "three/src/Three.js";
const stage = document.querySelector<HTMLElement>("[data-card-stage]");
const canvas = document.querySelector<HTMLCanvasElement>("[data-card-canvas]");
const aboutSection = stage?.closest<HTMLElement>("#about");
const controls = [...document.querySelectorAll<HTMLButtonElement>("[data-card-control]")];
const flipButton = document.querySelector<HTMLButtonElement>("[data-card-flip]");
if (stage && canvas && controls.length) {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(27, 1, 0.1, 100);
camera.position.z = 15;
const renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true });
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.25));
scene.add(new THREE.HemisphereLight(0xffffff, 0x4b3447, 1.8));
const keyLight = new THREE.DirectionalLight(0xffffff, 3.6);
keyLight.position.set(-4, 6, 8);
scene.add(keyLight);
const glowLight = new THREE.PointLight(0xffc8e1, 2.4, 12);
glowLight.position.set(0, 1.5, 6);
scene.add(glowLight);
const cardWidth = 2.481875;
const cardHeight = 3.474625;
const cardDepth = 0.028;
const cardCornerRadius = 6;
const fanOffsets = [-1.95, -0.98, 0, 0.98, 1.95];
const fanHeights = [-1.45, -1.34, -1.38, -1.34, -1.45];
const fanRotations = [-0.3, -0.15, 0, 0.15, 0.3];
const loader = new THREE.TextureLoader();
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
function createCardTexture(image: HTMLImageElement) {
const texture = new THREE.Texture(image);
texture.colorSpace = THREE.SRGBColorSpace;
texture.anisotropy = Math.min(4, renderer.capabilities.getMaxAnisotropy());
texture.needsUpdate = true;
return texture;
}
function createRoundedAlphaTexture() {
const maskCanvas = document.createElement("canvas");
maskCanvas.width = 256;
maskCanvas.height = 360;
const context = maskCanvas.getContext("2d");
if (!context) return new THREE.Texture();
context.fillStyle = "white";
context.beginPath();
context.roundRect(2, 2, 252, 356, cardCornerRadius);
context.fill();
const texture = new THREE.CanvasTexture(maskCanvas);
texture.needsUpdate = true;
return texture;
}
const roundedAlphaTexture = createRoundedAlphaTexture();
let loadedTextureCount = 0;
let texturesReady = false;
let sectionVisible = false;
let deckLiftStarted = false;
let fanExpanded = false;
let deckLiftTimer: number | undefined;
const markTextureReady = () => {
loadedTextureCount += 1;
if (loadedTextureCount === controls.length + 1) {
texturesReady = true;
startDeckReveal();
}
scheduleRender();
};
const cards = controls.map((control, index) => {
const group = new THREE.Group();
const frontMaterial = new THREE.MeshBasicMaterial({
alphaMap: roundedAlphaTexture,
transparent: true,
});
const front = new THREE.Mesh(new THREE.PlaneGeometry(cardWidth, cardHeight), frontMaterial);
loader.load(control.dataset.cardSrc ?? "", (texture: THREE.Texture) => {
frontMaterial.map = createCardTexture(texture.image as HTMLImageElement);
frontMaterial.needsUpdate = true;
front.visible = true;
markTextureReady();
scheduleRender();
});
const backMaterial = new THREE.MeshBasicMaterial({
alphaMap: roundedAlphaTexture,
transparent: true,
});
const back = new THREE.Mesh(new THREE.PlaneGeometry(cardWidth, cardHeight), backMaterial);
front.visible = false;
back.visible = false;
front.position.z = cardDepth / 2 + 0.008;
back.position.z = -cardDepth / 2 - 0.008;
back.rotation.y = Math.PI;
group.add(front, back);
group.userData = { index };
group.position.set(0, -0.28, index * 0.04);
group.rotation.y = Math.PI;
group.rotation.z = 0;
scene.add(group);
return group;
});
loader.load("/about/cards/back.avif", (texture: THREE.Texture) => {
const backTexture = createCardTexture(texture.image as HTMLImageElement);
cards.forEach((card) => {
const back = card.children[1] as THREE.Mesh;
const material = back.material as THREE.MeshBasicMaterial;
material.map = backTexture;
material.needsUpdate = true;
back.visible = true;
});
markTextureReady();
scheduleRender();
});
let selectedIndex = -1;
let revealedIndex = -1;
let revealTimer: number | undefined;
let animationFrameId: number | undefined;
const pointerDown = new THREE.Vector2();
function scheduleRender() {
if (animationFrameId === undefined) animationFrameId = requestAnimationFrame(render);
}
function startDeckReveal() {
if (!texturesReady || !sectionVisible || deckLiftStarted) return;
deckLiftStarted = true;
scheduleRender();
deckLiftTimer = window.setTimeout(() => {
fanExpanded = true;
scheduleRender();
}, 620);
}
function updateControls() {
controls.forEach((control, index) => {
control.setAttribute("aria-pressed", String(index === selectedIndex));
});
if (flipButton) flipButton.hidden = selectedIndex < 0;
}
function selectCard(index: number) {
if (revealTimer !== undefined) window.clearTimeout(revealTimer);
if (index === selectedIndex) {
selectedIndex = -1;
revealedIndex = -1;
updateControls();
scheduleRender();
return;
}
selectedIndex = index;
revealedIndex = -1;
updateControls();
revealTimer = window.setTimeout(() => {
if (selectedIndex === index) revealedIndex = index;
scheduleRender();
}, 280);
scheduleRender();
}
function setPointer(event: PointerEvent) {
const bounds = canvas!.getBoundingClientRect();
pointer.set(
((event.clientX - bounds.left) / bounds.width) * 2 - 1,
-((event.clientY - bounds.top) / bounds.height) * 2 + 1,
);
}
function hitCard() {
raycaster.setFromCamera(pointer, camera);
const hit = raycaster.intersectObjects(cards, true)[0];
return hit?.object.parent?.userData.index ?? hit?.object.userData.index ?? -1;
}
controls.forEach((control, index) => {
control.addEventListener("click", () => selectCard(index));
});
flipButton?.addEventListener("click", () => {
if (selectedIndex >= 0) {
revealedIndex = revealedIndex === selectedIndex ? -1 : selectedIndex;
scheduleRender();
}
});
canvas.addEventListener("pointermove", (event) => {
setPointer(event);
});
canvas.addEventListener("pointerleave", () => {
canvas.style.cursor = "grab";
});
canvas.addEventListener("pointerdown", (event) => {
pointerDown.set(event.clientX, event.clientY);
});
canvas.addEventListener("pointerup", (event) => {
if (Math.hypot(event.clientX - pointerDown.x, event.clientY - pointerDown.y) > 8) return;
setPointer(event);
const index = hitCard();
if (index >= 0) selectCard(index);
});
const scrollRoot = aboutSection?.closest<HTMLElement>("main") ?? null;
const revealObserver = new IntersectionObserver(
([entry]) => {
if (entry?.isIntersecting) {
sectionVisible = true;
startDeckReveal();
scheduleRender();
}
},
{ root: scrollRoot, threshold: 0.35 },
);
if (aboutSection) revealObserver.observe(aboutSection);
function resize() {
const { width, height } = stage!.getBoundingClientRect();
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
const visibleWidth = 2 * camera.position.z * Math.tan(THREE.MathUtils.degToRad(camera.fov / 2)) * camera.aspect;
const scale = Math.min(1, Math.max(0.58, (visibleWidth / (fanOffsets.at(-1)! * 2 + cardWidth)) * 0.92));
scene.scale.setScalar(scale * 0.9);
scheduleRender();
}
const resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(stage);
resize();
updateControls();
let previousTime = performance.now();
function render() {
animationFrameId = undefined;
const now = performance.now();
const delta = Math.min((now - previousTime) / 1000, 0.05);
previousTime = now;
let moving = false;
cards.forEach((card, index) => {
const selected = index === selectedIndex;
card.renderOrder = selected ? 20 : index;
const targetX = fanExpanded ? fanOffsets[index] : 0;
const targetY = selected
? fanHeights[index] + 2
: (fanExpanded ? fanHeights[index] : (deckLiftStarted ? -0.28 : -2.4));
const targetZ = selected ? 2.6 : index * 0.04;
const targetScale = selected ? 1.05 : 1;
card.position.x = THREE.MathUtils.damp(card.position.x, targetX, 5.5, delta);
card.position.y = THREE.MathUtils.damp(card.position.y, targetY, 5.5, delta);
card.position.z = THREE.MathUtils.damp(card.position.z, targetZ, 5.5, delta);
card.scale.setScalar(THREE.MathUtils.damp(card.scale.x, targetScale, 5.5, delta));
const targetRotation = fanExpanded ? fanRotations[index] : 0;
card.rotation.z = THREE.MathUtils.damp(card.rotation.z, targetRotation, 5.5, delta);
card.rotation.y = THREE.MathUtils.damp(card.rotation.y, revealedIndex === index ? 0 : Math.PI, 7, delta);
moving ||= Math.abs(card.position.x - targetX) > 0.001
|| Math.abs(card.position.y - targetY) > 0.001
|| Math.abs(card.position.z - targetZ) > 0.001
|| Math.abs(card.rotation.z - targetRotation) > 0.001
|| Math.abs(card.rotation.y - (revealedIndex === index ? 0 : Math.PI)) > 0.001;
});
renderer.render(scene, camera);
if (moving) scheduleRender();
}
scheduleRender();
}
</script>
<style>
.about-card-panel {
position: relative;
isolation: isolate;
}
.about-card-stage {
position: relative;
display: grid;
height: 100%;
min-height: 540px;
place-items: center;
overflow: hidden;
background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--background) 96%, white), var(--muted));
}
.about-card-stage::before {
position: absolute;
left: 50%;
bottom: 16%;
width: min(78%, 640px);
height: 18%;
border-radius: 50%;
background: color-mix(in srgb, var(--foreground) 14%, transparent);
content: "";
filter: blur(28px);
opacity: .22;
pointer-events: none;
transform: translateX(-50%);
}
.about-card-canvas {
display: block;
width: 100%;
height: 100%;
touch-action: none;
cursor: grab;
position: relative;
z-index: 1;
}
.about-card-access {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
clip-path: inset(50%);
white-space: nowrap;
}
.about-card-access button {
width: 1px;
height: 1px;
}
.about-card-flip {
position: absolute;
right: 28px;
bottom: 28px;
display: grid;
width: 42px;
height: 42px;
place-items: center;
z-index: 2;
border: 1px solid color-mix(in srgb, var(--foreground) 18%, transparent);
border-radius: 999px;
color: var(--foreground);
background: color-mix(in srgb, var(--background) 72%, transparent);
font-size: 21px;
cursor: pointer;
backdrop-filter: blur(10px);
box-shadow: 0 8px 24px rgb(32 17 29 / 10%);
transition: transform 220ms ease, background 220ms ease, box-shadow 220ms ease;
}
.about-card-flip:hover,
.about-card-flip:focus-visible {
outline: none;
background: var(--background);
transform: rotate(45deg);
box-shadow: 0 10px 28px rgb(32 17 29 / 16%);
}
@media (prefers-reduced-motion: reduce) {
.about-card-flip {
transition: none;
}
}
</style>

View file

@ -1,29 +0,0 @@
---
interface Props {
year: string;
connector: "wave" | "line";
}
const { year, connector } = Astro.props;
const connectorClass =
connector === "wave"
? "h-[0.17em] w-[0.52em] [filter:var(--mono-filter)]"
: "h-[0.1em] w-[0.55em] [filter:var(--mono-filter)]";
---
<div
class="grid min-w-0 grid-cols-[2.25em_0.55em_minmax(0,1fr)] items-center gap-[0.5em]"
>
<time class="whitespace-nowrap" datetime={year}>{year}</time>
<img
class={connectorClass}
src={`/about/separator-${connector}.svg`}
alt=""
aria-hidden="true"
/>
<div
class="flex min-w-0 flex-wrap items-center gap-x-[0.34em] gap-y-[0.2em] lg:flex-nowrap"
>
<slot />
</div>
</div>

View file

@ -1,187 +0,0 @@
---
const contacts = [
{ name: "Email", icon: "mail", action: "dialog" },
{ name: "Blog", icon: "rss", url: "https://blog.imnya.ng" },
{ name: "GitHub", icon: "github", url: "https://github.com/imnyang" },
{
name: "git.mizuki.guru",
icon: "git",
url: "https://git.mizuki.guru/imnyang",
},
{
name: "Instagram",
icon: "instagram",
url: "https://instagram.com/imnya.ng",
},
{ name: "𝕏", icon: "x", url: "https://x.com/imnya_ng" },
];
const emailContacts = [
{ label: "Personal", address: "me@imnya.ng" },
{ label: "Dazzle.st", address: "imnyang@dazzle.st" },
];
const icons: Record<string, string> = {
mail: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>`,
rss: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg>`,
github: `<img src="/icon/github.svg" width="24" height="24" alt="GitHub" class="h-6 w-6 transition-[filter] duration-300 [filter:var(--mono-filter)]" />`,
git: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" x2="6" y1="3" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>`,
instagram: `<img src="/icon/instagram.svg" width="18" height="18" alt="Instagram" class="h-4 w-4 transition-[filter] duration-300 [filter:var(--mono-filter)]" />`,
x: `<p class="text-[20px] font-bold leading-none">𝕏</p>`,
};
---
<div class="flex flex-row space-x-4 relative select-none">
{
contacts.map((c) =>
c.action === "dialog" ? (
<button
type="button"
id="email-btn"
title={c.name}
class="flex items-center space-x-2 text-foreground/80 hover:text-foreground transition-colors hover:cursor-pointer"
set:html={icons[c.icon]}
/>
) : (
<a
href={c.url}
target="_blank"
rel="noopener noreferrer"
title={c.name}
class="flex items-center space-x-2 text-foreground/80 hover:text-foreground transition-colors"
set:html={icons[c.icon]}
/>
),
)
}
</div>
<!-- Email Dialog -->
<div
id="email-dialog"
class="hidden fixed inset-0 z-50 flex items-center justify-center"
role="dialog"
aria-modal="true"
aria-label="Contact Me"
>
<div id="email-dialog-backdrop" class="absolute inset-0 bg-black/50"></div>
<div
class="relative z-10 bg-background border border-border rounded-xl shadow-xl p-6 w-full max-w-sm mx-4"
>
<h2 class="text-lg font-semibold mb-1">Contact Me</h2>
<p class="text-sm text-muted-foreground mb-4">
이메일 주소를 클릭하면 복사되고, 더블클릭하면 메일 앱이 열립니다.
</p>
<div class="flex flex-col gap-3">
{
emailContacts.map((ec) => (
<div>
<p class="text-xs text-muted-foreground mb-1">
{ec.label}
</p>
<button
type="button"
data-email={ec.address}
class="email-copy-btn w-full flex items-center gap-3 border border-border rounded-lg px-4 py-2.5 hover:bg-muted transition-colors text-left active:scale-95 transition-transform"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="shrink-0"
>
<>
<rect
width="20"
height="16"
x="2"
y="4"
rx="2"
/>
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
</>
</svg>
<span class="flex-1 text-sm">{ec.address}</span>
<span class="copy-icon text-muted-foreground">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<>
<rect
width="14"
height="14"
x="8"
y="8"
rx="2"
ry="2"
/>
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
</>
</svg>
</span>
</button>
</div>
))
}
</div>
<div class="mt-5 flex justify-end">
<button
type="button"
id="email-dialog-close"
class="px-4 py-2 rounded bg-muted text-foreground text-sm hover:bg-muted/80 transition-colors cursor-pointer"
>
Close
</button>
</div>
</div>
</div>
<script>
const dialog = document.getElementById("email-dialog")!;
const openBtn = document.getElementById("email-btn")!;
const closeBtn = document.getElementById("email-dialog-close")!;
const backdrop = document.getElementById("email-dialog-backdrop")!;
const open = () => dialog.classList.remove("hidden");
const close = () => dialog.classList.add("hidden");
openBtn.addEventListener("click", open);
closeBtn.addEventListener("click", close);
backdrop.addEventListener("click", close);
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") close();
});
document
.querySelectorAll<HTMLButtonElement>(".email-copy-btn")
.forEach((btn) => {
const email = btn.dataset.email!;
const copyIcon = btn.querySelector(".copy-icon")!;
btn.addEventListener("click", async () => {
await navigator.clipboard.writeText(email);
copyIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>`;
setTimeout(() => {
copyIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`;
}, 1200);
});
btn.addEventListener("dblclick", () => {
window.location.href = `mailto:${email}`;
});
});
</script>

View file

@ -1,696 +0,0 @@
---
// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below.
const groups = [
{
id: "direct",
title: "연락처",
items: [
{
name: "개인 이메일",
value: "me@imnya.ng",
href: "mailto:me@imnya.ng",
icon: "mail",
tone: "pink",
email: true,
},
{
name: "dazzle.st 이메일",
value: "imnyang@dazzle.st",
href: "mailto:imnyang@dazzle.st",
icon: "mail",
tone: "green",
email: true,
},
{
name: "Discord",
value: "@imnyang",
href: "https://discord.com/users/909353223901569035",
icon: "discord",
tone: "purple",
},
],
},
{
id: "social",
title: "소셜",
items: [
{
name: "X (Twitter)",
value: "@imnya_ng",
href: "https://twitter.com/imnya_ng",
icon: "x",
tone: "blue",
},
{
name: "Instagram",
value: "@imnya.ng",
href: "https://instagram.com/imnya.ng",
icon: "instagram",
tone: "pink",
},
{
name: "YouTube",
value: "@imnyang",
href: "https://youtube.com/@imnyang",
icon: "youtube",
tone: "red",
},
],
},
{
id: "work",
title: "코드와 글",
items: [
{
name: "GitHub",
value: "@imnyang",
href: "https://github.com/imnyang",
icon: "github",
tone: "neutral",
},
{
name: "git.mizuki.guru",
value: "@imnyang",
href: "https://git.mizuki.guru/imnyang",
icon: "mizuki",
tone: "orange",
},
{
name: "Blog",
value: "blog.imnya.ng",
href: "https://blog.imnya.ng",
icon: "blog",
tone: "green",
},
],
},
{
id: "game",
title: "Game",
items: [
{
name: "Steam",
value: "@imnyang",
href: "https://steamcommunity.com/id/imnyang/",
icon: "steam",
tone: "blue",
},
{
name: "maimai",
value: "@imnya.ng",
href: "https://mai.sft.sh/imnyang",
icon: "maimai",
tone: "blue",
},
{
name: "Project Sekai KR",
value: "7354623251148069648",
copy: true,
icon: "project-sekai",
tone: "blue",
},
{
name: "Project Sekai JP",
value: "729310364018688008",
copy: true,
icon: "project-sekai",
tone: "blue",
},
{
name: "VRChat",
value: "@imnyang",
href: "https://vrchat.com/home/user/usr_d53ac697-182d-40d0-9fd8-1a7442b0ebfd",
icon: "vrchat",
tone: "blue",
},
],
},
];
// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below.
const imageIcons: Record<string, { src: string; monochrome: boolean }> = {
github: { src: "/icon/github.svg", monochrome: true },
discord: { src: "/icon/discord.svg", monochrome: true },
mizuki: { src: "/icon/mizuki.svg", monochrome: false },
// Source: https://github.com/simple-icons/simple-icons/blob/develop/icons/steam.svg
steam: { src: "/icon/steam.svg", monochrome: true },
maimai: { src: "/icon/maimai.webp", monochrome: false },
vrchat: { src: "/icon/vrchat.svg", monochrome: true },
// Source: https://pjsekai.sega.jp/assets/data/webp/icon/icon_app.png.webp
"project-sekai": { src: "/icon/project-sekai.webp", monochrome: false },
};
// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below.
const paths: Record<string, string> = {
mail: "M22 12a10 10 0 1 0-4 8 M16 8v5a3 3 0 0 0 6 0v-1 M16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0",
x: "M4 3h4l12 18h-4L4 3Z M20 3l-7 8 M4 21l7-8",
instagram:
"M7 3h10a4 4 0 0 1 4 4v10a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V7a4 4 0 0 1 4-4Z M16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0 M17.5 6.5h.01",
youtube:
"M7 5h10a5 5 0 0 1 5 5v4a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5v-4a5 5 0 0 1 5-5Z M10 9l5 3-5 3V9Z",
blog: "M5 3h11l3 3v15H5V3Z M15 3v4h4 M9 11h6 M9 15h6",
};
---
<section id="contact" class="contact-section snap-start" aria-labelledby="contact-title">
<div class="contact-content">
<header class="contact-heading">
<h2 id="contact-title">Contact<span aria-hidden="true">.</span></h2>
<p class="contact-description">
새로운 이야기와 재미있는 만남은 언제나 환영해요.
</p>
</header>
<div class="contact-groups">
{
groups.map((group) => (
<section aria-labelledby={`contact-${group.id}`}>
<h3
id={`contact-${group.id}`}
class="contact-group-title"
>
{group.title}
</h3>
<ul class="contact-list">
{group.items.map((item) => (
<li class="contact-row">
{"copy" in item ? (
<button
class="contact-link contact-copy-link"
type="button"
data-contact-copy={item.value}
aria-label={`${item.name} ${item.value} 복사`}
>
<span
class={`contact-icon tone-${item.tone}`}
aria-hidden="true"
>
{imageIcons[item.icon] ? (
<img
src={
imageIcons[item.icon]
.src
}
width="22"
height="22"
alt=""
class:list={{
"mono-icon":
imageIcons[
item.icon
].monochrome,
}}
/>
) : (
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.7"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d={paths[item.icon]}
/>
</svg>
)}
</span>
<span class="contact-name">
{item.name}
</span>
<span class="contact-value">
{item.value}
</span>
<span
class="contact-copy-indicator"
aria-hidden="true"
>
<svg
class="copy-symbol"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect
x="8"
y="8"
width="12"
height="12"
rx="2"
/>
<path d="M16 8V4a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h4" />
</svg>
<svg
class="copied-symbol"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="m5 12 4 4L19 6" />
</svg>
</span>
</button>
) : (
<a
class="contact-link"
href={item.href}
target={
"email" in item
? undefined
: "_blank"
}
rel={
"email" in item
? undefined
: "noopener noreferrer"
}
>
<span
class={`contact-icon tone-${item.tone}`}
aria-hidden="true"
>
{imageIcons[item.icon] ? (
<img
src={
imageIcons[item.icon]
.src
}
width="22"
height="22"
alt=""
class:list={{
"mono-icon":
imageIcons[
item.icon
].monochrome,
}}
/>
) : (
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.7"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d={paths[item.icon]}
/>
</svg>
)}
</span>
<span class="contact-name">
{item.name}
</span>
<span class="contact-value">
{item.value}
</span>
{!("email" in item) && (
<svg
class="contact-arrow"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M7 17 17 7M7 7h10v10" />
</svg>
)}
</a>
)}
{"email" in item && (
<button
class="contact-copy"
type="button"
data-contact-email={item.value}
aria-label={`${item.value} 복사`}
title="이메일 주소 복사"
>
<svg
class="copy-symbol"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect
x="8"
y="8"
width="12"
height="12"
rx="2"
/>
<path d="M16 8V4a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h4" />
</svg>
<svg
class="copied-symbol"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="m5 12 4 4L19 6" />
</svg>
</button>
)}
</li>
))}
</ul>
</section>
))
}
</div>
<div class="contact-footer">
<p>여기까지 와주셔서 고마워요.</p>
<a href="#home">맨 위로 <span aria-hidden="true">↑</span></a>
</div>
<p
class="contact-status"
role="status"
aria-live="polite"
aria-atomic="true"
>
</p>
</div>
</section>
<style>
.contact-section {
--contact-top-spacing: clamp(48px, 7vw, 88px);
min-height: calc(100svh - 64px);
padding: var(--contact-top-spacing) clamp(24px, 5.208vw, 100px) 32px;
}
.contact-content {
max-width: 1080px;
margin-inline: auto;
}
.contact-heading {
display: flow-root;
padding-bottom: 32px;
border-bottom: 1px solid var(--border);
}
.contact-eyebrow {
font-size: 11px;
font-weight: 700;
letter-spacing: 0.16em;
color: var(--muted-foreground);
}
h2 {
margin-top: 8px;
font-size: clamp(36px, 5vw, 52px);
font-weight: 750;
letter-spacing: -0.045em;
line-height: 1.15;
}
h2 span {
color: #dc6291;
}
.contact-description {
margin-top: 14px;
font-size: 14px;
color: color-mix(in srgb, var(--foreground) 65%, var(--background));
word-break: keep-all;
}
.contact-groups {
display: grid;
gap: 28px;
margin-top: 28px;
}
.contact-group-title {
margin-bottom: 12px;
font-size: 15px;
font-weight: 700;
}
.contact-list {
display: grid;
gap: 8px;
}
.contact-row {
display: flex;
min-width: 0;
border: 1px solid var(--border);
border-radius: 9px;
transition:
background-color 160ms,
border-color 160ms;
}
.contact-row:hover,
.contact-row:focus-within {
background: var(--muted);
border-color: color-mix(
in srgb,
var(--foreground) 22%,
var(--background)
);
}
.contact-link {
display: grid;
grid-template-columns: 22px auto minmax(0, 1fr) 18px;
gap: 12px;
align-items: center;
flex: 1;
min-width: 0;
min-height: 58px;
padding: 12px 18px;
border-radius: 8px;
text-decoration: none;
}
.contact-copy-link {
width: 100%;
border: 0;
background: transparent;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
}
.contact-row:has(.contact-copy) .contact-link {
grid-template-columns: 22px auto minmax(0, 1fr);
padding-right: 0;
}
.contact-icon {
display: flex;
align-items: center;
justify-content: center;
}
.contact-icon svg,
.contact-icon img {
width: 21px;
height: 21px;
object-fit: contain;
}
.mono-icon {
filter: var(--mono-filter);
}
.tone-pink {
color: #ce5484;
}
.tone-green {
color: #46916c;
}
.tone-purple {
color: #8279e2;
}
.tone-blue {
color: #569fc9;
}
.tone-red {
color: #d96570;
}
.tone-orange {
color: #c58055;
}
.contact-name {
font-size: 14px;
font-weight: 650;
}
.contact-value {
text-align: right;
font-size: 14px;
color: color-mix(in srgb, var(--foreground) 65%, var(--background));
overflow-wrap: anywhere;
}
.contact-arrow {
width: 18px;
height: 18px;
color: var(--muted-foreground);
transition:
transform 160ms,
color 160ms;
}
.contact-link:hover .contact-arrow {
transform: translate(2px, -2px);
color: var(--foreground);
}
.contact-copy {
display: grid;
place-items: center;
align-self: center;
width: 44px;
height: 44px;
margin: 0 5px;
flex-shrink: 0;
border-radius: 6px;
color: var(--muted-foreground);
cursor: pointer;
}
.contact-copy-indicator {
display: grid;
place-items: center;
width: 18px;
height: 18px;
color: var(--muted-foreground);
transition: color 160ms;
}
.contact-copy-link:hover .contact-copy-indicator {
color: var(--foreground);
}
.contact-copy-indicator svg {
width: 17px;
height: 17px;
grid-area: 1 / 1;
}
.contact-copy:hover {
color: var(--foreground);
background: color-mix(in srgb, var(--foreground) 7%, transparent);
}
.contact-copy svg {
width: 17px;
height: 17px;
}
.copied-symbol,
.contact-copy[data-copied] .copy-symbol,
.contact-copy-link[data-copied] .copy-symbol {
display: none;
}
.contact-copy[data-copied] .copied-symbol,
.contact-copy-link[data-copied] .copied-symbol {
display: block;
color: #46916c;
}
.contact-link:focus-visible,
.contact-copy:focus-visible,
.contact-footer a:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 3px;
}
.contact-footer {
display: flex;
justify-content: space-between;
gap: 16px;
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid var(--border);
font-size: 12px;
color: var(--muted-foreground);
}
.contact-footer a {
flex-shrink: 0;
border-radius: 2px;
}
.contact-footer a:hover {
color: var(--foreground);
}
.contact-footer span {
margin-left: 8px;
}
.contact-status {
min-height: 20px;
margin-top: 12px;
font-size: 12px;
color: var(--foreground);
text-align: right;
}
@media (max-width: 540px) {
.contact-link,
.contact-row:has(.contact-copy) .contact-link {
grid-template-columns: 22px minmax(0, 1fr) 18px;
gap: 4px 12px;
padding: 14px;
}
.contact-row:has(.contact-copy) .contact-link {
grid-template-columns: 22px minmax(0, 1fr);
padding-right: 0;
}
.contact-icon {
grid-row: 1 / 3;
}
.contact-name {
grid-column: 2;
font-size: 13px;
}
.contact-value {
grid-column: 2;
grid-row: 2;
text-align: left;
font-size: 12px;
}
.contact-arrow {
grid-column: 3;
grid-row: 1 / 3;
}
.contact-copy-link .contact-copy-indicator {
grid-column: 3;
grid-row: 1 / 3;
}
}
@media (prefers-reduced-motion: reduce) {
.contact-row,
.contact-arrow {
transition: none;
}
.contact-link:hover .contact-arrow {
transform: none;
}
}
</style>
<script>
const contactStatus =
document.querySelector<HTMLElement>(".contact-status");
document
.querySelectorAll<HTMLButtonElement>(
"[data-contact-email], [data-contact-copy]",
)
.forEach((button) => {
let resetTimer: ReturnType<typeof setTimeout>;
button.addEventListener("click", async () => {
const value =
button.dataset.contactEmail ?? button.dataset.contactCopy;
if (!value) return;
try {
await navigator.clipboard.writeText(value);
clearTimeout(resetTimer);
button.dataset.copied = "true";
button.setAttribute("aria-label", `${value} 복사 완료`);
if (contactStatus)
contactStatus.textContent = `${value}를 복사했어요.`;
resetTimer = setTimeout(() => {
delete button.dataset.copied;
button.setAttribute("aria-label", `${value} 복사`);
}, 2000);
} catch {
if (contactStatus)
contactStatus.textContent =
"복사하지 못했어요. 값을 직접 선택해 복사해주세요.";
}
});
});
</script>

View file

@ -1,31 +0,0 @@
---
export interface Props {
targetDate: string;
label?: string;
}
const { targetDate, label } = Astro.props;
---
<div class="flex flex-row items-start text-left text-base gap-2">
<span class="text-foreground"
>{label && `${label} | `}{
new Date(targetDate).toLocaleDateString()
}</span
>
<span id="dday-label">D-Day</span>
</div>
<script define:vars={{ targetDate }}>
const today = new Date();
const target = new Date(targetDate);
const diffTime = target.getTime() - today.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
let label = "D-Day";
if (diffDays > 0) label = `D-${diffDays}`;
else if (diffDays < 0) label = `D+${Math.abs(diffDays)}`;
const el = document.getElementById("dday-label");
if (el) el.textContent = label;
</script>

View file

@ -1,218 +0,0 @@
---
const videoUrl =
"https://www.youtube.com/live/5HDW7u3xt6Y?si=SgPxg83YMdeqGo3t&t=8366";
const roles = ["Broadcast Manager", "ARG Creator", "Developer"];
---
<section
id="projects"
class="min-h-[calc(100svh-64px)] snap-start bg-background text-foreground"
aria-labelledby="projects-title"
>
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
<div
class="px-6 py-12 sm:px-10 lg:px-[clamp(52px,5.208vw,100px)] lg:py-[clamp(58px,9.26vh,100px)]"
>
<div class="max-w-[654px] break-keep">
<h2
id="projects-title"
class="mt-5 text-[clamp(32px,3.1vw,54px)] font-bold leading-[1.2] tracking-[-0.04em]"
>
무대 뒤에서,<br />경험을 만들면서...
</h2>
<p
class="mt-6 max-w-[32rem] text-base leading-relaxed text-foreground/65"
>
불과 얼음의 춤(A Dance of Fire and Ice)의 이펙트 제작과
플레이를<br /> 함께 다루는 대회, Effect Playing Contest. 2025와
Finale 시즌에 참여하며 방송부터 ARG, 개발까지 함께했어요.
</p>
<ul
class="mt-6 flex flex-wrap gap-x-4 gap-y-2 text-[13px] font-semibold"
aria-label="담당 역할"
>
{
roles.map((role) => (
<li class="border-b-2 border-[#ff92ad]/60 pb-1">
{role}
</li>
))
}
</ul>
<div class="mt-10 space-y-7">
<article
class="border-t border-foreground/15 pt-5"
aria-labelledby="epc-finale-title"
>
<div
class="mb-2 flex items-center gap-3 text-xs font-medium text-foreground/50"
>
<span>01</span><span>2026 · FINALE</span>
</div>
<h3
id="epc-finale-title"
class="text-[clamp(21px,1.7vw,28px)] font-bold tracking-[-0.025em]"
>
Effect Playing Contest : Finale
</h3>
<p
class="mt-3 text-sm leading-[1.85] text-foreground/65"
>
달성이 주관하고 ADOFAI.gg가 공동 주최하는 EPC의
마지막 시즌이에요.<br /> 방송 화면 개발과 운영을 맡고,
대회의 퍼즐을 경험하는 ARG를 제작했었어요.
</p>
<a
href="https://www.youtube.com/playlist?list=PLZeYZotn5_IM15cD3W2y5SAtI83xXE226"
target="_blank"
rel="noopener noreferrer"
class="mt-4 inline-block text-sm font-semibold underline decoration-foreground/25 underline-offset-4 hover:decoration-current focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ring"
>Finale 영상 플레이리스트 <span aria-hidden="true"
>↗</span
></a
>
</article>
<article
class="border-t border-foreground/15 pt-5"
aria-labelledby="epc-2025-title"
>
<div
class="mb-2 flex items-center gap-3 text-xs font-medium text-foreground/50"
>
<span>02</span><span>2025</span>
</div>
<h3
id="epc-2025-title"
class="text-[clamp(21px,1.7vw,28px)] font-bold tracking-[-0.025em]"
>
Effect Playing Contest 2025
</h3>
<p
class="mt-3 text-sm leading-[1.85] text-foreground/65"
>
이펙트 제작자와 플레이어가 각자의 실력을 선보이는
리듬 게임 대회입니다. 방송 화면의 대부분의 기능을
개발하고, 방송 운영을 담당했습니다.
</p>
<a
href="https://www.youtube.com/playlist?list=PLZeYZotn5_IOJDek6e35NKzUtJm09yxZD"
target="_blank"
rel="noopener noreferrer"
class="mt-4 inline-block text-sm font-semibold underline decoration-foreground/25 underline-offset-4 hover:decoration-current focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ring"
>2025 영상 플레이리스트 <span aria-hidden="true"
>↗</span
></a
>
</article>
</div>
</div>
</div>
<div
class="grid min-w-0 items-center overflow-hidden px-4 pt-8 pb-[52px] lg:sticky lg:top-0 lg:h-[calc(100svh-64px)] lg:min-h-[560px] lg:self-start lg:py-6 lg:pr-7 lg:pl-0"
aria-label="EPC 방송과 ARG 작업 사진"
>
<div class="relative mx-auto aspect-[0.98] w-full max-w-[880px]">
<figure
class="absolute top-[9%] left-[6%] z-[2] m-0 w-[80%] -rotate-[5deg]"
>
<div
class="aspect-video overflow-hidden rounded-xl bg-[#18141f] shadow-[0_12px_36px_#00000014]"
id="epc-video"
>
<button
class="group relative block h-full w-full cursor-pointer border-0 bg-transparent p-0 text-white focus-visible:outline-2 focus-visible:outline-offset-[-5px] focus-visible:outline-[#ff92ad]"
type="button"
aria-label="EPC Finale 후기 영상 재생"
>
<img
class="block h-full w-full object-cover"
src="/projects/epc-finale.avif"
alt="썸네일"
width="655"
height="387"
loading="lazy"
decoding="async"
/>
<span
class="absolute top-1/2 left-1/2 grid aspect-square w-[clamp(40px,4vw,64px)] -translate-x-1/2 -translate-y-1/2 place-items-center rounded-full border border-[#ffffff80] bg-[#17121d99] pl-[3px] backdrop-blur-[8px] transition-colors duration-200 group-hover:bg-[#17121de6] motion-reduce:transition-none"
aria-hidden="true">▶</span
>
<span
class="absolute inset-x-0 bottom-0 flex justify-between gap-2 bg-gradient-to-b from-transparent to-[#000c] px-4 pt-[30px] pb-3 text-left text-[clamp(10px,1vw,14px)] font-semibold"
>후기 영상
</span>
</button>
</div>
<img
class="absolute top-[-13%] left-[-5%] z-[3] pointer-events-none h-auto w-[13%] aspect-[94/131] rotate-[10deg]"
src="/projects/tape.svg"
alt=""
width="94"
height="131"
/>
<img
class="absolute top-[-13%] right-[-5%] z-[3] pointer-events-none h-auto w-[13%] aspect-[94/131] rotate-[100deg]"
src="/projects/tape.svg"
alt=""
width="94"
height="131"
/>
</figure>
<figure
class="absolute top-[47%] left-[21%] z-[1] m-0 w-[70%] rotate-[5deg] pointer-events-none select-none"
>
<img
class="block h-auto w-full pointer-events-none overflow-hidden rounded-2xl shadow-[0_12px_36px_#00000014] focus-visible:rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ring"
src="/projects/IMG_0170.avif"
alt="점자로 보이는 단서가 적힌 찢어진 종이와 태블릿, 펜이 놓인 ARG 작업 사진"
width="2880"
height="2160"
loading="lazy"
decoding="async"
/>
<img
class="absolute bottom-[-10%] left-[-6%] z-[3] pointer-events-none h-auto w-[13%] aspect-[94/131] rotate-90"
src="/projects/tape.svg"
alt=""
width="94"
height="131"
/>
<img
class="absolute top-[-9%] right-[-5%] z-[3] pointer-events-none h-auto w-[13%] aspect-[94/131] rotate-[100deg]"
src="/projects/tape.svg"
alt=""
width="94"
height="131"
/>
</figure>
</div>
</div>
</div>
</section>
<script>
const videoFrame = document.getElementById("epc-video");
const playButton = videoFrame?.querySelector("button");
playButton?.addEventListener(
"click",
() => {
if (!videoFrame) return;
const player = document.createElement("iframe");
player.src =
"https://www.youtube-nocookie.com/embed/3NY8vgxvKaU?autoplay=1&playsinline=1";
player.title = "EPC : Finale 방송화면에 이런 비밀이???";
player.allow =
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";
player.allowFullscreen = true;
player.referrerPolicy = "strict-origin-when-cross-origin";
player.className = "block h-full w-full border-0";
videoFrame.replaceChildren(player);
player.focus();
},
{ once: true },
);
</script>

View file

@ -1,145 +0,0 @@
---
import { events } from "@/lib/events";
const sortedEvents = [...events].sort((a, b) => b.date.localeCompare(a.date));
const years = [...new Set(sortedEvents.map((event) => event.date.slice(0, 4)))];
// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below.
const eventsByYear = years.map((year) => ({
year,
events: sortedEvents.filter((event) => event.date.startsWith(year)),
}));
// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below.
const getShortDate = (date: string) => {
const [, month, day] = date.split("-");
return `${month}.${day}`;
};
const currentYear = new Date().getFullYear();
// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below.
const daysUntilYearEnd = Math.ceil(
(new Date(currentYear + 1, 0, 1).getTime() - Date.now()) /
(1000 * 60 * 60 * 24),
);
---
<section
id="experience"
data-node-id="4:104"
class="min-h-[calc(100svh-64px)] snap-start bg-background text-foreground"
aria-labelledby="experience-title"
>
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
<div
class="relative z-10 px-6 py-12 sm:px-10 lg:px-[clamp(52px,5.208vw,100px)] lg:py-[clamp(58px,9.26vh,100px)]"
>
<div
class="max-w-[654px] break-keep text-[24px] leading-[1.2] tracking-[-0.02em] lg:leading-none"
>
<p id="experience-title">
저는 <b>{years.length}년간 {events.length}개</b>의 개성있는
조각들을 모아왔어요.
</p>
<section class="mt-[0.75em]" aria-label="Experience">
{
eventsByYear.map(({ year, events: yearEvents }) => (
<section
class="py-[0.55em]"
aria-labelledby={`experience-${year}`}
>
<div class="flex items-center gap-3">
<h3
id={`experience-${year}`}
class="text-[0.62em] font-bold leading-none"
>
{year}
</h3>
<span class="text-[0.43em] font-medium tracking-[0.04em] text-foreground/45">
{yearEvents.length}{" "}
{yearEvents.length === 1
? "EVENT"
: "EVENTS"}
</span>
<div class="h-px flex-1 bg-foreground/10" />
</div>
<ol class="mt-[0.35em]">
{yearEvents.map((event) => (
<li class="grid min-w-0 grid-cols-[3.5em_minmax(0,1fr)] gap-x-[0.6em] border-b border-foreground/[0.07] py-[0.48em] last:border-b-0">
<time
class="pt-[0.08em] text-[0.55em] font-medium tabular-nums tracking-[0.02em] text-foreground/50"
datetime={event.date}
>
{getShortDate(event.date)}
</time>
<div class="min-w-0">
<div class="mb-[0.12em] flex items-center gap-[0.45em]">
<span class="text-[0.43em] font-semibold tracking-[0.04em] text-foreground/50">
{event.category}
</span>
{event.link && (
<svg
aria-hidden="true"
class="h-[0.52em] w-[0.52em] text-foreground/40"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M7 17 17 7" />
<path d="M7 7h10v10" />
</svg>
)}
</div>
{event.link ? (
<a
href={event.link}
target="_blank"
rel="noopener noreferrer"
class="text-[0.62em] leading-[1.35] underline decoration-foreground/20 underline-offset-2 transition-colors hover:decoration-foreground focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-foreground"
>
{event.description}
</a>
) : (
<p class="text-[0.62em] leading-[1.35]">
{event.description}
</p>
)}
</div>
</li>
))}
</ol>
{year === currentYear.toString() && (
<div class="my-8 flex items-center gap-4">
<div class="flex-1 h-px bg-foreground/10" />
<span class="text-xs text-muted-foreground whitespace-nowrap">
✨ | D-{daysUntilYearEnd}동안
만들어나갈 멋진 것들을 기대해주세요.
</span>
<div class="flex-1 h-px bg-foreground/10" />
</div>
)}
</section>
))
}
</section>
</div>
</div>
<div
class="relative order-last h-[min(100vw,480px)] min-h-0 overflow-hidden lg:sticky lg:top-0 lg:order-none lg:h-[calc(100svh-64px)] lg:min-h-0 lg:self-start"
aria-label="활동 사진"
>
<img
class="absolute inset-0 h-full w-full select-none pointer-events-none object-contain"
src="/side.avif"
alt="활동 사진 콜라주"
width="3840"
height="4320"
/>
</div>
</div>
</section>

View file

@ -1,117 +0,0 @@
---
const navigationItems = [
{ label: "Home", href: "#home" },
{ label: "About", href: "#about" },
{ label: "Projects", href: "#projects" },
{ label: "Experience", href: "#experience" },
{ label: "Contact", href: "#contact" },
] as const;
const desktopLinkClass =
"text-foreground no-underline transition-opacity duration-150 hover:opacity-55 focus-visible:opacity-55";
const mobileLinkClass =
"block rounded-xl px-3 py-2 text-sm font-semibold text-foreground no-underline transition-colors hover:bg-foreground/5";
---
<header
data-node-id="43:26"
class="fixed inset-x-0 top-0 z-50 flex h-[64px] items-center justify-between overflow-clip border-b border-foreground/[0.06] bg-background/90 px-[clamp(26px,2.5vw,48px)] backdrop-blur-xl transition-colors duration-300 max-md:overflow-visible max-md:px-6"
>
<a
class="shrink-0 text-2xl font-bold leading-[normal] text-foreground no-underline max-md:text-xl"
href="#home"
data-node-id="43:28">@imnya.ng</a
>
<div id="navigation" class="relative flex shrink-0 items-center">
<nav
class="flex shrink-0 items-center gap-4 whitespace-nowrap text-base font-semibold leading-[1.5] tracking-[-0.02em] max-md:hidden"
aria-label="주요 메뉴"
data-node-id="43:40"
>
{
navigationItems.map((item) => (
<a
class={desktopLinkClass}
href={item.href}
>
{item.label}
</a>
))
}
</nav>
<button
id="menu-toggle"
type="button"
class="relative hidden h-10 w-10 items-center justify-center rounded-full text-foreground transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-foreground max-md:flex"
aria-label="메뉴 열기"
aria-controls="mobile-nav"
aria-expanded="false"
>
<span class="sr-only">메뉴</span>
<span
aria-hidden="true"
class="absolute h-px w-5 -translate-y-1.5 bg-foreground"
></span>
<span
aria-hidden="true"
class="absolute h-px w-5 bg-foreground"></span>
<span
aria-hidden="true"
class="absolute h-px w-5 translate-y-1.5 bg-foreground"
></span>
</button>
<nav
id="mobile-nav"
class="absolute right-0 top-[calc(100%+12px)] z-50 hidden min-w-40 flex-col gap-1 rounded-2xl border border-border bg-background p-2 shadow-[0_12px_30px_rgba(0,0,0,0.18)] md:hidden"
aria-label="모바일 메뉴"
>
{
navigationItems.map((item) => (
<a class={mobileLinkClass} href={item.href}>
{item.label}
</a>
))
}
</nav>
</div>
</header>
<script>
const menuToggle =
document.querySelector<HTMLButtonElement>("#menu-toggle");
const mobileNav = document.querySelector<HTMLElement>("#mobile-nav");
const navigation = document.querySelector<HTMLElement>("#navigation");
if (menuToggle && mobileNav && navigation) {
const setMenuOpen = (isOpen: boolean) => {
mobileNav.classList.toggle("hidden", !isOpen);
mobileNav.classList.toggle("flex", isOpen);
menuToggle.setAttribute("aria-expanded", String(isOpen));
menuToggle.setAttribute(
"aria-label",
isOpen ? "메뉴 닫기" : "메뉴 열기",
);
};
menuToggle.addEventListener("click", () => {
setMenuOpen(menuToggle.getAttribute("aria-expanded") !== "true");
});
mobileNav.addEventListener("click", (event) => {
if (event.target instanceof HTMLAnchorElement) setMenuOpen(false);
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") setMenuOpen(false);
});
document.addEventListener("click", (event) => {
if (event.target instanceof Node && !navigation.contains(event.target)) {
setMenuOpen(false);
}
});
}
</script>

View file

@ -1,95 +0,0 @@
<div
id="home"
data-node-id="1:3"
data-name="imnyang"
class="flex h-[calc(100svh-64px)] min-h-0 snap-start flex-col overflow-hidden"
>
<section
class="flex h-[250px] min-h-[250px] min-w-0 flex-none basis-[250px] items-center overflow-clip px-[clamp(26px,2.5vw,48px)] max-md:px-6"
aria-labelledby="hero-title"
data-node-id="43:24"
>
<div class="w-full min-w-0" data-node-id="43:23">
<h1
id="hero-title"
class="m-0 flex h-[250px] w-full max-w-full flex-col justify-center break-words whitespace-nowrap text-[clamp(34px,3.333333vw,64px)] font-bold leading-[normal] tracking-[0] max-md:whitespace-normal max-md:text-[clamp(24px,8vw,48px)] max-md:leading-[1.12]"
>
<span class="block" data-node-id="43:14">
<span class="font-bold">항상 꿈꾸던 것</span><span
class="font-normal text-foreground/50">들을</span
>
</span>
<span class="block" data-node-id="43:16">
<span class="font-bold">현실</span><span
class="font-normal text-foreground/50"
>{"로 만들어나가는 "}
</span><br class="hidden max-md:block md:hidden" /><span
class="font-bold"
>
암냥</span
><span class="font-normal text-foreground/50">입니다.</span>
</span>
</h1>
</div>
</section>
<section
class="min-h-0 w-full min-w-0 flex-1 basis-0 px-[clamp(26px,2.5vw,48px)] max-md:px-6"
data-node-id="44:41"
>
<div
class="relative isolate h-full min-h-0 w-full overflow-hidden rounded-tl-[clamp(10px,0.833333vw,16px)] rounded-tr-[clamp(10px,0.833333vw,16px)]"
data-node-id="42:10"
>
<picture class="contents">
<source
id="hero-theme-source"
media="(prefers-color-scheme: dark)"
srcset="/hero-dark.avif"
type="image/png"
/>
<img
class="block h-full w-full object-cover object-center transition-[scale,border-radius,box-shadow] duration-500 ease-[var(--ease-out-expo)] hover:z-10 hover:scale-105 hover:rounded-lg hover:shadow-[0_15px_45px_#0006] motion-reduce:transition-none"
src="/hero-light.avif"
alt="벚꽃이 핀 수로에서 보트를 타고 있는 암냥"
width="3840"
height="2160"
fetchpriority="high"
/>
</picture>
<div
aria-hidden="true"
class="pointer-events-none absolute inset-x-0 bottom-0 z-20 h-[min(150px,35%)] bg-gradient-to-b from-transparent via-background/20 to-background backdrop-blur-[2px] [mask-image:linear-gradient(to_bottom,transparent,black_42%)]"
>
</div>
</div>
</section>
</div>
<script>
const heroThemeSource =
document.querySelector<HTMLSourceElement>("#hero-theme-source");
if (heroThemeSource) {
const syncHeroTheme = () => {
const root = document.documentElement;
if (root.classList.contains("dark")) {
heroThemeSource.media = "all";
heroThemeSource.srcset = "/hero-dark.avif";
} else if (root.classList.contains("light")) {
heroThemeSource.media = "all";
heroThemeSource.srcset = "/hero-light.avif";
} else {
heroThemeSource.media = "(prefers-color-scheme: dark)";
heroThemeSource.srcset = "/hero-dark.avif";
}
};
syncHeroTheme();
new MutationObserver(syncHeroTheme).observe(document.documentElement, {
attributes: true,
attributeFilter: ["class"],
});
}
</script>

View file

@ -1,116 +0,0 @@
@import "@sun-typeface/suit/fonts/variable/woff2/SUIT-Variable.css";
@import "tailwindcss";
@custom-variant dark (&:is(.dark *));
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-border: var(--border);
--color-ring: var(--ring);
--font-sans: "SUIT Variable", "SUIT", system-ui, sans-serif;
--radius-sm: calc(var(--radius) * 0.6);
--radius-md: calc(var(--radius) * 0.8);
--radius-lg: var(--radius);
}
:root {
color-scheme: light;
--light-background: hsl(340 40% 98%);
--light-foreground: hsl(315 21% 8%);
--light-muted: hsl(340 20% 95%);
--light-muted-foreground: hsl(340 10% 60%);
--light-border: hsl(340 25% 90%);
--light-ring: hsl(315 21% 8%);
--dark-background: hsl(315 21% 8%);
--dark-foreground: hsl(0 0% 98%);
--dark-muted: hsl(296 18% 15%);
--dark-muted-foreground: hsl(240 5% 68%);
--dark-border: hsl(296 18% 15%);
--dark-ring: hsl(240 4.9% 83.9%);
--background: var(--light-background);
--foreground: var(--light-foreground);
--muted: var(--light-muted);
--muted-foreground: var(--light-muted-foreground);
--border: var(--light-border);
--ring: var(--light-ring);
--radius: 0.625rem;
--scrollbar: hsla(340 10% 60% / 0.5);
--scrollbar-hover: hsla(340 10% 60% / 0.8);
--mono-filter: none;
}
.dark {
color-scheme: dark;
--background: var(--dark-background);
--foreground: var(--dark-foreground);
--muted: var(--dark-muted);
--muted-foreground: var(--dark-muted-foreground);
--border: var(--dark-border);
--ring: var(--dark-ring);
--mono-filter: invert(1);
}
.light {
color-scheme: light;
--background: var(--light-background);
--foreground: var(--light-foreground);
--muted: var(--light-muted);
--muted-foreground: var(--light-muted-foreground);
--border: var(--light-border);
--ring: var(--light-ring);
--mono-filter: none;
}
@media (prefers-color-scheme: dark) {
:root:not(.light) {
color-scheme: dark;
--background: var(--dark-background);
--foreground: var(--dark-foreground);
--muted: var(--dark-muted);
--muted-foreground: var(--dark-muted-foreground);
--border: var(--dark-border);
--ring: var(--dark-ring);
--mono-filter: invert(1);
}
}
html {
scroll-behavior: smooth;
scroll-padding-top: 64px;
}
html::-webkit-scrollbar {
width: 19px;
height: 11px;
}
html::-webkit-scrollbar-track {
background: transparent;
}
html::-webkit-scrollbar-thumb {
background: var(--scrollbar);
border: 5px solid var(--background);
border-radius: 16px;
}
html::-webkit-scrollbar-thumb:hover {
background: var(--scrollbar-hover);
}
html {
scrollbar-color: var(--scrollbar) var(--background);
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}

View file

@ -1,163 +0,0 @@
interface Event {
description: string;
category: string;
date: string;
link?: string;
}
export const events: Event[] = [
{
description: "제 2회 SSD CTF - 최다 풀이자 SSD상 수상",
category: "Award",
date: "2026-08-30",
link: "https://forge.hspace.io/competitions/6a8b93c72586e8e70978b4df",
},
{
description:
"33회 해킹캠프 발표 - LLM에 로그인했더니 내 계정이 아니게 됐다???",
category: "Presentation",
date: "2026-08-22",
},
{
description: "2026 사이버 가디언즈 CMX 대회 장려상 수상",
category: "Award",
date: "2026-08-18",
},
{
description: "선린인터넷고등학교 전공동아리 Layer7 26기 입부",
category: "Education",
date: "2026-04-01",
},
{
description: "선린인터넷고등학교 121기 입학",
category: "Education",
date: "2026-03-03",
},
{
description: "리눅스 마스터 2급",
category: "License",
date: "2026-01-02",
},
{
description: "화이트햇스쿨 3기 이수",
category: "Education",
date: "2025-09-24",
link: "https://whitehatschool.kr/home/kor/main.do",
},
{
date: "2025-09-13",
description: "선린인터넷고 소프트웨어 나눔축제 AnA 이수",
category: "Education",
link: "https://ssf.sunrin.io/",
},
{
date: "2025-07-26",
description: "선린인터넷고 여름방학 중학생 특별교육 우수 이수 (프로그래밍)",
category: "Education",
link: "https://sunrint.sen.hs.kr/",
},
{
date: "2025-01-19",
description: "2025 Sunrin LOGCON(TeamLog 주최) 중등부 3위",
category: "Award",
link: "https://teamlog.kr",
},
{
date: "2025-01-12",
description: "2024 Sunrin Layer7 CTF 중등부 2위",
category: "Award",
link: "https://layer7.kr",
},
{
date: "2025-01-10",
description: "선린인터넷고 겨울방학 중학생 특별교육 이수 (IT경영학과)",
category: "Education",
link: "https://sunrint.sen.hs.kr/",
},
{
date: "2024-12-14",
description:
"2024 글로벌스타트업학교 K-청소년스타트업 경진대회 우수상 수상",
category: "Award",
link: "https://www.ncf.or.kr/projects/'2024-%EA%B8%80%EB%A1%9C%EB%B2%8C%EC%8A%A4%ED%83%80%ED%8A%B8%EC%97%85%ED%95%99%EA%B5%90-k-%EC%B2%AD%EC%86%8C%EB%85%84%EC%8A%A4%ED%83%80%ED%8A%B8%EC%97%85-%EA%B2%BD%EC%A7%84%EB%8C%80%ED%9A%8C'-%EC%B0%B8%EA%B0%80%EC%9E%90-%EB%AA%A8%EC%A7%91",
},
{
date: "2024-12-07",
description: "글로벌 스타트업 학교 팀 1위",
category: "Award",
link: "https://ncf.or.kr",
},
{
date: "2024-12-07",
description: "글로벌 스타트업 학교 개인 최우수상",
category: "Award",
link: "https://ncf.or.kr",
},
{
date: "2024-08-18",
description: "29회 해킹캠프 CTF 1위 (고민중독)",
category: "Award & Conference",
link: "https://ctf.hackingcamp.org/",
},
{
date: "2024-08-01",
description:
"글로벌 스타트업 학교 2기 베트남 해외 연수 데모데이 대상 (1위)",
category: "Award",
link: "http://ncf.or.kr",
},
{
date: "2024-05-16",
description: "글로벌 스타트업 학교 2기 합격",
category: "Education",
link: "http://ncf.or.kr",
},
{
date: "2024-05-11",
description: "LG AI 청소년 캠프 1기 LG 탐색상 수상",
category: "Award",
link: "https://lgaiyouthcamp.or.kr/",
},
{
date: "2024-05-11",
description: "LG AI 청소년 캠프 1기 수료",
category: "Award & Education",
link: "https://lgaiyouthcamp.or.kr/",
},
{
date: "2023-11-14",
description: "인천상정중학교 2023학년도 SW 문제 해결 활동 우수상(2위) 수여",
category: "Award",
},
{
date: "2023-09-02",
description:
"선린인터넷고등학교 제6회 소프트웨어나눔축제 Layer7 부서 과정 이수",
category: "Education",
},
{
date: "2023-07-24",
description: "한국정보기술연구원이 주도하는 사이버 가디언즈 보안캠프 수료",
category: "Education",
},
{
date: "2023-05-15",
description: "한국 코드페어 예선 진출",
category: "Award",
},
{
date: "2022-12-20",
description: "2022 SW영재 창작대회 은상 수상",
category: "Award",
},
{
date: "2022-09-27",
description: "2022 삼성 주니어 SW 창작대회 본선 진출",
category: "Award",
},
{
date: "2022-05-23",
description: "2022학년도 석정초SW영재학급 첫 수업",
category: "Education",
},
];

View file

@ -1,86 +0,0 @@
---
import About from "@/components/About.astro";
import ContactSection from "@/components/ContactSection.astro";
import EPCProjects from "@/components/EPCProjects.astro";
import Experience from "@/components/Experience.astro";
import Header from "@/components/Header.astro";
import Hero from "@/components/Hero.astro";
import "@/globals.css";
---
<html lang="ko">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width" />
<meta name="color-scheme" content="light dark" />
<meta
name="theme-color"
media="(prefers-color-scheme: light)"
content="#fcf8f9"
/>
<meta
name="theme-color"
media="(prefers-color-scheme: dark)"
content="#191014"
/>
<title>암냥 | imnya.ng</title>
<meta
name="description"
content="항상 꿈꾸던 것들을 현실로 만들어나가기 위해..."
/>
</head>
<body
class="m-0 min-w-[320px] overflow-hidden bg-background font-sans text-foreground transition-colors duration-300"
>
<Header />
<main
class="mt-[64px] h-[calc(100svh-64px)] snap-y snap-proximity overflow-x-hidden overflow-y-auto scroll-smooth overscroll-y-contain bg-background transition-colors duration-300 [&::-webkit-scrollbar]:h-[11px] [&::-webkit-scrollbar]:w-[19px] [&::-webkit-scrollbar-thumb]:rounded-2xl [&::-webkit-scrollbar-thumb]:border-[5px] [&::-webkit-scrollbar-thumb]:border-background [&::-webkit-scrollbar-thumb]:bg-[var(--scrollbar)] [&::-webkit-scrollbar-thumb:hover]:bg-[var(--scrollbar-hover)] [&::-webkit-scrollbar-track]:bg-transparent"
>
<Hero />
<About />
<EPCProjects />
<Experience />
<ContactSection />
</main>
</body>
</html>
<script>
const scrollContainer = document.querySelector<HTMLElement>("main");
const inPageLinks =
document.querySelectorAll<HTMLAnchorElement>('a[href^="#"]');
const getTargetScrollTop = (target: HTMLElement) =>
target.offsetTop - (scrollContainer?.offsetTop ?? 0);
if (scrollContainer && window.location.hash) {
requestAnimationFrame(() => {
const initialTarget = document.querySelector<HTMLElement>(
window.location.hash,
);
if (initialTarget) {
scrollContainer.scrollTop = getTargetScrollTop(initialTarget);
}
});
}
inPageLinks.forEach((link) => {
link.addEventListener("click", (event) => {
const hash = link.getAttribute("href");
const target = hash
? document.querySelector<HTMLElement>(hash)
: null;
if (!scrollContainer || !target) return;
event.preventDefault();
scrollContainer.scrollTo({
top: getTargetScrollTop(target),
behavior: "smooth",
});
history.pushState(null, "", hash);
});
});
</script>

38
tailwind.config.ts Normal file
View file

@ -0,0 +1,38 @@
import type { Config } from "tailwindcss";
export default {
content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {
fontFamily: {
sans: [
'"Inter"',
"ui-sans-serif",
"system-ui",
"sans-serif",
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
'"Noto Color Emoji"',
],
},
animation: {
flip: "flip 6s infinite steps(2, end)",
rotate: "rotate 3s linear infinite both",
},
keyframes: {
flip: {
to: {
transform: "rotate(360deg)",
},
},
rotate: {
to: {
transform: "rotate(90deg)",
},
},
},
},
},
plugins: [],
} satisfies Config;

View file

@ -1,11 +1,27 @@
{ {
"extends": "astro/tsconfigs/strict", "include": [
"compilerOptions": { "**/*",
"baseUrl": ".", "**/.server/**/*",
"paths": { "**/.client/**/*",
"@/*": ["./src/*"] ".react-router/types/**/*"
} ],
}, "compilerOptions": {
"include": [".astro/types.d.ts", "**/*"], "lib": ["DOM", "DOM.Iterable", "ES2022"],
"exclude": ["dist"] "types": ["node", "vite/client"],
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"rootDirs": [".", "./.react-router/types"],
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true
}
} }

14
vite.config.ts Normal file
View file

@ -0,0 +1,14 @@
import { reactRouter } from "@react-router/dev/vite";
import autoprefixer from "autoprefixer";
import tailwindcss from "tailwindcss";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
css: {
postcss: {
plugins: [tailwindcss, autoprefixer],
},
},
plugins: [reactRouter(), tsconfigPaths()],
});