commit 6c6218ef3662a806744c76409407600fa91ce1d6
Author: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com>
Date: Tue Aug 18 18:33:49 2026 -0700
(chore) init commit and add tasks
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..d065a06
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,23 @@
+{
+ "parser": "@typescript-eslint/parser",
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/recommended"
+ ],
+ "plugins": ["@typescript-eslint"],
+ "env": {
+ "browser": true,
+ "es2021": true,
+ "node": true
+ },
+ "parserOptions": {
+ "ecmaVersion": "latest",
+ "sourceType": "module",
+ "jsx": true
+ },
+ "ignorePatterns": ["tsconfig.json", ".next", "node_modules"],
+ "rules": {
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/triple-slash-reference": "off"
+ }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..425ab4f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.next/
+*.log
+.DS_Store
+.env
+.env.local
+.env.*.local
+.claude
\ No newline at end of file
diff --git a/IMPLEMENTATION.md b/IMPLEMENTATION.md
new file mode 100644
index 0000000..2d89087
--- /dev/null
+++ b/IMPLEMENTATION.md
@@ -0,0 +1,1348 @@
+# Implementation: Homarr + Portfolio via Terraform
+
+## Phase 1: Portfolio Site (Local Dev)
+
+### 1.1 Initialize Next.js project
+
+```bash
+cd ~/workplace/riotpiao
+npm init -y
+npm install next@15 react@19 react-dom@19 typescript tailwindcss postcss autoprefixer
+npx tailwindcss init -p
+npx tsc --init
+```
+
+**`tsconfig.json`:**
+```json
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "jsx": "react-jsx",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./*"]
+ }
+ },
+ "include": ["**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules", ".next"]
+}
+```
+
+**`next.config.js`:**
+```javascript
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ output: 'standalone',
+ reactStrictMode: true,
+};
+
+module.exports = nextConfig;
+```
+
+**`package.json` (key fields):**
+```json
+{
+ "name": "riotpiao-portfolio",
+ "version": "1.0.0",
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "eslint ."
+ }
+}
+```
+
+### 1.2 App Router structure
+
+**`app/layout.tsx`:**
+```typescript
+import "@/styles/globals.css";
+import Header from "@/components/Header";
+import Footer from "@/components/Footer";
+
+export const metadata = {
+ title: "Rock Liang — Portfolio & Demos",
+ description: "Software engineer showcasing live demos and open-source projects.",
+ openGraph: {
+ title: "Rock Liang",
+ description: "Portfolio and interactive demo platform",
+ url: "https://portfolio.riotpiao.homelab.com",
+ images: [
+ {
+ url: "https://portfolio.riotpiao.homelab.com/og-image.png",
+ width: 1200,
+ height: 630,
+ },
+ ],
+ },
+};
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+
+ {children}
+
+
+
+ );
+}
+```
+
+**`app/page.tsx` (landing):**
+```typescript
+import { projects } from "@/content/projects";
+import ProjectCard from "@/components/ProjectCard";
+
+export default function HomePage() {
+ return (
+ <>
+
+
+
Rock Liang
+
+ Software Engineer • Building scalable systems • Live demos & open source
+
+
+
+
+
+
+ Projects & Demos
+
+ {projects.map(project => (
+
+ ))}
+
+
+ >
+ );
+}
+```
+
+**`app/about/page.tsx`:**
+```typescript
+import { experience, skills } from "@/content/experience";
+
+export default function AboutPage() {
+ return (
+
+
About Rock Liang
+
+
+
+ I'm a software engineer focused on building scalable, observable systems.
+ Currently exploring event-driven architecture, Kubernetes at scale, and developer
+ experience in the cloud-native ecosystem.
+
+
+
+
+ Skills
+
+ {Object.entries(skills).map(([category, items]) => (
+
+
{category.replace(/_/g, " ")}
+
+ {items.map(skill => (
+ {skill}
+ ))}
+
+
+ ))}
+
+
+
+
+ Experience
+
+ {experience.map((role, idx) => (
+
+
{role.role}
+
{role.company} • {role.period}
+
+ {role.highlights.map((h, i) => (
+ • {h}
+ ))}
+
+
+ ))}
+
+
+
+ );
+}
+```
+
+### 1.3 Components
+
+**`components/Header.tsx`:**
+```typescript
+export default function Header() {
+ return (
+
+ );
+}
+```
+
+**`components/Footer.tsx`:**
+```typescript
+export default function Footer() {
+ return (
+
+ );
+}
+```
+
+**`components/ProjectCard.tsx`:**
+```typescript
+import { Project } from "@/content/projects";
+
+export default function ProjectCard({ project }: { project: Project }) {
+ return (
+
+
{project.title}
+
{project.description}
+
+
+ {project.tags.map(tag => (
+
+ {tag}
+
+ ))}
+
+
+
+
+ GitHub
+
+
+ {project.demoStatus === "live" && project.demoUrl ? (
+
+ Live Demo
+
+ ) : (
+
+ Coming Soon
+
+ )}
+
+
+ );
+}
+```
+
+### 1.4 Content
+
+**`content/projects.ts`:**
+```typescript
+export interface Project {
+ slug: string;
+ title: string;
+ description: string;
+ tags: string[];
+ githubUrl: string;
+ demoUrl?: string;
+ demoStatus: "live" | "coming-soon";
+}
+
+export const projects: Project[] = [
+ {
+ slug: "rest-api-demo",
+ title: "REST API Demo",
+ description: "Go-based REST API with OpenAPI docs and rate limiting.",
+ tags: ["REST API", "Go", "Docker", "Kubernetes"],
+ githubUrl: "https://github.com/riotpiaole/rest-api-demo",
+ demoStatus: "coming-soon",
+ },
+ {
+ slug: "auth-demo",
+ title: "Auth System Demo",
+ description: "OIDC/OAuth2 flow with Authentik integration.",
+ tags: ["Auth", "OIDC", "Authentik", "Go"],
+ githubUrl: "https://github.com/riotpiaole/auth-demo",
+ demoStatus: "coming-soon",
+ },
+ {
+ slug: "monitoring-stack",
+ title: "Monitoring Stack Demo",
+ description: "Prometheus + Grafana + Loki in a sandbox environment.",
+ tags: ["Monitoring", "Prometheus", "Grafana", "Observability"],
+ githubUrl: "https://github.com/riotpiaole/monitoring-demo",
+ demoStatus: "coming-soon",
+ },
+];
+```
+
+**`content/experience.ts`:**
+```typescript
+export const skills = {
+ languages: ["Go", "TypeScript", "Rust"],
+ infrastructure: ["Kubernetes", "Talos", "Helm", "Terraform"],
+ observability: ["Prometheus", "Grafana", "Loki", "Temporal"],
+ architecture: ["Event-Driven", "Microservices", "OIDC/Security"],
+};
+
+export const experience = [
+ {
+ role: "Infrastructure Engineer",
+ company: "Personal Homelab",
+ period: "2024–Present",
+ highlights: [
+ "Designed and deployed a 3-node bare-metal Kubernetes cluster (Talos)",
+ "Integrated Authentik OIDC, Vault, and event-driven patterns",
+ "Built demo platform for skill showcase (this site)",
+ ],
+ },
+];
+```
+
+**`styles/globals.css`:**
+```css
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+}
+
+.prose h1,
+.prose h2,
+.prose h3 {
+ @apply font-bold;
+}
+```
+
+### 1.5 Build & test locally
+
+```bash
+cd ~/workplace/riotpiao
+npm run build
+npm run start
+# Open http://localhost:3000 — verify landing + about pages render
+```
+
+---
+
+## Phase 2: Docker Image
+
+**`Dockerfile` (multi-stage):**
+```dockerfile
+FROM node:20-alpine AS builder
+WORKDIR /app
+COPY package*.json ./
+RUN npm ci
+COPY . .
+RUN npm run build
+
+FROM node:20-alpine
+WORKDIR /app
+RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
+
+COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
+COPY --from=builder --chown=nextjs:nodejs /app/public ./public
+COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
+
+USER nextjs
+EXPOSE 3000
+ENV NEXT_TELEMETRY_DISABLED=1
+
+CMD ["node", "server.js"]
+```
+
+**`.dockerignore`:**
+```
+.git
+.gitignore
+.next
+node_modules
+npm-debug.log
+README.md
+.env*
+.DS_Store
+```
+
+**`build.sh`:**
+```bash
+#!/bin/bash
+set -euo pipefail
+
+REGISTRY="forgejo.riotpiao.homelab.com"
+IMAGE_NAME="rock/portfolio"
+FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:latest"
+
+echo "Building image: ${FULL_IMAGE}"
+docker buildx build --platform linux/amd64 -t "${FULL_IMAGE}" -f Dockerfile .
+
+echo "Authenticating to Forgejo..."
+# Get token (adjust based on your secret storage)
+REGISTRY_TOKEN=$(cat ~/.docker/config.json | jq -r '.auths."forgejo.riotpiao.homelab.com".auth' | base64 -d | cut -d: -f2)
+echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" -u ci-bot --password-stdin
+
+echo "Pushing image..."
+docker push "${FULL_IMAGE}"
+
+echo "✓ Complete: ${FULL_IMAGE}"
+```
+
+```bash
+chmod +x build.sh
+./build.sh
+docker run -p 3000:3000 forgejo.riotpiao.homelab.com/rock/portfolio:latest
+# Verify http://localhost:3000 works
+```
+
+---
+
+## Phase 3: Helm Chart (for Kubernetes)
+
+**`k8s/portfolio/Chart.yaml` (in homelab repo):**
+```yaml
+apiVersion: v2
+name: portfolio
+description: Rock Liang personal portfolio site
+type: application
+version: 1.0.0
+appVersion: "1.0"
+```
+
+**`k8s/portfolio/values.yaml`:**
+```yaml
+replicaCount: 2
+
+image:
+ repository: forgejo.riotpiao.homelab.com/rock/portfolio
+ pullPolicy: IfNotPresent
+ tag: latest
+
+service:
+ type: ClusterIP
+ port: 3000
+
+resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+
+nodeSelector: {}
+tolerations: []
+affinity: {}
+```
+
+**`k8s/portfolio/templates/deployment.yaml`:**
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "portfolio.fullname" . }}
+ labels:
+ {{ include "portfolio.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{ include "portfolio.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ labels:
+ {{ include "portfolio.selectorLabels" . | nindent 8 }}
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: 3000
+ protocol: TCP
+ livenessProbe:
+ httpGet:
+ path: /
+ port: http
+ initialDelaySeconds: 10
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /
+ port: http
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ resources:
+ {{ toYaml .Values.resources | nindent 10 }}
+```
+
+**`k8s/portfolio/templates/service.yaml`:**
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "portfolio.fullname" . }}
+ labels:
+ {{ include "portfolio.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ {{ include "portfolio.selectorLabels" . | nindent 4 }}
+```
+
+**`k8s/portfolio/templates/_helpers.tpl`:**
+```
+{{- define "portfolio.fullname" -}}
+{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{- define "portfolio.labels" -}}
+helm.sh/chart: {{ include "portfolio.chart" . }}
+{{ include "portfolio.selectorLabels" . }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{- define "portfolio.selectorLabels" -}}
+app.kubernetes.io/name: {{ .Chart.Name }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{- define "portfolio.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+```
+
+---
+
+## Phase 4: Terraform Infrastructure
+
+Create in homelab repo (or new `homelab-terraform/` directory). Authentik already running at `iam` namespace — just consume it.
+
+**`main.tf`:**
+```hcl
+terraform {
+ required_providers {
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = "~> 2.25"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ version = "~> 2.12"
+ }
+ }
+
+ backend "local" {
+ path = "terraform.tfstate"
+ }
+}
+
+provider "kubernetes" {
+ host = var.cluster_endpoint
+ cluster_ca_certificate = base64decode(var.cluster_ca_cert)
+ token = var.cluster_token
+}
+
+provider "helm" {
+ kubernetes {
+ host = var.cluster_endpoint
+ cluster_ca_certificate = base64decode(var.cluster_ca_cert)
+ token = var.cluster_token
+ }
+}
+
+module "portfolio" {
+ source = "./modules/portfolio"
+
+ portfolio_image_repo = var.portfolio_image_repo
+ portfolio_image_tag = var.portfolio_image_tag
+ domain = var.domain
+}
+
+module "homarr" {
+ source = "./modules/homarr"
+
+ homarr_version = var.homarr_version
+ homarr_oidc_client_secret = var.homarr_oidc_client_secret
+ domain = var.domain
+}
+
+module "ingress_protected" {
+ source = "./modules/ingress"
+
+ protected_services = var.protected_services
+ domain = var.domain
+}
+
+module "network_policy" {
+ source = "./modules/network-policy"
+
+ isolated_services = var.isolated_services
+}
+```
+
+**`variables.tf`:**
+```hcl
+variable "cluster_endpoint" {
+ type = string
+ description = "Kubernetes API server endpoint"
+}
+
+variable "cluster_ca_cert" {
+ type = string
+ sensitive = true
+ description = "Cluster CA certificate (base64 encoded)"
+}
+
+variable "cluster_token" {
+ type = string
+ sensitive = true
+ description = "Kubernetes API token"
+}
+
+variable "domain" {
+ type = string
+ default = "riotpiao.homelab.com"
+ description = "Base domain for all services"
+}
+
+variable "portfolio_image_repo" {
+ type = string
+ default = "forgejo.riotpiao.homelab.com/rock/portfolio"
+ description = "Portfolio image repository"
+}
+
+variable "portfolio_image_tag" {
+ type = string
+ default = "latest"
+ description = "Portfolio image tag"
+}
+
+variable "homarr_version" {
+ type = string
+ default = "~1"
+ description = "Homarr Helm chart version"
+}
+
+variable "homarr_oidc_client_secret" {
+ type = string
+ sensitive = true
+ description = "Homarr OIDC client secret from Authentik"
+}
+
+variable "protected_services" {
+ type = map(object({
+ host = string
+ namespace = string
+ service_name = string
+ service_port = number
+ }))
+
+ default = {
+ longhorn = {
+ host = "longhorn.riotpiao.homelab.com"
+ namespace = "longhorn-system"
+ service_name = "longhorn-frontend"
+ service_port = 80
+ }
+ portainer = {
+ host = "portainer.riotpiao.homelab.com"
+ namespace = "dashboard"
+ service_name = "portainer"
+ service_port = 9000
+ }
+ prometheus = {
+ host = "prometheus.riotpiao.homelab.com"
+ namespace = "monitoring"
+ service_name = "prometheus-operated"
+ service_port = 9090
+ }
+ }
+}
+
+variable "isolated_services" {
+ type = map(object({
+ namespace = string
+ pod_selector = map(string)
+ }))
+
+ default = {
+ longhorn = {
+ namespace = "longhorn-system"
+ pod_selector = {
+ "app.kubernetes.io/name" = "longhorn"
+ }
+ }
+ portainer = {
+ namespace = "dashboard"
+ pod_selector = {
+ app = "portainer"
+ }
+ }
+ prometheus = {
+ namespace = "monitoring"
+ pod_selector = {
+ "app.kubernetes.io/name" = "prometheus"
+ }
+ }
+ }
+}
+```
+
+**`outputs.tf`:**
+```hcl
+output "portfolio_url" {
+ value = "https://portfolio.${var.domain}"
+}
+
+output "homarr_url" {
+ value = "https://homarr.${var.domain}"
+}
+
+output "protected_services" {
+ value = {
+ for name, config in var.protected_services :
+ name => "https://${config.host}"
+ }
+}
+```
+
+### 4.1 Portfolio module
+
+**`modules/portfolio/main.tf`:**
+```hcl
+resource "kubernetes_namespace" "portfolio" {
+ metadata {
+ name = "portfolio"
+ labels = {
+ "managed_by" = "terraform"
+ }
+ }
+}
+
+resource "helm_release" "portfolio" {
+ name = "portfolio"
+ namespace = kubernetes_namespace.portfolio.metadata[0].name
+ chart = var.chart_path != null ? var.chart_path : "${path.root}/k8s/portfolio"
+ create_namespace = false
+
+ set {
+ name = "image.repository"
+ value = var.portfolio_image_repo
+ }
+
+ set {
+ name = "image.tag"
+ value = var.portfolio_image_tag
+ }
+
+ set {
+ name = "replicaCount"
+ value = 2
+ }
+
+ depends_on = [kubernetes_namespace.portfolio]
+}
+
+resource "kubernetes_ingress_v1" "portfolio" {
+ metadata {
+ name = "portfolio"
+ namespace = kubernetes_namespace.portfolio.metadata[0].name
+ annotations = {
+ "cert-manager.io/cluster-issuer" = "letsencrypt-prod"
+ }
+ }
+
+ spec {
+ ingress_class_name = "nginx"
+ tls {
+ hosts = ["portfolio.${var.domain}"]
+ secret_name = "portfolio-tls"
+ }
+ rule {
+ host = "portfolio.${var.domain}"
+ http {
+ path {
+ path = "/"
+ path_type = "Prefix"
+ backend {
+ service {
+ name = "portfolio-portfolio"
+ port {
+ number = 3000
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ depends_on = [helm_release.portfolio]
+}
+```
+
+**`modules/portfolio/variables.tf`:**
+```hcl
+variable "portfolio_image_repo" {
+ type = string
+}
+
+variable "portfolio_image_tag" {
+ type = string
+}
+
+variable "domain" {
+ type = string
+}
+
+variable "chart_path" {
+ type = string
+ default = null
+ description = "Path to Helm chart (null = use k8s/portfolio relative to repo root)"
+}
+```
+
+**`modules/portfolio/outputs.tf`:**
+```hcl
+output "namespace" {
+ value = kubernetes_namespace.portfolio.metadata[0].name
+}
+
+output "service_url" {
+ value = "https://portfolio.${var.domain}"
+}
+```
+
+### 4.2 Homarr module
+
+**`modules/homarr/main.tf`:**
+```hcl
+resource "kubernetes_namespace" "homarr" {
+ metadata {
+ name = "dashboard"
+ labels = {
+ "managed_by" = "terraform"
+ "reloader" = "enabled"
+ }
+ }
+}
+
+resource "kubernetes_secret" "homarr_oidc" {
+ metadata {
+ name = "homarr-oidc"
+ namespace = kubernetes_namespace.homarr.metadata[0].name
+ }
+
+ data = {
+ AUTH_OIDC_CLIENT_SECRET = var.homarr_oidc_client_secret
+ }
+
+ type = "Opaque"
+}
+
+resource "helm_release" "homarr" {
+ name = "homarr"
+ namespace = kubernetes_namespace.homarr.metadata[0].name
+ chart = "homarr"
+ repository = "https://homarr-labs.github.io/charts/"
+ version = var.homarr_version
+
+ set {
+ name = "env.AUTH_PROVIDERS"
+ value = "oidc"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_CLIENT_ID"
+ value = "homarr"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_ISSUER"
+ value = "https://authentik.${var.domain}/application/o/homarr/"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_URI"
+ value = "https://authentik.${var.domain}/application/o/homarr/.well-known/openid-configuration"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_GROUPS_ATTRIBUTE"
+ value = "groups"
+ }
+
+ set {
+ name = "envFrom[0].secretRef.name"
+ value = kubernetes_secret.homarr_oidc.metadata[0].name
+ }
+
+ set {
+ name = "persistence.enabled"
+ value = "true"
+ }
+
+ set {
+ name = "persistence.storageClass"
+ value = "longhorn"
+ }
+
+ set {
+ name = "persistence.size"
+ value = "2Gi"
+ }
+
+ depends_on = [kubernetes_secret.homarr_oidc]
+}
+
+resource "kubernetes_ingress_v1" "homarr" {
+ metadata {
+ name = "homarr"
+ namespace = kubernetes_namespace.homarr.metadata[0].name
+ annotations = {
+ "cert-manager.io/cluster-issuer" = "letsencrypt-prod"
+ }
+ }
+
+ spec {
+ ingress_class_name = "nginx"
+ tls {
+ hosts = ["homarr.${var.domain}"]
+ secret_name = "homarr-tls"
+ }
+ rule {
+ host = "homarr.${var.domain}"
+ http {
+ path {
+ path = "/"
+ path_type = "Prefix"
+ backend {
+ service {
+ name = helm_release.homarr.name
+ port {
+ number = 3000
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ depends_on = [helm_release.homarr]
+}
+```
+
+**`modules/homarr/variables.tf`:**
+```hcl
+variable "homarr_version" {
+ type = string
+}
+
+variable "homarr_oidc_client_secret" {
+ type = string
+ sensitive = true
+}
+
+variable "domain" {
+ type = string
+}
+```
+
+**`modules/homarr/outputs.tf`:**
+```hcl
+output "namespace" {
+ value = kubernetes_namespace.homarr.metadata[0].name
+}
+
+output "service_url" {
+ value = "https://homarr.${var.domain}"
+}
+```
+
+### 4.3 Ingress module
+
+**`modules/ingress/main.tf`:**
+```hcl
+resource "kubernetes_ingress_v1" "protected" {
+ for_each = var.protected_services
+
+ metadata {
+ name = each.key
+ namespace = each.value.namespace
+ annotations = {
+ "nginx.ingress.kubernetes.io/auth-url" = "http://authentik-server.iam.svc.cluster.local/outpost.goauthentik.io/auth/nginx"
+ "nginx.ingress.kubernetes.io/auth-signin" = "https://authentik.${var.domain}/outpost.goauthentik.io/start?rd=$scheme://$http_host$escaped_request_uri"
+ "nginx.ingress.kubernetes.io/auth-response-headers" = "Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid"
+ "cert-manager.io/cluster-issuer" = "letsencrypt-prod"
+ }
+ }
+
+ spec {
+ ingress_class_name = "nginx"
+ tls {
+ hosts = [each.value.host]
+ secret_name = "${each.key}-tls"
+ }
+ rule {
+ host = each.value.host
+ http {
+ path {
+ path = "/"
+ path_type = "Prefix"
+ backend {
+ service {
+ name = each.value.service_name
+ port {
+ number = each.value.service_port
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+**`modules/ingress/variables.tf`:**
+```hcl
+variable "protected_services" {
+ type = map(object({
+ host = string
+ namespace = string
+ service_name = string
+ service_port = number
+ }))
+}
+
+variable "domain" {
+ type = string
+}
+```
+
+### 4.4 NetworkPolicy module
+
+**`modules/network-policy/main.tf`:**
+```hcl
+resource "kubernetes_network_policy" "backend_isolation" {
+ for_each = var.isolated_services
+
+ metadata {
+ name = "${each.key}-ingress-only"
+ namespace = each.value.namespace
+ }
+
+ spec {
+ pod_selector {
+ match_labels = each.value.pod_selector
+ }
+ policy_types = ["Ingress"]
+ ingress {
+ from {
+ namespace_selector {
+ match_labels = {
+ name = "ingress-nginx"
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+**`modules/network-policy/variables.tf`:**
+```hcl
+variable "isolated_services" {
+ type = map(object({
+ namespace = string
+ pod_selector = map(string)
+ }))
+}
+```
+
+---
+
+## Phase 5: Authentik Setup (Python)
+
+**`k8s/talos-iam/register_proxy_app.py`** (new):
+
+```python
+#!/usr/bin/env python3
+import argparse
+import json
+import os
+import requests
+from typing import Optional
+
+def _request(method: str, path: str, data: dict = None) -> dict:
+ """Helper: authenticate and make Authentik API request."""
+ base_url = os.getenv("AUTHENTIK_URL", "https://authentik.riotpiao.homelab.com")
+ token = os.getenv("AUTHENTIK_TOKEN")
+ if not token:
+ raise ValueError("AUTHENTIK_TOKEN not set")
+
+ url = f"{base_url}/api/v3/{path}"
+ headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
+
+ if method == "GET":
+ resp = requests.get(url, headers=headers)
+ elif method == "POST":
+ resp = requests.post(url, headers=headers, json=data)
+ elif method == "PATCH":
+ resp = requests.patch(url, headers=headers, json=data)
+ else:
+ raise ValueError(f"Unsupported method: {method}")
+
+ resp.raise_for_status()
+ return resp.json() if resp.content else {}
+
+def get_or_create_group(name: str) -> dict:
+ """Get or create group."""
+ resp = _request("GET", f"core/groups/?name={name}")
+ if resp["results"]:
+ return resp["results"][0]
+
+ group = _request("POST", "core/groups/", {"name": name})
+ print(f"✓ Created group: {name}")
+ return group
+
+def register_proxy_app(
+ service_name: str,
+ namespace: str,
+ external_host: str,
+ group_name: str,
+):
+ """Register Proxy Provider + Application."""
+
+ # 1. Get embedded outpost
+ outpost = _request("GET", "outposts/instances/?name=embedded")
+ if not outpost["results"]:
+ raise ValueError("Embedded outpost not found")
+ outpost_pk = outpost["results"][0]["pk"]
+ print(f"Found outpost PK: {outpost_pk}")
+
+ # 2. Create Proxy Provider
+ provider = _request("POST", "providers/proxy/", {
+ "name": service_name,
+ "mode": "forward_single",
+ "external_host": external_host,
+ })
+ print(f"✓ Created Proxy Provider: {service_name}")
+
+ # 3. Create Application
+ _request("POST", "core/applications/", {
+ "name": service_name,
+ "slug": service_name,
+ "provider": provider["pk"],
+ })
+ print(f"✓ Created Application: {service_name}")
+
+ # 4. Get/create group
+ group = get_or_create_group(group_name)
+
+ # 5. Bind group to provider
+ _request("POST", f"providers/proxy/{provider['pk']}/bind/", {
+ "group": group["pk"],
+ })
+ print(f"✓ Bound group {group_name} to provider {service_name}")
+
+ # 6. Add provider to outpost
+ outpost_data = _request("GET", f"outposts/instances/{outpost_pk}/")
+ current_providers = outpost_data.get("providers", [])
+ if provider["pk"] not in current_providers:
+ current_providers.append(provider["pk"])
+ _request("PATCH", f"outposts/instances/{outpost_pk}/", {
+ "providers": current_providers,
+ })
+ print(f"✓ Added provider to outpost")
+
+def main():
+ parser = argparse.ArgumentParser(description="Register Authentik Proxy Provider")
+ parser.add_argument("--service-name", required=True)
+ parser.add_argument("--namespace", required=True)
+ parser.add_argument("--external-host", required=True)
+ parser.add_argument("--add-group", default="infra-admins")
+
+ args = parser.parse_args()
+
+ try:
+ register_proxy_app(
+ service_name=args.service_name,
+ namespace=args.namespace,
+ external_host=args.external_host,
+ group_name=args.add_group,
+ )
+ print(f"\n✓ Proxy app registered: {args.service_name}")
+ except Exception as e:
+ print(f"✗ Error: {e}")
+ exit(1)
+
+if __name__ == "__main__":
+ main()
+```
+
+```bash
+chmod +x k8s/talos-iam/register_proxy_app.py
+
+# Set token first
+export AUTHENTIK_TOKEN="your_api_token_from_authentik"
+
+# Register protected services
+python3 k8s/talos-iam/register_proxy_app.py \
+ --service-name longhorn \
+ --namespace longhorn-system \
+ --external-host longhorn.riotpiao.homelab.com \
+ --add-group infra-admins
+
+python3 k8s/talos-iam/register_proxy_app.py \
+ --service-name portainer \
+ --namespace dashboard \
+ --external-host portainer.riotpiao.homelab.com \
+ --add-group infra-admins
+
+python3 k8s/talos-iam/register_proxy_app.py \
+ --service-name prometheus \
+ --namespace monitoring \
+ --external-host prometheus.riotpiao.homelab.com \
+ --add-group infra-admins
+```
+
+---
+
+## Phase 6: Deploy with Terraform
+
+**`terraform.tfvars.example`:**
+```hcl
+cluster_endpoint = "https://10.0.0.1:6443" # Replace
+cluster_ca_cert = "LS0tLS1CRUdJTi..." # From kubeconfig
+cluster_token = "eyJhbGc..." # Service account token
+domain = "riotpiao.homelab.com"
+portfolio_image_repo = "forgejo.riotpiao.homelab.com/rock/portfolio"
+portfolio_image_tag = "latest"
+homarr_version = "~1"
+homarr_oidc_client_secret = "from_authentik"
+```
+
+```bash
+cp terraform.tfvars.example terraform.tfvars
+# Edit with actual values
+
+terraform init
+terraform plan
+terraform apply -auto-approve
+```
+
+---
+
+## Phase 7: Verification
+
+```bash
+# Portfolio accessible, no auth
+curl -I https://portfolio.riotpiao.homelab.com
+# Expected: 200 OK
+
+# Homarr OIDC redirect
+curl -I https://homarr.riotpiao.homelab.com
+# Expected: 302 or 200 with Authentik sign-in form
+
+# Protected services redirect
+curl -I https://longhorn.riotpiao.homelab.com
+# Expected: 302 to Authentik sign-in
+
+# Check rollouts
+kubectl rollout status deploy/portfolio -n portfolio
+kubectl rollout status deploy/homarr -n dashboard
+
+# Verify NetworkPolicy
+kubectl describe networkpolicy longhorn-ingress-only -n longhorn-system
+```
+
+Browse:
+- `https://portfolio.riotpiao.homelab.com` — landing + about pages
+- `https://homarr.riotpiao.homelab.com` — OIDC login
+- After Homarr login, create boards/tiles pointing to protected services
+- Click tile → redirects to service, Authentik intercepts, login required
+
+---
+
+## Success Criteria
+
+- [ ] Portfolio site builds, runs locally
+- [ ] Docker image pushes to Forgejo registry
+- [ ] Terraform `init`, `plan`, `apply` succeed
+- [ ] Portfolio live at `https://portfolio.riotpiao.homelab.com` (no auth)
+- [ ] Homarr live at `https://homarr.riotpiao.homelab.com` (OIDC login)
+- [ ] Protected services (Longhorn/Portainer/Prometheus) require Authentik login
+- [ ] Homarr boards render, tiles link to protected services
+- [ ] All resources created by Terraform (kubectl shows labels)
diff --git a/PLAN.md b/PLAN.md
new file mode 100644
index 0000000..fc2eae3
--- /dev/null
+++ b/PLAN.md
@@ -0,0 +1,620 @@
+# Homelab Auth + Portfolio: Authentik Forward-Auth + Homarr SSO + Portfolio Site (Terraform)
+
+## Context
+
+Three services (Longhorn, Portainer, Prometheus) currently zero-auth. Goal: rebuild with Authentik forward-auth + Homarr dashboard + personal portfolio site. Infrastructure as Terraform (not Helm).
+
+Authentik bootstrap (Proxy Providers, groups) via Python helper. Homarr + Portfolio deployed as K8s manifests via Terraform modules.
+
+---
+
+## Track A — Authentik Forward-Auth (Setup via Python, Ingress via TF)
+
+Authentik cluster already running (deployed separately). Python helper script registers Proxy Providers + groups:
+
+**`k8s/talos-iam/register_proxy_app.py`** (mirrors `register_oauth_app.py`):
+- Queries embedded outpost, creates `/providers/proxy/` (mode: `forward_single`)
+- Creates `/core/applications/` entry
+- Creates/binds Authentik group
+- Patches outpost `providers` list
+
+```bash
+python3 k8s/talos-iam/register_proxy_app.py \
+ --service-name longhorn --namespace longhorn-system \
+ --external-host longhorn.riotpiao.homelab.com \
+ --add-group infra-admins
+# Repeat for portainer, prometheus
+```
+
+**Ingress wiring (Terraform):**
+
+`modules/ingress/protected-services.tf`:
+```hcl
+resource "kubernetes_ingress_v1" "protected_services" {
+ for_each = var.protected_services
+
+ metadata {
+ name = each.key
+ namespace = each.value.namespace
+ annotations = {
+ "nginx.ingress.kubernetes.io/auth-url" = "http://authentik-server.iam.svc.cluster.local/outpost.goauthentik.io/auth/nginx"
+ "nginx.ingress.kubernetes.io/auth-signin" = "https://authentik.riotpiao.homelab.com/outpost.goauthentik.io/start?rd=$scheme://$http_host$escaped_request_uri"
+ "nginx.ingress.kubernetes.io/auth-response-headers" = "Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid"
+ }
+ }
+
+ spec {
+ ingress_class_name = "nginx"
+ rule {
+ host = each.value.host
+ http {
+ path {
+ path = "/"
+ path_type = "Prefix"
+ backend {
+ service {
+ name = each.value.service_name
+ port {
+ number = each.value.service_port
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+**NetworkPolicy (per-service, Terraform):**
+
+`modules/network-policy/backend-isolation.tf`:
+```hcl
+resource "kubernetes_network_policy" "backend_only_from_ingress" {
+ for_each = var.isolated_services
+
+ metadata {
+ name = "${each.key}-deny-except-ingress"
+ namespace = each.value.namespace
+ }
+
+ spec {
+ pod_selector {
+ match_labels = each.value.pod_selector
+ }
+ policy_types = ["Ingress"]
+ ingress {
+ from {
+ namespace_selector {
+ match_labels = {
+ name = "ingress-nginx"
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+---
+
+## Track B — Homarr (Terraform Deployment)
+
+**Homarr Helm chart wrapper (Terraform):**
+
+`modules/homarr/main.tf`:
+```hcl
+resource "kubernetes_namespace" "homarr" {
+ metadata {
+ name = "dashboard"
+ labels = {
+ "managed_by" = "terraform"
+ "reloader" = "enabled"
+ }
+ }
+}
+
+resource "kubernetes_secret" "homarr_oidc" {
+ metadata {
+ name = "homarr-oidc"
+ namespace = kubernetes_namespace.homarr.metadata[0].name
+ }
+
+ data = {
+ AUTH_OIDC_CLIENT_SECRET = var.homarr_oidc_client_secret
+ }
+
+ type = "Opaque"
+}
+
+resource "helm_release" "homarr" {
+ name = "homarr"
+ namespace = kubernetes_namespace.homarr.metadata[0].name
+ chart = "homarr"
+ repository = "https://homarr-labs.github.io/charts/"
+ version = var.homarr_version
+
+ set {
+ name = "env.AUTH_PROVIDERS"
+ value = "oidc"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_CLIENT_ID"
+ value = "homarr"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_ISSUER"
+ value = "https://authentik.riotpiao.homelab.com/application/o/homarr/"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_URI"
+ value = "https://authentik.riotpiao.homelab.com/application/o/homarr/.well-known/openid-configuration"
+ }
+
+ set {
+ name = "env.AUTH_OIDC_GROUPS_ATTRIBUTE"
+ value = "groups"
+ }
+
+ set {
+ name = "envFrom[0].secretRef.name"
+ value = kubernetes_secret.homarr_oidc.metadata[0].name
+ }
+
+ set {
+ name = "persistence.enabled"
+ value = "true"
+ }
+
+ set {
+ name = "persistence.storageClass"
+ value = "longhorn"
+ }
+
+ set {
+ name = "persistence.size"
+ value = "2Gi"
+ }
+
+ depends_on = [kubernetes_secret.homarr_oidc]
+}
+```
+
+**Homarr Ingress (no auth, Homarr handles login):**
+
+`modules/homarr/ingress.tf`:
+```hcl
+resource "kubernetes_ingress_v1" "homarr" {
+ metadata {
+ name = "homarr"
+ namespace = kubernetes_namespace.homarr.metadata[0].name
+ annotations = {
+ "cert-manager.io/cluster-issuer" = "letsencrypt-prod"
+ }
+ }
+
+ spec {
+ ingress_class_name = "nginx"
+ tls {
+ hosts = ["homarr.riotpiao.homelab.com"]
+ secret_name = "homarr-tls"
+ }
+ rule {
+ host = "homarr.riotpiao.homelab.com"
+ http {
+ path {
+ path = "/"
+ path_type = "Prefix"
+ backend {
+ service {
+ name = helm_release.homarr.name
+ port {
+ number = 3000
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+**Authentik setup for Homarr (Python):**
+
+```bash
+python3 k8s/talos-iam/register_oauth_app.py \
+ --service-name homarr \
+ --namespace dashboard \
+ --redirect-uri "https://homarr.riotpiao.homelab.com/api/auth/callback/oidc" \
+ --add-group homarr-infra-admins
+```
+
+Then attach `groups` scope mapping (manual Authentik UI or separate Terraform provider if available).
+
+**Homarr board setup (manual runbook in `k8s/homarr/README.md`):**
+- Create groups: Infra (Longhorn/Portainer/Prometheus), Platform (Grafana/Vault), Workflows (Temporal/kmsvc)
+- Each tile deep-links to existing ingress
+- Restrict Infra group visibility to `infra-admins`
+
+---
+
+## Track C — Portfolio Site (Terraform Deployment)
+
+Portfolio source repo: `~/workplace/riotpiao` (Next.js, standalone output).
+
+**Portfolio Helm chart (Terraform wrapper):**
+
+`modules/portfolio/main.tf`:
+```hcl
+resource "kubernetes_namespace" "portfolio" {
+ metadata {
+ name = "portfolio"
+ labels = {
+ "managed_by" = "terraform"
+ }
+ }
+}
+
+resource "helm_release" "portfolio" {
+ name = "portfolio"
+ namespace = kubernetes_namespace.portfolio.metadata[0].name
+ chart = "./k8s/portfolio" # Local chart from homelab repo
+
+ set {
+ name = "image.repository"
+ value = var.portfolio_image_repo
+ }
+
+ set {
+ name = "image.tag"
+ value = var.portfolio_image_tag
+ }
+
+ set {
+ name = "replicaCount"
+ value = 2
+ }
+
+ set {
+ name = "resources.requests.cpu"
+ value = "100m"
+ }
+
+ set {
+ name = "resources.requests.memory"
+ value = "128Mi"
+ }
+
+ set {
+ name = "resources.limits.cpu"
+ value = "500m"
+ }
+
+ set {
+ name = "resources.limits.memory"
+ value = "512Mi"
+ }
+}
+```
+
+**Portfolio Ingress (public, no auth):**
+
+`modules/portfolio/ingress.tf`:
+```hcl
+resource "kubernetes_ingress_v1" "portfolio" {
+ metadata {
+ name = "portfolio"
+ namespace = kubernetes_namespace.portfolio.metadata[0].name
+ annotations = {
+ "cert-manager.io/cluster-issuer" = "letsencrypt-prod"
+ }
+ }
+
+ spec {
+ ingress_class_name = "nginx"
+ tls {
+ hosts = ["portfolio.riotpiao.homelab.com"]
+ secret_name = "portfolio-tls"
+ }
+ rule {
+ host = "portfolio.riotpiao.homelab.com"
+ http {
+ path {
+ path = "/"
+ path_type = "Prefix"
+ backend {
+ service {
+ name = helm_release.portfolio.name
+ port {
+ number = 3000
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+**Portfolio Helm chart structure** (local, in homelab repo):
+
+```
+k8s/portfolio/
+├── Chart.yaml
+├── values.yaml
+├── templates/
+│ ├── deployment.yaml
+│ ├── service.yaml
+│ └── _helpers.tpl
+└── README.md
+```
+
+**Build + push script** (portfolio repo):
+
+`~/workplace/riotpiao/build.sh`:
+```bash
+#!/bin/bash
+set -euo pipefail
+
+REGISTRY="forgejo.riotpiao.homelab.com"
+IMAGE="${REGISTRY}/rock/portfolio:latest"
+
+docker buildx build --platform linux/amd64 -t "${IMAGE}" .
+docker push "${IMAGE}"
+
+echo "✓ Pushed ${IMAGE}"
+```
+
+---
+
+## Terraform Structure
+
+```
+~/workplace/homelab-terraform/ (or extend existing homelab repo)
+├── main.tf # K8s provider config
+├── variables.tf # Inputs
+├── outputs.tf
+│
+├── modules/
+│ ├── ingress/
+│ │ ├── protected-services.tf # Longhorn, Portainer, Prometheus
+│ │ └── variables.tf
+│ │
+│ ├── homarr/
+│ │ ├── main.tf # Namespace, Secret, Helm release
+│ │ ├── ingress.tf # Public Homarr ingress
+│ │ └── variables.tf
+│ │
+│ ├── portfolio/
+│ │ ├── main.tf # Namespace, Helm release
+│ │ ├── ingress.tf # Public portfolio ingress
+│ │ └── variables.tf
+│ │
+│ └── network-policy/
+│ └── backend-isolation.tf # Deny ingress except nginx
+│
+├── environments/
+│ └── prod.tfvars # Domain, image repos, versions
+│
+└── .terraform.lock.hcl
+```
+
+**Main entry point:**
+
+`main.tf`:
+```hcl
+terraform {
+ required_providers {
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = "~> 2.25"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ version = "~> 2.12"
+ }
+ }
+
+ backend "local" {
+ path = "terraform.tfstate"
+ }
+}
+
+provider "kubernetes" {
+ host = var.cluster_endpoint
+ cluster_ca_certificate = base64decode(var.cluster_ca_cert)
+ token = var.cluster_token
+}
+
+provider "helm" {
+ kubernetes {
+ host = var.cluster_endpoint
+ cluster_ca_certificate = base64decode(var.cluster_ca_cert)
+ token = var.cluster_token
+ }
+}
+
+module "ingress" {
+ source = "./modules/ingress"
+ protected_services = var.protected_services
+}
+
+module "homarr" {
+ source = "./modules/homarr"
+ homarr_version = var.homarr_version
+ homarr_oidc_client_secret = var.homarr_oidc_client_secret
+}
+
+module "portfolio" {
+ source = "./modules/portfolio"
+ portfolio_image_repo = var.portfolio_image_repo
+ portfolio_image_tag = var.portfolio_image_tag
+}
+
+module "network_policy" {
+ source = "./modules/network-policy"
+ isolated_services = var.isolated_services
+}
+```
+
+**`variables.tf`:**
+```hcl
+variable "cluster_endpoint" {
+ type = string
+ description = "K8s API endpoint"
+}
+
+variable "cluster_ca_cert" {
+ type = string
+ sensitive = true
+}
+
+variable "cluster_token" {
+ type = string
+ sensitive = true
+}
+
+variable "protected_services" {
+ type = map(object({
+ host = string
+ namespace = string
+ service_name = string
+ service_port = number
+ }))
+ default = {
+ "longhorn" = {
+ host = "longhorn.riotpiao.homelab.com"
+ namespace = "longhorn-system"
+ service_name = "longhorn-frontend"
+ service_port = 80
+ }
+ "portainer" = {
+ host = "portainer.riotpiao.homelab.com"
+ namespace = "dashboard"
+ service_name = "portainer"
+ service_port = 9000
+ }
+ "prometheus" = {
+ host = "prometheus.riotpiao.homelab.com"
+ namespace = "monitoring"
+ service_name = "prometheus-operated"
+ service_port = 9090
+ }
+ }
+}
+
+variable "homarr_version" {
+ type = string
+ default = "~1"
+}
+
+variable "homarr_oidc_client_secret" {
+ type = string
+ sensitive = true
+ description = "From Authentik provider"
+}
+
+variable "portfolio_image_repo" {
+ type = string
+ default = "forgejo.riotpiao.homelab.com/rock/portfolio"
+}
+
+variable "portfolio_image_tag" {
+ type = string
+ default = "latest"
+}
+
+variable "isolated_services" {
+ type = map(object({
+ namespace = string
+ pod_selector = map(string)
+ }))
+ default = {
+ "longhorn" = {
+ namespace = "longhorn-system"
+ pod_selector = {
+ "app.kubernetes.io/name" = "longhorn"
+ }
+ }
+ "portainer" = {
+ namespace = "dashboard"
+ pod_selector = {
+ "app" = "portainer"
+ }
+ }
+ "prometheus" = {
+ namespace = "monitoring"
+ pod_selector = {
+ "app.kubernetes.io/name" = "prometheus"
+ }
+ }
+ }
+}
+```
+
+---
+
+## Implementation Sequencing
+
+1. **Authentik setup (Python):**
+ - Register Proxy Providers (Longhorn, Portainer, Prometheus)
+ - Create groups (infra-admins, homarr-infra-admins)
+ - Verify `/outpost.goauthentik.io/auth/nginx` endpoint accessible
+
+2. **Terraform deploy (parallel):**
+ - Ingress + NetworkPolicies (protected services)
+ - Homarr (depends on Authentik, has own OIDC)
+ - Portfolio (independent, public)
+
+3. **Portfolio build + push:**
+ - `cd ~/workplace/riotpiao && ./build.sh`
+ - Verify image in Forgejo registry
+
+4. **Terraform apply:**
+ ```bash
+ terraform init
+ terraform plan
+ terraform apply
+ ```
+
+5. **Verification:**
+ - `curl -I https://longhorn.riotpiao.homelab.com` → 302 to Authentik (unauthenticated)
+ - Login as `infra-admins` member → Longhorn UI loads
+ - `curl -I https://homarr.riotpiao.homelab.com` → OIDC sign-in page
+ - Login → Homarr boards visible
+ - `curl -I https://portfolio.riotpiao.homelab.com` → 200, no redirect
+
+---
+
+## Files to Create
+
+**In homelab repo:**
+- `terraform.tfvars` (git-ignored)
+- `main.tf`, `variables.tf`, `outputs.tf`
+- `modules/{ingress,homarr,portfolio,network-policy}/*`
+- `k8s/homarr/README.md` (board setup runbook)
+- `k8s/portfolio/Chart.yaml`, `templates/*`
+
+**In portfolio repo (`~/workplace/riotpiao`):**
+- `app/layout.tsx`, `app/page.tsx`, `app/about/page.tsx`
+- `components/{Header,Footer,ProjectCard}.tsx`
+- `content/{projects,experience,metadata}.ts`
+- `styles/globals.css`
+- `Dockerfile`, `build.sh`, `next.config.js`
+- `package.json` (Next.js 15 + Tailwind)
+
+---
+
+## Success Criteria
+
+- [ ] Protected services (Longhorn/Portainer/Prometheus) redirect unauthenticated to Authentik
+- [ ] Infra-admins group members see UI; non-members denied
+- [ ] Homarr OIDC login works; boards render for authorized groups
+- [ ] Portfolio site accessible without auth; project grid + about page live
+- [ ] All deployed via `terraform apply` (no manual kubectl)
+- [ ] Terraform state tracks 100% of resources
diff --git a/app/cluster/chat/page.tsx b/app/cluster/chat/page.tsx
new file mode 100644
index 0000000..a7b2799
--- /dev/null
+++ b/app/cluster/chat/page.tsx
@@ -0,0 +1,217 @@
+'use client'
+
+import { useEffect, useRef, useState } from 'react'
+import { ChevronDown } from 'lucide-react'
+import { Panel } from '@/components/cluster/Panel'
+import { SlotMeter } from '@/components/cluster/SlotMeter'
+
+const DAILY_BUDGET = 12
+
+type Turn = {
+ role: 'user' | 'model'
+ reasoning?: string
+ content: string
+ streaming?: boolean
+}
+
+const SEED: Turn[] = [
+ { role: 'user', content: 'Why is the sms application degraded?' },
+ {
+ role: 'model',
+ reasoning:
+ 'The snapshot lists sms with health "degraded" and sync "synced". Sync being clean means the manifests applied fine, so this is a runtime problem rather than a delivery one. The sms namespace shows 0 of 1 pods running. A single pod that never reaches Running, with Argo reporting the desired state as applied, usually means the pod cannot be placed at all.',
+ content:
+ 'Delivery is fine — sms is Synced, so Argo applied everything it was asked to. The failure is at runtime: the namespace has one pod and zero running. Argo marks the app degraded because the workload never became ready, not because the manifests are wrong.',
+ },
+]
+
+const REPLY =
+ 'Wave 4 is empty. Waves are sort keys, not a sequence — Argo orders by value and skips gaps, so 3 is followed directly by 5. Nothing is missing.'
+
+const REPLY_REASONING =
+ 'The user is asking about a gap in the wave column display. Argo CD sync waves are integers used purely for ordering; there is no requirement that they be contiguous. The cluster uses 0,1,2,3,5,6,7,8. This is normal and usually happens when a wave is retired or intentionally reserved.'
+
+export default function ChatPage() {
+ const [turns, setTurns] = useState(SEED)
+ const [value, setValue] = useState('')
+ const [queue, setQueue] = useState(null)
+ const [slots, setSlots] = useState(3)
+ const [used, setUsed] = useState(2)
+ const [openReasoning, setOpenReasoning] = useState(1)
+ const scrollRef = useRef(null)
+
+ useEffect(() => {
+ scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' })
+ }, [turns, queue])
+
+ const send = () => {
+ if (!value.trim() || queue !== null || used >= DAILY_BUDGET) return
+ setTurns((t) => [...t, { role: 'user', content: value }])
+ setValue('')
+ setQueue(3)
+ }
+
+ // Placeholder for the queue → stream transition. Real version is SSE from atlas.
+ useEffect(() => {
+ if (queue === null) return
+ if (queue > 0) {
+ const t = setTimeout(() => setQueue((q) => (q === null ? null : q - 1)), 700)
+ return () => clearTimeout(t)
+ }
+ setQueue(null)
+ setSlots((s) => Math.min(s + 1, 6))
+ setUsed((u) => u + 1)
+ setTurns((t) => [...t, { role: 'model', reasoning: REPLY_REASONING, content: '', streaming: true }])
+
+ let i = 0
+ const stream = setInterval(() => {
+ i += 3
+ setTurns((t) => {
+ const next = [...t]
+ const last = next[next.length - 1]
+ if (last?.role !== 'model') return t
+ next[next.length - 1] = { ...last, content: REPLY.slice(0, i), streaming: i < REPLY.length }
+ return next
+ })
+ if (i >= REPLY.length) {
+ clearInterval(stream)
+ setSlots((s) => Math.max(s - 1, 1))
+ }
+ }, 40)
+ return () => clearInterval(stream)
+ }, [queue])
+
+ const exhausted = used >= DAILY_BUDGET
+
+ return (
+
+
+ Surface D — Chat
+
+ A 32B model, running on one card, two rooms from here.
+
+
+ It reads a redacted snapshot of the cluster and answers questions about it. It cannot query anything, run
+ anything, or change anything. When all six public slots are busy, you wait in line — the queue is real,
+ and so is the hardware.
+
+
+
+
+ {DAILY_BUDGET - used} of {DAILY_BUDGET} messages left today
+
+
+
+
+
+
+
+ {turns.map((turn, i) =>
+ turn.role === 'user' ? (
+
+ ) : (
+
+ {turn.reasoning && (
+
+
setOpenReasoning(openReasoning === i ? null : i)}
+ aria-expanded={openReasoning === i}
+ className="flex w-full items-center gap-2 py-1 pl-3 font-data text-[10px] uppercase tracking-[0.16em] text-lamp focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp"
+ >
+
+ thinking
+
+ {openReasoning === i && (
+
+ {turn.reasoning}
+
+ )}
+
+ )}
+
+ {turn.content}
+ {turn.streaming && }
+
+
+ ),
+ )}
+
+ {queue !== null && (
+
+
+
+ all six public slots busy · position {queue} in queue
+
+
+ )}
+
+
+
+
+
+
+
+
+ {[
+ ['public slots', '6 of 8'],
+ ['queue depth', '20'],
+ ['per session', '12 / day'],
+ ['request timeout', '120s'],
+ ['output cap', '1500 tokens'],
+ ].map(([k, v]) => (
+
+
{k}
+ {v}
+
+ ))}
+
+
+ Closing this tab frees your slot immediately. Two slots stay reserved so the operator is never locked
+ out of their own hardware.
+
+
+
+
+
+ {['call tools', 'query the cluster', 'read logs', 'change anything', 'see Secret contents'].map((x) => (
+
+
+ {x}
+
+ ))}
+
+
+
+
+
+ )
+}
diff --git a/app/cluster/delivery/page.tsx b/app/cluster/delivery/page.tsx
new file mode 100644
index 0000000..8283c09
--- /dev/null
+++ b/app/cluster/delivery/page.tsx
@@ -0,0 +1,219 @@
+'use client'
+
+import { useCallback, useEffect, useState } from 'react'
+import { Panel } from '@/components/cluster/Panel'
+import { DEFAULT_KINDS, WAVES, apps, appsInWave, resourceKinds, type App } from '@/lib/clusterMock'
+
+const TOTAL_RESOURCES = apps.reduce((n, a) => n + a.resources, 0)
+
+/** Resource count as discrete cells, capped so a 68-resource app stays readable. */
+function CountBar({ n }: { n: number }) {
+ const cells = Math.min(n, 24)
+ return (
+
+ {Array.from({ length: cells }, (_, i) => (
+
+ ))}
+ {n > 24 && +{n - 24} }
+
+ )
+}
+
+function AppCard({
+ app,
+ state,
+ active,
+ onSelect,
+}: {
+ app: App
+ state: 'idle' | 'syncing' | 'done'
+ active: boolean
+ onSelect: () => void
+}) {
+ const degraded = app.health === 'degraded'
+ const drifted = app.sync === 'outofsync'
+
+ const border = active
+ ? 'border-lamp'
+ : state === 'syncing'
+ ? 'border-lamp/70'
+ : degraded
+ ? 'border-rose/50'
+ : drifted
+ ? 'border-lamp/40'
+ : 'border-wire'
+
+ return (
+
+
+ {app.name}
+
+
+
+ {(degraded || drifted) && (
+
+ {degraded ? 'degraded' : 'out of sync'}
+
+ )}
+
+ )
+}
+
+export default function DeliveryPage() {
+ const [selected, setSelected] = useState('prometheus')
+ const [front, setFront] = useState(null)
+
+ const replay = useCallback(() => setFront(0), [])
+
+ useEffect(() => {
+ if (front === null) return
+ if (front > 8) {
+ const done = setTimeout(() => setFront(null), 700)
+ return () => clearTimeout(done)
+ }
+ const next = setTimeout(() => setFront((w) => (w === null ? null : w + 1)), 520)
+ return () => clearTimeout(next)
+ }, [front])
+
+ const selectedApp = apps.find((a) => a.name === selected) ?? null
+ const kinds = selectedApp ? (resourceKinds[selectedApp.name] ?? DEFAULT_KINDS) : []
+
+ return (
+
+
+ Surface E — Delivery
+
+ Nothing starts until the thing it needs is already running.
+
+
+ {apps.length} applications, {TOTAL_RESOURCES} resources, applied in nine ordered waves. Certificates
+ before issuers, issuers before ingress, storage before the databases that sit on it. The order is the
+ design.
+
+
+ {front !== null ? `syncing wave ${Math.min(front, 8)}` : 'Replay sync'}
+
+
+
+
+
+
+
+ {WAVES.map((wave) => {
+ const inWave = appsInWave(wave)
+ const state = front === null ? 'idle' : front === wave ? 'syncing' : front > wave ? 'done' : 'idle'
+
+ return (
+
+
+
+ {wave}
+
+
+ {inWave.length || '—'}
+
+
+
+ {inWave.length === 0 ? (
+
+ unused — waves are sparse by design, not sequential
+
+ ) : (
+
+ {inWave.map((app) => (
+
setSelected(app.name)}
+ />
+ ))}
+
+ )}
+
+ )
+ })}
+
+
+
+
+
+ {selectedApp ? (
+
+
+
+
sync
+ {selectedApp.sync}
+
+
+
health
+
+ {selectedApp.health}
+
+
+
+
+
+
Resources by kind
+
+ {kinds.map((k) => (
+
+ {k.kind}
+
+ {k.count}
+ {!k.named && (
+
+ count only
+
+ )}
+
+ ))}
+
+
+
+
+ Secrets appear as counts. Names, source repositories, and condition messages are never sent to the
+ browser.
+
+
+ ) : (
+ Select an application to inspect its resources.
+ )}
+
+
+
+ )
+}
diff --git a/app/cluster/layout.tsx b/app/cluster/layout.tsx
new file mode 100644
index 0000000..4769a85
--- /dev/null
+++ b/app/cluster/layout.tsx
@@ -0,0 +1,39 @@
+import type { ReactNode } from 'react'
+import { IBM_Plex_Mono, IBM_Plex_Sans, IBM_Plex_Sans_Condensed } from 'next/font/google'
+import { Rail } from '@/components/cluster/Rail'
+import { Ribbon } from '@/components/cluster/Ribbon'
+
+const signage = IBM_Plex_Sans_Condensed({
+ subsets: ['latin'],
+ weight: ['600', '700'],
+ variable: '--font-signage',
+})
+
+const plex = IBM_Plex_Sans({
+ subsets: ['latin'],
+ weight: ['400', '500', '600'],
+ variable: '--font-plex',
+})
+
+const data = IBM_Plex_Mono({
+ subsets: ['latin'],
+ weight: ['400', '500'],
+ variable: '--font-data',
+})
+
+export const metadata = {
+ title: 'Cluster — Rock Liang',
+ description: 'Live view of a Talos Kubernetes cluster: topology, GitOps delivery, and GPU inference.',
+}
+
+export default function ClusterLayout({ children }: { children: ReactNode }) {
+ return (
+
+ )
+}
diff --git a/app/cluster/page.tsx b/app/cluster/page.tsx
new file mode 100644
index 0000000..663fe28
--- /dev/null
+++ b/app/cluster/page.tsx
@@ -0,0 +1,147 @@
+'use client'
+
+import { useState } from 'react'
+import { Panel } from '@/components/cluster/Panel'
+import { SlotMeter } from '@/components/cluster/SlotMeter'
+import { models, namespaces, nodes, type Node } from '@/lib/clusterMock'
+
+function Cells({ filled, total, tone = 'flux' }: { filled: number; total: number; tone?: 'flux' | 'rose' }) {
+ return (
+
+ {Array.from({ length: total }, (_, i) => (
+
+ ))}
+
+ )
+}
+
+function NodeCard({ node, active, onSelect }: { node: Node; active: boolean; onSelect: () => void }) {
+ const isGpu = node.gpu > 0
+ return (
+
+ {isGpu && }
+
+
{node.name}
+
+
+
+ {node.role}
+
+
+
+
+
cpu
+ {node.cpu}
+
+
+
mem
+ {node.memoryGi} Gi
+
+
+
gpu
+ {node.gpu}
+
+
+
pods
+ {node.pods}
+
+
+
+ )
+}
+
+export default function TopologyPage() {
+ const [selected, setSelected] = useState('worker-1')
+
+ return (
+
+ {/* Thesis: the constraint that shaped everything downstream. */}
+
+
+
+ {nodes.map((n) => (
+ setSelected(n.name)} />
+ ))}
+
+
+
+
+
+ {namespaces.map((ns) => {
+ const short = ns.running < ns.total
+ return (
+
+ {ns.name}
+
+
+ {ns.running}/{ns.total}
+
+
+ )
+ })}
+
+
+
+
+
+
+
+
+
+
+ {['node and pod addresses', 'container arguments', 'image tags and digests', 'source repository URLs', 'Secret names', 'condition messages'].map((x) => (
+
+
+ {x}
+
+ ))}
+
+
+ Fields are built by explicit construction, so anything not listed as public never enters the
+ response.
+
+
+
+
+
+ )
+}
diff --git a/app/cluster/terminal/page.tsx b/app/cluster/terminal/page.tsx
new file mode 100644
index 0000000..c212d7f
--- /dev/null
+++ b/app/cluster/terminal/page.tsx
@@ -0,0 +1,173 @@
+'use client'
+
+import { useEffect, useRef, useState } from 'react'
+import { Panel } from '@/components/cluster/Panel'
+import { namespaces, nodes, apps } from '@/lib/clusterMock'
+
+const COMMANDS = [
+ 'get nodes',
+ 'get pods ',
+ 'get apps',
+ 'top nodes',
+ 'describe pod ',
+ 'help',
+]
+
+type Line = { kind: 'input' | 'output' | 'reject'; text: string }
+
+const pad = (s: string, n: number) => s.padEnd(n, ' ')
+
+function run(raw: string): Line[] {
+ const cmd = raw.trim().toLowerCase()
+
+ if (cmd === 'help') {
+ return [{ kind: 'output', text: COMMANDS.map((c) => ` ${c}`).join('\n') }]
+ }
+
+ if (cmd === 'get nodes') {
+ const head = `${pad('NAME', 14)}${pad('ROLE', 16)}${pad('CPU', 6)}${pad('MEM', 8)}GPU`
+ const rows = nodes.map((n) => `${pad(n.name, 14)}${pad(n.role, 16)}${pad(String(n.cpu), 6)}${pad(`${n.memoryGi}Gi`, 8)}${n.gpu}`)
+ return [{ kind: 'output', text: [head, ...rows].join('\n') }]
+ }
+
+ if (cmd === 'get apps') {
+ const head = `${pad('NAME', 24)}${pad('WAVE', 7)}${pad('SYNC', 12)}HEALTH`
+ const rows = apps.map((a) => `${pad(a.name, 24)}${pad(String(a.wave ?? '-'), 7)}${pad(a.sync, 12)}${a.health}`)
+ return [{ kind: 'output', text: [head, ...rows].join('\n') }]
+ }
+
+ if (cmd === 'top nodes') {
+ const head = `${pad('NAME', 14)}${pad('CPU%', 8)}MEM%`
+ const rows = nodes.map((n) => `${pad(n.name, 14)}${pad(n.gpu ? '61%' : '18%', 8)}${n.gpu ? '74%' : '42%'}`)
+ return [{ kind: 'output', text: [head, ...rows].join('\n') }]
+ }
+
+ if (cmd.startsWith('get pods')) {
+ const ns = cmd.split(/\s+/)[2]
+ if (!ns) return [{ kind: 'reject', text: 'get pods requires a namespace. Try: get pods llm-serving' }]
+ const known = namespaces.find((n) => n.name === ns)
+ if (!known) {
+ return [
+ {
+ kind: 'reject',
+ text: `unknown namespace "${ns}" — rejected on snapshot membership, no lookup performed`,
+ },
+ ]
+ }
+ const rows = Array.from({ length: Math.min(known.total, 8) }, (_, i) => {
+ const running = i < known.running
+ return `${pad(`${ns}-workload-${i + 1}`, 30)}${pad(running ? '1/1' : '0/1', 6)}${running ? 'Running' : 'Pending'}`
+ })
+ return [{ kind: 'output', text: [`${pad('NAME', 30)}${pad('READY', 6)}STATUS`, ...rows].join('\n') }]
+ }
+
+ if (cmd.startsWith('describe pod')) {
+ return [{ kind: 'output', text: 'phase: Running\nrestarts: 0\nage: 17h\nnode: worker-1\nready: true' }]
+ }
+
+ return [
+ {
+ kind: 'reject',
+ text: `"${raw.trim()}" is not in the command set. Input parses to a closed enum; nothing else reaches the cluster. Type help.`,
+ },
+ ]
+}
+
+const BOOT: Line[] = [
+ { kind: 'output', text: 'atlas read-only shell. Six commands, no shell, no exec.\nType help to list them.' },
+]
+
+export default function TerminalPage() {
+ const [lines, setLines] = useState(BOOT)
+ const [value, setValue] = useState('')
+ const scrollRef = useRef(null)
+
+ useEffect(() => {
+ scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight })
+ }, [lines])
+
+ const submit = (raw: string) => {
+ if (!raw.trim()) return
+ setLines((prev) => [...prev, { kind: 'input', text: raw }, ...run(raw)])
+ setValue('')
+ }
+
+ return (
+
+
+
+
+
+
+ {lines.map((line, i) => (
+
+ {line.kind === 'input' && (
+
+ $
+ {line.text}
+
+ )}
+ {line.kind === 'output' &&
{line.text}
}
+ {line.kind === 'reject' && (
+
{line.text}
+ )}
+
+ ))}
+
+
+
+
+
+
+
+ {COMMANDS.map((c) => (
+
+ submit(c.replace('', 'llm-serving').replace('', 'ornith-predictor'))}
+ className="w-full border border-wire px-2.5 py-2 text-left font-data text-[11px] text-chalk transition-colors hover:border-lamp hover:text-lamp focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp"
+ >
+ {c}
+
+
+ ))}
+
+
+ Every rejected input is logged with its source address. The allowlist is the whole security model.
+
+
+
+
+ )
+}
diff --git a/app/globals.css b/app/globals.css
new file mode 100644
index 0000000..192997f
--- /dev/null
+++ b/app/globals.css
@@ -0,0 +1,11 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+}
diff --git a/app/layout.tsx b/app/layout.tsx
new file mode 100644
index 0000000..6c51a91
--- /dev/null
+++ b/app/layout.tsx
@@ -0,0 +1,22 @@
+import './globals.css'
+import Header from '@/components/Header'
+
+export const metadata = {
+ title: 'Rock Liang — Portfolio & Live Infrastructure',
+ description: 'Personal portfolio showcasing Kubernetes, Terraform, and cloud-native systems.',
+};
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+
+ {children}
+
+
+ );
+}
diff --git a/app/page.tsx b/app/page.tsx
new file mode 100644
index 0000000..4f7d55a
--- /dev/null
+++ b/app/page.tsx
@@ -0,0 +1,182 @@
+'use client'
+
+import { motion } from 'framer-motion'
+import { FeatureCard } from '@/components/FeatureCard'
+import { HeroBlobFlow } from '@/components/HeroBlobFlow'
+import { InteractiveTerminal } from '@/components/InteractiveTerminal'
+import { ExperienceTimeline } from '@/components/ExperienceTimeline'
+import {
+ GitBranch,
+ Database,
+ BarChart3,
+ MessageSquare,
+ Cpu,
+ Layers,
+} from 'lucide-react'
+
+const features = [
+ {
+ icon: GitBranch,
+ title: 'Infrastructure Platform',
+ description: 'Multi-region Terraform + Argo CD GitOps on Kubernetes',
+ href: '/infrastructure',
+ stat: '40% CPU reduction',
+ status: 'live' as const,
+ },
+ {
+ icon: Cpu,
+ title: 'Distributed Systems',
+ description: 'gRPC, Kafka, AWS Step Functions across 57+ regions',
+ href: '/systems',
+ stat: 'Mission-critical',
+ status: 'live' as const,
+ },
+ {
+ icon: MessageSquare,
+ title: 'LLM Systems',
+ description: 'CPU-bound inference optimization, INT4/INT8 quantization',
+ href: '/llm',
+ stat: '60% latency cut',
+ status: 'live' as const,
+ },
+ {
+ icon: Database,
+ title: 'Kafka Cluster',
+ description: 'Strimzi KRaft cluster with auto-scaling brokers',
+ href: '/kafka',
+ stat: '3 brokers',
+ status: 'live' as const,
+ },
+ {
+ icon: Layers,
+ title: 'Open Source',
+ description: 'go-flink: distributed DataLakeHouse in Go',
+ href: '/opensource',
+ stat: 'Public repo',
+ status: 'live' as const,
+ },
+ {
+ icon: BarChart3,
+ title: 'Observability',
+ description: 'Prometheus, Grafana, Dynatrace — live metrics',
+ href: '/infrastructure',
+ stat: '99.2% uptime',
+ status: 'live' as const,
+ },
+]
+
+export default function Home() {
+ return (
+
+ {/* Hero */}
+
+
+ {/* Avatar with flowing outcomes */}
+
+
+ {/* Description */}
+
+
+ Full-Stack Systems Engineer
+
+
+ Infrastructure × Backend × LLM Systems
+
+
+ Building observable, fault-tolerant systems from bare metal to cloud. Optimizing cost (infrastructure) × performance (inference) × reliability (SRE).
+
+
+
+
+
+ 💡 Press Cmd+K to explore via terminal
+
+
+
+
+
+ {/* Experience Timeline */}
+
+
+ {/* Features Grid */}
+
+
+ What I Build
+
+ Production systems spanning infrastructure, distributed backends, and LLM optimization. Click any domain to explore.
+
+
+
+
+ {features.map((feature) => (
+
+ ))}
+
+
+
+ {/* Footer */}
+
+
+ {/* Interactive Terminal */}
+
+
+ )
+}
diff --git a/components/AnimatedRoles.tsx b/components/AnimatedRoles.tsx
new file mode 100644
index 0000000..bbb9fcb
--- /dev/null
+++ b/components/AnimatedRoles.tsx
@@ -0,0 +1,62 @@
+'use client'
+
+import { motion } from 'framer-motion'
+
+interface AnimatedRolesProps {
+ roles: string[]
+ className?: string
+}
+
+export function AnimatedRoles({ roles, className }: AnimatedRolesProps) {
+ const animations = [
+ {
+ initial: { opacity: 0, x: -20 },
+ animate: { opacity: 1, x: 0 },
+ },
+ {
+ initial: { opacity: 0, y: 20 },
+ animate: { opacity: 1, y: 0 },
+ },
+ {
+ initial: { opacity: 0, x: 20 },
+ animate: { opacity: 1, x: 0 },
+ },
+ {
+ initial: { opacity: 0, scale: 0.8 },
+ animate: { opacity: 1, scale: 1 },
+ },
+ ]
+
+ return (
+
+ {roles.map((role, index) => {
+ const animation = animations[index % animations.length]
+ return (
+
+ {role}
+ {index < roles.length - 1 && (
+
+ •
+
+ )}
+
+ )
+ })}
+
+ )
+}
diff --git a/components/AvatarWithBlob.tsx b/components/AvatarWithBlob.tsx
new file mode 100644
index 0000000..32ee84f
--- /dev/null
+++ b/components/AvatarWithBlob.tsx
@@ -0,0 +1,87 @@
+'use client'
+
+import { motion } from 'framer-motion'
+
+interface AvatarWithBlobProps {
+ roles: string[]
+}
+
+export function AvatarWithBlob({ roles }: AvatarWithBlobProps) {
+ // Floating animation variants for each role blob
+ const getBlobVariants = (index: number) => ({
+ animate: {
+ y: [0, -20, 0],
+ x: [0, Math.cos((index * 2 * Math.PI) / roles.length) * 10, 0],
+ rotate: [0, 5, -5, 0],
+ transition: {
+ duration: 4 + index * 0.5,
+ repeat: Infinity,
+ ease: 'easeInOut',
+ },
+ },
+ })
+
+ return (
+
+ {/* Animated background blobs */}
+
+ {/* Center circle glow */}
+
+
+
+ {/* Avatar center */}
+
+
+ RL
+
+
+
+ {/* Floating role blobs */}
+ {roles.map((role, index) => {
+ const angle = (index * 2 * Math.PI) / roles.length
+ const radius = 120
+ const x = Math.cos(angle) * radius
+ const y = Math.sin(angle) * radius
+
+ return (
+
+
+ {role}
+
+
+ )
+ })}
+
+ )
+}
diff --git a/components/ExperienceTimeline.tsx b/components/ExperienceTimeline.tsx
new file mode 100644
index 0000000..500806a
--- /dev/null
+++ b/components/ExperienceTimeline.tsx
@@ -0,0 +1,150 @@
+'use client'
+
+import { motion } from 'framer-motion'
+
+interface TimelineItem {
+ company: string
+ role: string
+ period: string
+ description: string
+ impact: string
+ skills: string[]
+ color: string
+}
+
+const timeline: TimelineItem[] = [
+ {
+ company: 'RBC',
+ role: 'Infrastructure Platform Architect',
+ period: '2020 — Present',
+ description: 'Leading multi-region infrastructure platform on Kubernetes. Building GitOps workflows with Terraform and Argo CD across 4 global regions.',
+ impact: '40% CPU reduction, 99.2% uptime',
+ skills: ['Kubernetes', 'Terraform', 'Argo CD', 'Go', 'AWS', 'Cilium', 'Prometheus', 'Grafana'],
+ color: 'from-blue-500 to-blue-600',
+ },
+ {
+ company: 'AWS',
+ role: 'Senior Software Engineer (Step Functions)',
+ period: '2019 — 2020',
+ description: 'Designed and optimized distributed orchestration platform. Built fault-tolerant task scheduling across 57+ regions serving mission-critical workloads.',
+ impact: '8 core components, 57+ regions',
+ skills: ['AWS', 'Java', 'gRPC', 'Distributed Systems', 'DynamoDB', 'CloudWatch'],
+ color: 'from-orange-500 to-orange-600',
+ },
+ {
+ company: 'Homelab',
+ role: 'DevOps / SRE / SDE',
+ period: '2021 — Present',
+ description: 'Production-grade bare-metal K8s cluster (Talos + Cilium). Built Temporal-based LLM inference pipeline with CPU-bound optimization and quantization.',
+ impact: '60% latency cut, 75% memory saved',
+ skills: ['LangGraph', 'Temporal', 'LLM Ops', 'PyTorch', 'Kafka', 'Observability'],
+ color: 'from-green-500 to-green-600',
+ },
+ {
+ company: 'Open Source',
+ role: 'Maintainer — go-flink',
+ period: '2022 — Present',
+ description: 'Building distributed DataLakeHouse framework in Go. Fault-tolerant task scheduling, streaming semantics, and efficient data processing.',
+ impact: 'Public repository, active development',
+ skills: ['Go', 'Distributed Systems', 'Data Pipeline', 'Testing', 'Architecture'],
+ color: 'from-purple-500 to-purple-600',
+ },
+]
+
+const containerVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.2,
+ },
+ },
+}
+
+const itemVariants = {
+ hidden: { opacity: 0, x: -20 },
+ visible: {
+ opacity: 1,
+ x: 0,
+ transition: { duration: 0.6, ease: 'easeOut' },
+ },
+}
+
+export function ExperienceTimeline() {
+ return (
+
+
+ Explore Experience
+
+ From AWS to RBC. Building systems at scale. Skills acquired along the journey.
+
+
+
+
+ {/* Timeline line */}
+
+
+ {/* Timeline items */}
+
+ {timeline.map((item, index) => (
+
+ {/* Timeline dot */}
+
+
+ {/* Content card */}
+
+
+
+
+
+ {item.company}
+
+
+ {item.role}
+
+
+
+ {item.period}
+
+
+
+
+ {item.description}
+
+
+
+ 📊 {item.impact}
+
+
+
+ {item.skills.map((skill) => (
+
+ {skill}
+
+ ))}
+
+
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/components/FeatureCard.tsx b/components/FeatureCard.tsx
new file mode 100644
index 0000000..787b03a
--- /dev/null
+++ b/components/FeatureCard.tsx
@@ -0,0 +1,54 @@
+'use client'
+
+import Link from 'next/link'
+import { motion } from 'framer-motion'
+import { LucideIcon } from 'lucide-react'
+import { LiveIndicator } from './LiveIndicator'
+
+interface FeatureCardProps {
+ icon: LucideIcon
+ title: string
+ description: string
+ href: string
+ stat?: string
+ status?: 'live' | 'offline' | 'pending'
+}
+
+export function FeatureCard({
+ icon: Icon,
+ title,
+ description,
+ href,
+ stat,
+ status = 'live',
+}: FeatureCardProps) {
+ return (
+
+
+
+
+
+
+
+ {title}
+
+ {description}
+
+ {stat && (
+
+ {stat}
+
+ )}
+
+
+
+ )
+}
diff --git a/components/Header.tsx b/components/Header.tsx
new file mode 100644
index 0000000..6b1e0db
--- /dev/null
+++ b/components/Header.tsx
@@ -0,0 +1,65 @@
+'use client'
+
+import Link from 'next/link'
+import { Menu, X, Moon, Sun } from 'lucide-react'
+import { useState, useEffect } from 'react'
+
+export default function Header() {
+ const [open, setOpen] = useState(false)
+ const [dark, setDark] = useState(false)
+
+ useEffect(() => {
+ const isDark = document.documentElement.classList.contains('dark')
+ setDark(isDark)
+ }, [])
+
+ const toggleDark = () => {
+ document.documentElement.classList.toggle('dark')
+ setDark(!dark)
+ }
+
+ return (
+
+ )
+}
diff --git a/components/HeroBlobFlow.tsx b/components/HeroBlobFlow.tsx
new file mode 100644
index 0000000..0a5dfdb
--- /dev/null
+++ b/components/HeroBlobFlow.tsx
@@ -0,0 +1,80 @@
+'use client'
+
+import { motion, AnimatePresence } from 'framer-motion'
+import { useState, useEffect } from 'react'
+import { Code, Network, Zap, Sparkles, Github } from 'lucide-react'
+import { TypewriterText } from './TypewriterText'
+
+const roles = [
+ { text: 'Software Engineer Lead', icon: Code },
+ { text: 'Infrastructure Architect', icon: Network },
+ { text: 'Distributed Systems Builder', icon: Zap },
+ { text: 'LLM Systems Optimizer', icon: Sparkles },
+ { text: 'Open Source Developer', icon: Github },
+]
+
+export function HeroBlobFlow() {
+ const [index, setIndex] = useState(0)
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setIndex((prev) => (prev + 1) % roles.length)
+ }, 2000)
+ return () => clearInterval(interval)
+ }, [])
+
+ return (
+
+ {/* Background glow */}
+
+
+
+
+ {/* Avatar center */}
+
+
+ RL
+
+
+
+ {/* Typewriter text below avatar */}
+
+
+ {/* Rotating role text */}
+
+
+
+ {(() => {
+ const Icon = roles[index].icon
+ return
+ })()}
+ {roles[index].text}
+
+
+
+
+ )
+}
diff --git a/components/InteractiveTerminal.tsx b/components/InteractiveTerminal.tsx
new file mode 100644
index 0000000..b6d8c8e
--- /dev/null
+++ b/components/InteractiveTerminal.tsx
@@ -0,0 +1,148 @@
+'use client'
+
+import { motion } from 'framer-motion'
+import { useEffect, useRef, useState } from 'react'
+
+const commands: Record = {
+ help: `Available commands:
+ ls - List services
+ kubectl - Cluster info
+ terraform - Infrastructure
+ argocd - Deployments
+ kafka - Message broker
+ about - About me
+ clear - Clear terminal`,
+ ls: `storage/
+monitoring/
+cicd/
+sqs/
+temporal/
+iam/`,
+ kubectl: `Nodes: 3 (talos-cp-1, talos-worker-1, talos-worker-2)
+Pods: 42 running
+Uptime: 99.2%
+Cluster Version: v1.36.1`,
+ terraform: `Modules: 18 deployed
+Services: Kafka, PostgreSQL, MinIO, Grafana
+Storage: Longhorn (3-replica)
+Network: Cilium eBPF CNI`,
+ argocd: `Applications: 12
+Synced: 11/12
+Last Sync: 2 min ago
+Health: Healthy`,
+ kafka: `Brokers: 3 (KRaft)
+Replication Factor: 3
+Min ISR: 2
+Topics: 5 active
+Throughput: ~1K msgs/sec`,
+ about: `Rock Liang - Senior Full-Stack Systems Engineer
+Experience: 5+ years (AWS, RBC, Homelab)
+Focus: Infrastructure × Backend × LLM Systems
+Tech: Go, Java, Python, C++ | Kubernetes, Terraform, gRPC
+Current: Building production homelab + LLM inference optimization
+Open Source: go-flink (distributed DataLakeHouse)`,
+}
+
+export function InteractiveTerminal() {
+ const [input, setInput] = useState('')
+ const [history, setHistory] = useState<{ cmd: string; output: string }[]>([])
+ const [isOpen, setIsOpen] = useState(false)
+ const terminalRef = useRef(null)
+
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
+ e.preventDefault()
+ setIsOpen(!isOpen)
+ }
+ }
+
+ window.addEventListener('keydown', handleKeyDown)
+ return () => window.removeEventListener('keydown', handleKeyDown)
+ }, [isOpen])
+
+ const handleCommand = (cmd: string) => {
+ const trimmed = cmd.trim().toLowerCase()
+ if (trimmed === 'clear') {
+ setHistory([])
+ setInput('')
+ return
+ }
+
+ const output = commands[trimmed] || `command not found: ${cmd}`
+ setHistory([...history, { cmd, output }])
+ setInput('')
+
+ setTimeout(() => {
+ terminalRef.current?.scrollTo(0, terminalRef.current.scrollHeight)
+ }, 0)
+ }
+
+ return (
+
+ {!isOpen ? (
+ setIsOpen(true)}
+ className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-mono text-sm shadow-lg"
+ >
+ Terminal (Cmd+K)
+
+ ) : (
+
+
+ ZSH_THEME="robbyrussell"
+ setIsOpen(false)}
+ className="text-gray-400 hover:text-white"
+ >
+ ✕
+
+
+
+
+ {history.length === 0 && (
+
type 'help' for commands
+ )}
+ {history.map((entry, i) => (
+
+
➜ % {entry.cmd}
+
+ {entry.output}
+
+
+ ))}
+
+
+
+
+ ➜
+ %
+ setInput(e.target.value)}
+ onKeyPress={(e) => {
+ if (e.key === 'Enter') handleCommand(input)
+ }}
+ placeholder=""
+ className="flex-1 bg-transparent text-green-400 font-mono text-sm outline-none ml-1"
+ autoFocus
+ />
+
+
+
+ )}
+
+ )
+}
diff --git a/components/LiveIndicator.tsx b/components/LiveIndicator.tsx
new file mode 100644
index 0000000..108ecb3
--- /dev/null
+++ b/components/LiveIndicator.tsx
@@ -0,0 +1,35 @@
+'use client'
+
+import { motion } from 'framer-motion'
+
+interface LiveIndicatorProps {
+ status: 'live' | 'offline' | 'pending'
+ label?: string
+}
+
+export function LiveIndicator({ status, label }: LiveIndicatorProps) {
+ const colors = {
+ live: 'bg-green-500',
+ offline: 'bg-red-500',
+ pending: 'bg-yellow-500',
+ }
+
+ const labels = {
+ live: 'Live',
+ offline: 'Offline',
+ pending: 'Pending',
+ }
+
+ return (
+
+
+
+ {label || labels[status]}
+
+
+ )
+}
diff --git a/components/ProgressiveText.tsx b/components/ProgressiveText.tsx
new file mode 100644
index 0000000..a0a916e
--- /dev/null
+++ b/components/ProgressiveText.tsx
@@ -0,0 +1,43 @@
+'use client'
+
+import { motion } from 'framer-motion'
+
+interface ProgressiveTextProps {
+ texts: string[]
+ className?: string
+}
+
+export function ProgressiveText({ texts, className }: ProgressiveTextProps) {
+ const container = {
+ hidden: { opacity: 0 },
+ visible: (i = 1) => ({
+ opacity: 1,
+ transition: { staggerChildren: 0.12, delayChildren: 0.04 * i },
+ }),
+ }
+
+ const child = {
+ hidden: { opacity: 0, y: 10 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.5 },
+ },
+ }
+
+ return (
+
+ {texts.map((text, i) => (
+
+ {text}
+ {i < texts.length - 1 && ' '}
+
+ ))}
+
+ )
+}
diff --git a/components/TypewriterText.tsx b/components/TypewriterText.tsx
new file mode 100644
index 0000000..04a13bc
--- /dev/null
+++ b/components/TypewriterText.tsx
@@ -0,0 +1,55 @@
+'use client'
+
+import { motion } from 'framer-motion'
+import { useState, useEffect } from 'react'
+
+const phrases = [
+ 'a Senior Systems engineer',
+ 'Rock Liang',
+ 'a Senior Full-stack builder',
+ 'a Senior Infrastructure architect',
+ 'a Senior Backend SDE',
+]
+
+export function TypewriterText() {
+ const [currentPhrase, setCurrentPhrase] = useState(0)
+ const [displayText, setDisplayText] = useState('')
+ const [isDeleting, setIsDeleting] = useState(false)
+
+ useEffect(() => {
+ const phrase = phrases[currentPhrase]
+ const delay = isDeleting ? 50 : 100
+
+ const timer = setTimeout(() => {
+ if (!isDeleting) {
+ if (displayText.length < phrase.length) {
+ setDisplayText(phrase.substring(0, displayText.length + 1))
+ } else {
+ setTimeout(() => setIsDeleting(true), 1500)
+ }
+ } else {
+ if (displayText.length > 0) {
+ setDisplayText(phrase.substring(0, displayText.length - 1))
+ } else {
+ setIsDeleting(false)
+ setCurrentPhrase((prev) => (prev + 1) % phrases.length)
+ }
+ }
+ }, delay)
+
+ return () => clearTimeout(timer)
+ }, [displayText, isDeleting, currentPhrase])
+
+ return (
+
+
+ I'm {displayText}
+
+
+
+ )
+}
diff --git a/components/cluster/Panel.tsx b/components/cluster/Panel.tsx
new file mode 100644
index 0000000..920a194
--- /dev/null
+++ b/components/cluster/Panel.tsx
@@ -0,0 +1,31 @@
+import type { ReactNode } from 'react'
+
+type Props = {
+ label: string
+ hint?: string
+ right?: ReactNode
+ children: ReactNode
+ className?: string
+}
+
+/** Instrument panel chrome: hairline frame, corner ticks, eyebrow label. */
+export function Panel({ label, hint, right, children, className = '' }: Props) {
+ return (
+
+
+
+
+
+
+
+
+
{label}
+ {hint &&
{hint}
}
+
+ {right}
+
+
+ {children}
+
+ )
+}
diff --git a/components/cluster/Rail.tsx b/components/cluster/Rail.tsx
new file mode 100644
index 0000000..111b253
--- /dev/null
+++ b/components/cluster/Rail.tsx
@@ -0,0 +1,43 @@
+'use client'
+
+import Link from 'next/link'
+import { usePathname } from 'next/navigation'
+
+const SURFACES = [
+ { code: 'B', href: '/cluster', label: 'Topology' },
+ { code: 'E', href: '/cluster/delivery', label: 'Delivery' },
+ { code: 'C', href: '/cluster/terminal', label: 'Terminal' },
+ { code: 'D', href: '/cluster/chat', label: 'Chat' },
+]
+
+export function Rail() {
+ const pathname = usePathname()
+
+ return (
+
+ {SURFACES.map((s) => {
+ const active = pathname === s.href
+ return (
+
+ {s.code}
+
+ {s.label}
+
+
+ )
+ })}
+
+ )
+}
diff --git a/components/cluster/Ribbon.tsx b/components/cluster/Ribbon.tsx
new file mode 100644
index 0000000..8b86955
--- /dev/null
+++ b/components/cluster/Ribbon.tsx
@@ -0,0 +1,54 @@
+'use client'
+
+import { useEffect, useState } from 'react'
+import { cluster, nodes } from '@/lib/clusterMock'
+import { SlotMeter } from './SlotMeter'
+
+/** Fake liveness so the layout can be judged in motion. Replaced by SSE in Phase 2. */
+function useDrift() {
+ const [age, setAge] = useState(cluster.snapshotAge)
+ const [slots, setSlots] = useState(3)
+
+ useEffect(() => {
+ const tick = setInterval(() => setAge((a) => (a > 6 ? 0.4 : +(a + 0.9).toFixed(1))), 900)
+ const churn = setInterval(() => setSlots(() => 1 + Math.floor(Math.random() * 5)), 3400)
+ return () => {
+ clearInterval(tick)
+ clearInterval(churn)
+ }
+ }, [])
+
+ return { age, slots }
+}
+
+export function Ribbon() {
+ const { age, slots } = useDrift()
+
+ return (
+
+
+
+ {cluster.distro}
+
+
+ k8s {cluster.kubernetes}
+
+
+ nodes {nodes.length}
+
+
+ snapshot {age.toFixed(1)}s
+
+
+
+ seq
+
+ {slots}/8
+
+
+
+ placeholder data
+
+
+ )
+}
diff --git a/components/cluster/SlotMeter.tsx b/components/cluster/SlotMeter.tsx
new file mode 100644
index 0000000..a4cbbfd
--- /dev/null
+++ b/components/cluster/SlotMeter.tsx
@@ -0,0 +1,44 @@
+'use client'
+
+import { SEQUENCE_SLOTS, PUBLIC_SLOT_CAP } from '@/lib/clusterMock'
+
+type Props = {
+ used: number
+ size?: 'sm' | 'lg'
+ showCap?: boolean
+}
+
+/**
+ * The signature element. Eight discrete cells, one per vLLM sequence slot.
+ * Cells past PUBLIC_SLOT_CAP are operator headroom and read as reserved.
+ */
+export function SlotMeter({ used, size = 'sm', showCap = false }: Props) {
+ const cell = size === 'lg' ? 'h-6 w-3' : 'h-3 w-[7px]'
+
+ return (
+
+
+ {Array.from({ length: SEQUENCE_SLOTS }, (_, i) => {
+ const reserved = i >= PUBLIC_SLOT_CAP
+ const active = i < used
+ return (
+
+ )
+ })}
+
+ {showCap && (
+
+ {used}/{PUBLIC_SLOT_CAP} public · {SEQUENCE_SLOTS} total
+
+ )}
+
+ )
+}
diff --git a/docs/PLAN-atlas.md b/docs/PLAN-atlas.md
new file mode 100644
index 0000000..1d9dca9
--- /dev/null
+++ b/docs/PLAN-atlas.md
@@ -0,0 +1,327 @@
+# Implementation Plan: `atlas` — Interactive Cluster Visualization
+
+**Status**: For review — no code written yet
+**Companion ADR**: [ADR-0001](adr/ADR-0001-atlas-cluster-visualization.md)
+**Supersedes**: `PLAN.md`, `IMPLEMENTATION.md` (Homarr + Terraform — abandoned)
+
+---
+
+## 1. Scope
+
+### In scope
+
+| ID | Surface | Description |
+|---|---|---|
+| B | Cluster topology | Live node → namespace → workload graph, health-colored, drill-down |
+| E | Delivery tree | Argo CD app-of-apps as a sync-wave-ordered DAG, live sync animation |
+| C | Terminal | Read-only, enum-dispatched cluster queries in the browser |
+| D | Chat | Streaming ChatGPT-style session against the `reasoning` model |
+
+### Out of scope (v1)
+
+- Any write operation against the cluster
+- LLM tool-calling / agentic loops against live infrastructure
+- Forgejo CI half of the pipeline view (`forgejo-gitea` is currently stuck `Init:0/3`)
+- Log streaming to the browser (Loki content is unredactable in practice)
+- Authenticated / operator-only views — Grafana already serves that need
+
+### Non-goals
+
+- Replacing Grafana
+- Multi-cluster support
+- Historical / time-travel views
+
+---
+
+## 2. Phase 0 — Unblock (blocking; nothing ships until done)
+
+Verified problems, in the order they must be fixed:
+
+| # | Problem | Evidence |
+|---|---|---|
+| 0.1 | `portfolio` namespace is empty; `portfolio` and `auth-infra` Applications do not exist in the cluster | `kubectl get pods -n portfolio` → no resources; neither name appears in `kubectl get app -n argocd` |
+| 0.2 | `infra/argocd-apps.yaml` `repoURL` = `forgejo.riotpiao.homelab.com` — NXDOMAIN | `dig` |
+| 0.3 | Deployment image `forgejo.riotpiao.homelab.com/rock/portfolio:latest` — dead host, and `:latest` + `imagePullPolicy: IfNotPresent` means a pushed image will never roll out | `infra/portfolio/base/deployment.yaml` |
+| 0.4 | `forgejo-gitea` stuck `Init:0/3` for 3h — no image builds possible | `kubectl get pods -n cicd` |
+| 0.5 | `riotpiao.com` returns HTTP 403 from the Cloudflare edge; no origin headers present | `curl -I https://riotpiao.com` |
+| 0.6 | No test framework installed — TDD is impossible as the repo stands | `package.json` has no test script or runner |
+| 0.7 | `sms` Application Degraded (`macos-bluebubbles` Pending 3h); `longhorn-config` OutOfSync | `kubectl get app -n argocd` |
+
+**Decisions required from you before 0.1–0.3 can be actioned** — see ADR open questions 1 and 2.
+
+**Actions**
+
+1. Resolve which GitOps repo owns the portfolio; delete or correct the losing manifest
+2. Point `repoURL` and the image reference at real hostnames
+3. Replace `:latest` with a commit-SHA tag; set `imagePullPolicy: IfNotPresent` (correct once tags are immutable)
+4. Diagnose `forgejo-gitea` init containers — read the actual init container logs before changing anything
+5. Diagnose the apex 403 — check the tunnel's Public Hostnames list and Cloudflare WAF events; the event log names the blocking rule
+6. Add Vitest + Testing Library + `msw`; add `test` and `test:watch` scripts
+7. Triage 0.7 separately — unrelated to this work, but the delivery tree will render both as red on day one
+
+**Verify**
+
+```bash
+kubectl get pods -n portfolio # 2/2 Running
+curl -sS -o /dev/null -w '%{http_code}\n' https://riotpiao.com # 200
+pnpm test # runner executes, 0 tests, exit 0
+```
+
+---
+
+## 3. Architecture
+
+```
+kube API (client-go informers) ─┐
+Prometheus /api/v1/query ├──> atlas (Go, ns: portfolio, RO ServiceAccount)
+Argo CD Application CRs ┘ │
+ ├─ snapshot (in-memory, redacted at write)
+ ├─ Redis pub/sub (kmsvc-redis-master.sqs:6379)
+ └─ HTTP
+ GET /api/topology
+ GET /api/delivery
+ GET /api/stream (SSE)
+ POST /api/exec
+ POST /api/chat (SSE)
+ └──> reasoning-predictor.llm-serving:80
+```
+
+Event-driven, per project architectural preference: informers push to a reducer, the reducer publishes deltas to Redis, SSE handlers subscribe. No request-triggered upstream calls anywhere in the read path.
+
+Snapshot is redacted **at write time**, not at serialization time. A field that never enters the snapshot cannot leak from any surface.
+
+### Language
+
+Go, for `client-go` informers and because it matches the rest of the platform. Follow the repo's Go skill set (`go-naming`, `go-concurrency`, `go-error-handling`, `go-context`) — notably: every upstream call carries a context, no naked returns, no `_ =` on errors.
+
+---
+
+## 4. API contract
+
+Envelope for all non-stream responses:
+
+```json
+{ "data": { }, "meta": { "snapshotAge": 3.2, "generation": 88412 } }
+```
+
+Errors follow RFC 9457 (`application/problem+json`):
+
+```json
+{ "type": "https://riotpiao.com/errors/rate-limited",
+ "title": "Rate limit exceeded",
+ "status": 429, "detail": "12 of 12 messages used", "retryAfter": 3600 }
+```
+
+| Method | Path | Auth | Limit | Response |
+|---|---|---|---|---|
+| GET | `/api/topology` | none | 60/min/IP | Nodes, namespaces, workload summaries |
+| GET | `/api/delivery` | none | 60/min/IP | Argo apps, wave-grouped; resource children lazy |
+| GET | `/api/delivery/{app}/resources` | none | 60/min/IP | Virtualized child list for one app |
+| GET | `/api/stream` | session cookie | 2 concurrent/IP | SSE deltas, `topology` + `delivery` event types |
+| POST | `/api/exec` | session cookie | 20/min/session | Enum command result |
+| POST | `/api/chat` | session + Turnstile | 12/day/session, 6 global concurrent | SSE token stream |
+
+**Pagination**: `/api/delivery/{app}/resources` is cursor-paginated at 100 items. `prometheus` has 68 resources today, but `homelab-root`'s tree will grow.
+
+**Payload budget**: topology response capped at 256 KB, delivery at 256 KB. Exceeding the cap truncates and sets `meta.truncated: true` — never a silent drop.
+
+---
+
+## 5. Security
+
+Mapped against OWASP Top 10 (2021). Every item is a Phase gate, not a wish list.
+
+### A01 Broken Access Control
+
+- `atlas` ServiceAccount: one ClusterRole, verbs `get,list,watch` only, explicit resource list. **No `secrets`. No `*`. No wildcards on apiGroups.**
+- NetworkPolicy on `atlas`: egress restricted to kube API, `prometheus-operated.monitoring`, `reasoning-predictor.llm-serving`, `kmsvc-redis-master.sqs`. Ingress from `ingress-nginx` only.
+- Test: an integration test asserting the SA receives 403 on `get secrets` in every namespace.
+
+### A02 Cryptographic Failures
+
+- Session cookie: signed (HMAC), `HttpOnly`, `Secure`, `SameSite=Lax`, 24h expiry. No PII in the payload — a random session ID only.
+- Signing key from a Kubernetes Secret via SOPS (`sops-secrets` app already exists), never an env literal in a manifest.
+
+### A03 Injection
+
+The primary risk on surface C. Mitigation is structural, not filtering:
+
+- Input parses to a closed command enum. Anything unmatched is rejected before any lookup.
+- Namespace and resource-name arguments are validated by **set membership against the current snapshot**, not by regex or escaping.
+- No shell, no `exec`, no `kubectl` binary present in the container image.
+- Test: fuzz the parser; assert every input outside the allowlist returns a rejection and performs zero upstream calls.
+
+### A04 Insecure Design — information disclosure
+
+The core risk of the whole project. Redaction allowlist, enforced by DTO construction:
+
+**Emitted**: name, namespace, kind, phase, ready counts, restart count, age, node name, health status, sync status, sync wave, an explicit label subset.
+
+**Never emitted**: container env, container args, image digests, image tags, `spec.source.repoURL`, full `spec.source.path`, annotations, pod IPs, cluster IPs, Secret names, `status.conditions[].message`, node internal IPs.
+
+Specific known leaks in current data:
+- `reasoning` container args disclose the entire model and quantization strategy
+- `spec.source.repoURL` discloses a private GitHub repository
+- 21 `Secret` resources appear in Argo trees — render **kind and count only, never names**; `sops-secrets` included
+- `status.conditions[].message` echoes raw errors containing internal hostnames — emit condition **type** only
+
+Test: golden test asserting the serialized snapshot contains none of the denied field names, run against a fixture captured from the real cluster.
+
+### A05 Security Misconfiguration
+
+- Container: `runAsNonRoot`, read-only root filesystem, all capabilities dropped, `seccompProfile: RuntimeDefault`
+- Security headers on all responses: `Content-Security-Policy` (no `unsafe-inline`), `X-Content-Type-Options: nosniff`, `Referrer-Policy: no-referrer`, `Strict-Transport-Security`
+- CORS: same-origin only. No wildcard.
+
+### A07 Authentication Failures
+
+- Anonymous by design; Cloudflare Turnstile gates the first chat message
+- Session rotation on issue; no session fixation vector since there is no login
+
+### A08 Software and Data Integrity
+
+- Image tags are commit SHAs, never `:latest` (fixes Phase 0.3)
+- `pnpm audit` and `govulncheck` in CI, failing the build on high severity
+
+### A09 Logging and Monitoring
+
+- Structured logs: every rejected `/api/exec` input, every rate-limit trip, every chat queue rejection
+- Prometheus metrics from `atlas`: `atlas_chat_concurrent`, `atlas_chat_queue_depth`, `atlas_ratelimit_rejections_total`, `atlas_snapshot_age_seconds`
+- Alertmanager rule: chat queue saturated > 5 min, snapshot age > 60s
+
+### A10 SSRF
+
+- `atlas` calls a fixed, compile-time list of upstream URLs. No user input reaches any URL construction, on any path.
+
+### LLM-specific: prompt injection
+
+- System prompt is a compile-time constant, unreachable by user input
+- Cluster snapshot digest is injected in a delimited block explicitly labelled untrusted data
+- User message is always last
+- **No tool-calling.** The model reads a pre-built digest and cannot query anything. This removes the entire agentic attack surface for v1.
+- Output capped at `max_tokens: 1500` — DeepSeek-R1 will otherwise reason for minutes
+
+---
+
+## 6. Rate limiting
+
+Sized against the verified hard ceiling: **8 concurrent sequences** (`--max-num-seqs=4` × 2 replicas), single GPU node.
+
+**Tier 1 — Cloudflare edge.** WAF, Bot Fight Mode, per-IP rate rules, Turnstile before first chat message. Free, and stops scripted abuse before it reaches your hardware.
+
+**Tier 2 — Kong.** `rate-limiting` plugin, `policy: redis` against `kmsvc-redis-master.sqs:6379` so counters are cluster-wide rather than per-pod (Kong runs 2 replicas — a local policy would silently double every limit). Two profiles: generous for topology and delivery, tight for chat.
+
+**Tier 3 — `atlas`, the tier that actually protects the GPU.**
+
+| Control | Value | Rationale |
+|---|---|---|
+| Global chat semaphore | 6 | Leaves 2 of 8 sequence slots as operator headroom |
+| Queue depth | 20, then reject with `429` | A visible queue beats a wall; an unbounded queue beats nothing |
+| Per-session budget | 12 messages / 24h | Enough to explore, not enough to farm |
+| Per-request timeout | 120s hard, server-side | Independent of client behaviour |
+| Disconnect handling | cancel upstream immediately | **Critical** — a walked-away tab holding 1 of 8 slots is a real outage |
+
+Queue position is streamed to the client as SSE `{"type":"queue","position":N}` events, so waiting is legible rather than a hang.
+
+---
+
+## 7. Streaming
+
+SSE throughout — unidirectional server→client fits every surface, including token streaming. WebSockets are not justified; nothing flows client→server mid-stream.
+
+- Keepalive comment frame every 30s (idle SSE connections die at proxies)
+- `Last-Event-ID` supported on `/api/stream` for resumable topology/delivery deltas; chat is not resumable
+- `req.Context()` threaded to the upstream vLLM request so client abort cancels it — this is the mechanism that enforces the Tier 3 disconnect rule
+- Backpressure: bounded per-client channel; a slow consumer is dropped rather than allowed to grow memory
+- Chat events: `{"type":"reasoning"|"content"|"queue"|"done"|"error"}`. `--reasoning-parser=deepseek_r1` already separates `reasoning_content` from `content` — render thinking in a collapsible block. That block **is** the demo.
+
+**Context budget** (16384 total): system prompt ~300, snapshot digest capped at 2000, `max_tokens` 1500, leaving ~12500 for history. History is truncated oldest-first to fit. The digest is a compact rendering, never raw JSON.
+
+---
+
+## 8. Frontend
+
+- **Topology (B)**: React Flow, force layout. Node → namespace → workload.
+- **Delivery (E)**: React Flow, wave columns left→right from the existing `sync-wave` annotations (0→8). 31 app nodes — an ideal size for a readable DAG. Click an app → side panel with a `react-arborist` virtualized resource tree, children lazy-loaded. Live sync animation `OutOfSync → Syncing → Synced` driven by the Application watch. Push a commit during a demo and the wave cascades — that is the moment worth engineering for.
+- **Terminal (C)**: reuse [components/InteractiveTerminal.tsx](../components/InteractiveTerminal.tsx). Command set: `get nodes`, `get pods `, `get apps`, `top nodes`, `describe pod `, `help`.
+- **Chat (D)**: new component. Collapsible reasoning block, queue position, streaming tokens.
+
+Rendering budget: ~550 resources total across the tree. Lazy expansion plus virtualization is required, not optional. Target: initial delivery view interactive in < 1.5s on a cold load.
+
+**Also in scope**: delete the fabricated statistics in [app/page.tsx](../app/page.tsx) — "40% CPU reduction", "99.2% uptime", "Mission-critical", "60% latency cut" — and either wire each card to a real number from `/api/topology` or remove the claim. Five of the six cards link to routes that do not exist (`/infrastructure`, `/systems`, `/llm`, `/kafka`, `/opensource`).
+
+---
+
+## 9. Phases, TDD-first
+
+Each phase is RED → GREEN → REFACTOR. Tests named before implementation exists.
+
+### Phase 1 — `atlas` core (~4 days)
+
+RED
+- `redact_test.go`: golden test — serialized snapshot contains no denied field, against a real-cluster fixture
+- `rbac_test.go`: SA receives 403 on `get secrets`
+- `snapshot_test.go`: informer event produces the expected delta
+
+GREEN: ClusterRole, informers, reducer, DTO construction, Redis publish.
+Verify: `kubectl auth can-i get secrets --as=system:serviceaccount:portfolio:atlas` → `no`.
+
+### Phase 2 — Surface B (~3 days)
+
+RED
+- `stream_test.go`: SSE emits a delta within 5s of a pod state change
+- `topology.test.tsx`: graph re-renders on delta without a full reload
+
+Verify: delete a pod, observe the graph update in < 5s without reloading.
+
+### Phase 3 — Surface E (~3 days)
+
+RED
+- `delivery_test.go`: apps group correctly by `sync-wave`; Secret names absent from output; `repoURL` absent from output
+- `delivery.test.tsx`: 550-node tree renders under the frame budget with virtualization on
+
+Verify: trigger an Argo sync, observe wave-ordered animation.
+
+### Phase 4 — Surface C (~2 days)
+
+RED
+- `exec_parse_test.go`: fuzz corpus — every non-allowlisted input rejects and performs zero upstream calls
+- `exec_test.go`: unknown namespace rejects on snapshot membership, not regex
+
+Verify: attempt injection payloads against `/api/exec`; all rejected, all logged.
+
+### Phase 5 — Surface D + rate limiter, one PR (~5 days)
+
+RED
+- `ratelimit_test.go`: 7th concurrent chat queues rather than reaching vLLM
+- `disconnect_test.go`: client abort cancels the upstream request
+- `budget_test.go`: 13th message in 24h returns 429 with `Retry-After`
+- `injection_test.go`: snapshot content cannot alter system-prompt behaviour
+- `context_test.go`: history truncation keeps total tokens under 16384
+
+Verify: load test at 20 concurrent clients — GPU sequence usage never exceeds 6, no upstream 5xx, queue drains.
+
+**Total: ~17 working days.** Rate limiter ships in the same PR as chat, never after.
+
+---
+
+## 10. Risks
+
+| Risk | Impact | Mitigation |
+|---|---|---|
+| Redaction miss leaks internal detail | High | Allowlist by DTO construction; golden test; manual review of every new field |
+| `worker-1` fails | Chat and all inference down | Out of scope to fix; degrade chat gracefully to "offline", never a hang |
+| 8-slot ceiling makes chat feel broken under traffic | Medium | Visible queue position; consider disabling chat and shipping B/E/C only |
+| Argo CD CRD schema changes | Low | Allowlist construction means new fields are ignored by default |
+| `atlas` compromised | High | Read-only SA, NetworkPolicy egress restriction, no write verbs anywhere |
+| Cost of GPU inference for anonymous visitors | Medium | Per-session daily budget; Turnstile; edge WAF |
+
+---
+
+## 11. Decisions needed before Phase 1
+
+1. **Which GitOps repo owns the portfolio** — GitHub (`riotpiao.homelab.com`) or Forgejo? Blocks 0.1–0.3.
+2. **Apex 403 cause** — tunnel route, WAF rule, or no origin? Blocks 0.5.
+3. **Is `homarr` still wanted?** Deployed and healthy, but from the abandoned plan.
+4. **Does chat stay in v1?** Given the 8-slot ceiling, shipping B + E + C first and treating D as a separate decision is defensible.
+5. **Where does `atlas` live** — this repo, or the homelab repo? Follows from decision 1.
diff --git a/docs/adr/ADR-0001-atlas-cluster-visualization.md b/docs/adr/ADR-0001-atlas-cluster-visualization.md
new file mode 100644
index 0000000..d15763f
--- /dev/null
+++ b/docs/adr/ADR-0001-atlas-cluster-visualization.md
@@ -0,0 +1,285 @@
+# ADR-0001: `atlas` — Single Read-Only Aggregator for Public Cluster Visualization
+
+**Status**: Proposed
+
+**Date**: 2026-08-13
+
+**Authors**: Rock Liang
+
+**Supersedes**: `PLAN.md`, `IMPLEMENTATION.md` (Homarr + Terraform approach — abandoned; cluster is now GitOps/Kustomize + Argo CD)
+
+---
+
+## Context
+
+### Problem Statement
+
+The homelab cluster is fully operational and runs a non-trivial platform: Talos Kubernetes, GPU-backed LLM inference, event streaming, GitOps delivery, and a full observability stack. None of it is visible to anyone but the operator. The portfolio site meant to showcase it displays **hardcoded, fabricated statistics** and links to pages that do not exist.
+
+Goal: replace fabricated claims with a live, interactive, public view of the real system.
+
+### Current Situation (verified 2026-08-13)
+
+**Cluster**
+
+| Property | Value |
+|---|---|
+| Distro | Talos v1.13.3, Kubernetes v1.36.1 |
+| Nodes | 3× control-plane (`talos-cp-1/2/3`) + 1× `worker-1` (role `gpu-node`) |
+| `worker-1` allocatable | 95950m CPU, 65019644Ki memory, 1× `nvidia.com/gpu` |
+| Ingress | nginx, LoadBalancer `192.168.1.160`; Kong `10.105.63.160` for `api.riotpiao.com` |
+| Namespaces | 25 |
+
+**GitOps**
+
+- `homelab-root` is an app-of-apps: 31 child `Application` resources
+- Source: `git@github.com:Riotpiaole/riotpiao.homelab.com.git`, path `k8s/argocd/apps`
+- Sync waves **0 → 8** already annotated across apps
+- ~550 managed resources total (largest: `prometheus` 68, `cert-manager` 47, `kong` 39)
+
+**LLM serving** (`llm-serving`, KServe, all 5 `InferenceService` Ready)
+
+| Model | Notes |
+|---|---|
+| `reasoning` | `unsloth/DeepSeek-R1-Distill-Qwen-32B-bnb-4bit`, vLLM `v0.11.0` |
+| `ornith`, `embeddings`, `reranker`, `verifier` | 1 replica each |
+
+`reasoning` runtime args, verbatim: `--max-num-seqs=4`, `--max-model-len=16384`, `--gpu-memory-utilization=0.90`, `--enable-prefix-caching`, `--reasoning-parser=deepseek_r1`. `minReplicas: 2`, `maxReplicas: 2`, pinned to `worker-1`.
+
+**Existing building blocks**
+
+- Prometheus (kube-prometheus-stack) + kube-state-metrics + node-exporter + blackbox + Alertmanager — `monitoring`
+- Loki + promtail + Grafana — `logging`
+- Kong 3.9 + Kubernetes Ingress Controller 3.5 — `api`, 2 replicas
+- Redis (`kmsvc-redis-master.sqs.svc.cluster.local:6379`), 1 master + 3 replicas
+- Next.js 15.5 / React 19.2 portfolio source in this repo (not deployed)
+
+**Public exposure** (verified by DNS + HTTP probe)
+
+```
+api.riotpiao.com NXDOMAIN
+argocd|grafana|vault|longhorn|prometheus|minio|temporal|forgejo|portainer.riotpiao.com
+ NXDOMAIN
+riotpiao.com 172.67.196.33 / 104.21.60.115 (Cloudflare) → HTTP 403 at edge
+```
+
+Nothing in the cluster is currently reachable from the public internet. The Cloudflare tunnel has no public hostnames wired (cloudflared auto-creates a CNAME per public hostname; no CNAME exists).
+
+### Requirements
+
+1. Public, anonymous, interactive visualization of live cluster state
+2. Live Argo CD delivery pipeline view, ordered by sync wave
+3. Read-only browser terminal for cluster queries
+4. Streaming chat against the `reasoning` model, ChatGPT-style
+5. No internal service becomes publicly reachable as a side effect
+6. No fabricated statistics anywhere on the site
+
+### Constraints
+
+- **Hard capacity ceiling: 8 concurrent LLM sequences** (`--max-num-seqs=4` × 2 replicas). Single GPU. Not horizontally scalable without more hardware.
+- **Context ceiling: 16384 tokens** (`--max-model-len`)
+- Single GPU node — `worker-1` is a single point of failure for all inference
+- Solo operator, part-time
+- Cluster is GitOps-managed; every change ships through git → Argo CD (per project hard rules)
+- No test framework currently installed in the portfolio repo
+
+### Forces
+
+- **Impressiveness vs. attack surface** — the most impressive surfaces (terminal, chat) are the most dangerous
+- **Live data vs. information disclosure** — real cluster state is the whole point, and real cluster state is exactly what an attacker wants for reconnaissance
+- **Anonymous access vs. abuse** — requiring login kills the portfolio demo; not requiring it exposes 8 GPU slots to the open internet
+- **Four surfaces vs. one operator** — four independently-built backends is four times the security review
+
+---
+
+## Decision
+
+**We will build one read-only aggregator service, `atlas`, that is the sole public entry point to all cluster data, serving four presentation surfaces from one shared in-memory snapshot.**
+
+### Architecture
+
+```
+kube API (informers) ─┐
+Prometheus /api/v1 ├──> atlas (Go, ns: portfolio, read-only ServiceAccount)
+Argo CD Application CRs┘ │
+ ├─ snapshot: in-memory, redacted at write time
+ ├─ Redis pub/sub (kmsvc-redis) — cross-replica fanout
+ │
+ └─ HTTP surfaces
+ GET /api/topology + /api/stream (B: cluster topology)
+ GET /api/delivery + /api/stream (E: Argo CD tree)
+ POST /api/exec (C: terminal)
+ POST /api/chat (D: chat) ──> reasoning-predictor.llm-serving
+```
+
+### Core invariants
+
+These are the load-bearing decisions. Everything else is implementation detail.
+
+**I1 — One public hostname, forever.**
+`riotpiao.com` is the only name that ever gets a public DNS record. `argocd`, `grafana`, `vault`, `longhorn`, `prometheus`, `minio`, `temporal`, `forgejo`, `portainer` stay NXDOMAIN permanently. Every new public record is a new thing to defend, and `atlas` proxying makes all of them unnecessary.
+
+**I2 — The browser never talks to an internal API.**
+No kube API, no Prometheus, no Argo CD API, no vLLM endpoint is reachable from a browser. `atlas` is the only origin. One choke point for rate limiting, redaction, and audit.
+
+**I3 — Redaction is an allowlist, never a denylist.**
+Fields are serialized by explicit construction into DTO structs. A new field appearing in an upstream CRD cannot leak by default, because nothing copies it.
+
+**I4 — No free-form string ever reaches an internal system.**
+The terminal parses to a closed command enum. Resource names are validated by **membership in the current snapshot**, not by regex. The chat model reads a pre-built snapshot digest and has no tool-calling ability.
+
+**I5 — Global GPU concurrency is capped below physical capacity.**
+Hard semaphore at **6** concurrent chat streams, leaving 2 of 8 sequence slots as operator headroom. Client disconnect cancels the upstream vLLM request immediately.
+
+### Technology
+
+| Component | Choice | Rationale |
+|---|---|---|
+| Aggregator | Go, `client-go` informers | Watch-based, not poll-per-request; N visitors ≠ N API calls |
+| Fanout | Redis pub/sub (existing `kmsvc-redis`) | Multi-replica `atlas` shares one snapshot stream; no new infrastructure |
+| Transport | SSE | Unidirectional server→client fits every surface, including LLM token streaming |
+| Topology + delivery graph | React Flow | Both are graphs; one library, one mental model |
+| Resource drill-down | `react-arborist` | Virtualized; the 68-resource apps must not jank |
+| Edge protection | Cloudflare WAF + Turnstile | Free; stops scripted abuse before it costs a packet |
+| Gateway limits | Kong `rate-limiting`, `policy: redis` | Cluster-wide counters, not per-pod; Kong 3.9 OSS ships it |
+
+### Implementation strategy — phased, in dependency order
+
+| Phase | Deliverable | Why this position |
+|---|---|---|
+| 0 | Unblock deployment | Nothing is visible until this lands |
+| 1 | `atlas` core: RBAC, informers, redaction | Every surface depends on it |
+| 2 | Surface B — cluster topology | Proves the snapshot + SSE pipeline end to end |
+| 3 | Surface E — Argo CD delivery tree | Zero new data sources, zero new attack surface, highest signal |
+| 4 | Surface C — read-only terminal | First surface accepting user input |
+| 5 | Surface D — chat + full rate limiter | Highest risk, highest cost; ships last, ships with its limiter |
+
+Surface E precedes C and D deliberately: it reuses Phase 1 data wholesale and is the surface that reads as platform engineering rather than hobby.
+
+**Timeline**: ~3 weeks part-time. **Responsibility**: solo.
+
+---
+
+## Consequences
+
+### Positive
+
+- Fabricated portfolio statistics replaced by live, verifiable data
+- One service to secure, rate-limit, audit, and operate instead of four
+- Sync-wave DAG makes a real dependency-ordering decision legible to a visitor in seconds
+- Informer-based design means visitor traffic does not load the kube API
+- Invariant I1 leaves the cluster's public footprint at exactly one hostname
+- Existing `InteractiveTerminal.tsx` and `LiveIndicator.tsx` get real backing
+
+### Negative
+
+- New production service to build, secure, and maintain — currently zero
+- `atlas` becomes a high-value target: it holds cluster-wide read access by design
+- 8-slot GPU ceiling means chat will queue under real traffic; a "please wait" queue is a worse first impression than no chat at all
+- Public chat on a single GPU node has a genuine cost/abuse tail even behind three tiers of limiting
+- Redaction is permanent maintenance: every new field surfaced is a new disclosure review
+- Test framework must be added to the repo before any of this can be built TDD-first
+
+### Neutral
+
+- Grafana remains for operator use; `atlas` is presentation-only and never replaces it
+- Argo CD API is deliberately not used in v1 — `Application` CRs are read via the same informer, so no Argo CD token is ever minted
+- `worker-1` remains a single point of failure; this ADR does not change that, only exposes it
+
+---
+
+## Alternatives Considered
+
+### Alternative 1: Grafana dashboards + public iframe embeds
+
+**Description**: Build dashboards on existing data, expose a read-only Grafana org, embed in the portfolio.
+
+**Pros**
+- Approximately one day of work
+- Zero new services, zero new code, zero new attack surface of our own making
+- Data already flows
+
+**Cons**
+- Grafana's design, not the portfolio's — reads as a screenshot, not a product
+- Requires making Grafana publicly reachable, violating invariant I1
+- Iframes leak internal metric names, job labels, and namespace structure with no redaction layer available
+- No path to the terminal or chat surfaces
+
+**Why not chosen**: The one-day cost is real, but it forces a second public hostname and surrenders all control over what is disclosed. Grafana has no allowlist redaction model. Kept as the fallback if Phase 1 proves too expensive.
+
+### Alternative 2: Four independent backends, one per surface
+
+**Description**: Separate services for topology, delivery, terminal, and chat.
+
+**Pros**
+- Blast radius isolation — a terminal compromise does not reach the chat service
+- Independent scaling and deployment
+- Aligns with the microservices instinct
+
+**Cons**
+- Four RBAC policies, four redaction layers, four rate limiters, four security reviews
+- Four independent informer sets hammering the kube API for the same data
+- Solo operator; four services will not receive equal maintenance attention
+- Cross-surface consistency (terminal and topology disagreeing about pod state) becomes a real bug class
+
+**Why not chosen**: Blast-radius isolation is genuine, but every surface needs the *same* read-only snapshot. Duplicating the highest-risk component — cluster-wide read access — four times increases total exposure rather than reducing it. Rejected on the specific ground that the shared component is the dangerous one.
+
+### Alternative 3: Static snapshot generated at build time
+
+**Description**: CI job dumps cluster state to JSON at build; site renders it statically. No runtime cluster access at all.
+
+**Pros**
+- Zero runtime attack surface — no live credentials anywhere near the public internet
+- Trivially cacheable, effectively free to serve, cannot be DoS'd
+- No rate limiting needed
+
+**Cons**
+- Not live; "interactive" degrades to "pre-rendered"
+- Kills the terminal and chat surfaces entirely
+- The sync-wave cascade animation — the single best demo moment — is impossible
+- Data staleness makes the fabricated-statistics problem better but not solved
+
+**Why not chosen**: Fails requirements 1, 3, and 4. Worth revisiting for the topology surface alone if runtime cost becomes a problem.
+
+### Alternative 4: Authentik-gated access to all surfaces
+
+**Description**: Put the existing Authentik SSO in front of the whole visualization.
+
+**Pros**
+- Abuse problem largely disappears; rate limiting becomes a formality
+- Authentik is already deployed and working
+- Redaction requirements relax substantially for authenticated viewers
+
+**Cons**
+- Nobody creates an account to look at a stranger's homelab — the demo dies
+- Defeats the entire purpose of a public portfolio
+- Still requires a public Authentik hostname, violating I1
+
+**Why not chosen**: Directly contradicts requirement 1. Anonymous access plus Cloudflare Turnstile achieves most of the abuse resistance without the conversion cliff. Reconsider only if abuse proves unmanageable in production.
+
+---
+
+## References
+
+- Cluster state verified 2026-08-13 via `kubectl` against context `admin@homelab-cluster`
+- Public exposure verified 2026-08-13 via `dig` + `curl` against `riotpiao.com` and subdomains
+- vLLM engine args: `kubectl get inferenceservice reasoning -n llm-serving -o jsonpath='{.spec}'`
+- Superseded: [PLAN.md](../../PLAN.md), [IMPLEMENTATION.md](../../IMPLEMENTATION.md)
+- Companion implementation plan: [PLAN-atlas.md](../PLAN-atlas.md)
+
+---
+
+## Review Notes (Before Acceptance)
+
+**Open questions requiring an answer before Phase 1**
+
+1. **Two GitOps roots exist.** `homelab-root` reads `git@github.com:Riotpiaole/riotpiao.homelab.com.git`. This repo's `infra/argocd-apps.yaml` points at `forgejo.riotpiao.homelab.com` — a hostname that does not resolve — and its `portfolio` and `auth-infra` Applications **do not exist in the cluster**. Which repository is authoritative for the portfolio?
+2. **Apex returns 403 from the Cloudflare edge.** Is this an absent tunnel public-hostname route, a WAF rule, or a proxied record with no origin? The portfolio cannot ship until this is understood.
+3. Is `homarr` still wanted? It is deployed and healthy, but the plan it came from is abandoned.
+4. Does the chat surface stay in scope given the 8-slot ceiling, or ship topology + delivery + terminal first and treat chat as a separate decision?
+
+**Approval**
+
+- [ ] Architecture — invariants I1–I5 accepted
+- [ ] Security — redaction allowlist and rate-limit tiers accepted
+- [ ] Scope — four surfaces vs. three
diff --git a/infra/argocd-apps.yaml b/infra/argocd-apps.yaml
new file mode 100644
index 0000000..84cc553
--- /dev/null
+++ b/infra/argocd-apps.yaml
@@ -0,0 +1,59 @@
+apiVersion: argoproj.io/v1alpha1
+kind: Application
+metadata:
+ name: portfolio
+ namespace: argocd
+spec:
+ project: default
+ source:
+ repoURL: https://forgejo.riotpiao.homelab.com/rock/riotpiao.git
+ targetRevision: main
+ path: infra/portfolio/base
+ destination:
+ server: https://kubernetes.default.svc
+ namespace: portfolio
+ syncPolicy:
+ automated:
+ prune: true
+ selfHeal: true
+ syncOptions:
+ - CreateNamespace=true
+---
+apiVersion: argoproj.io/v1alpha1
+kind: Application
+metadata:
+ name: homarr
+ namespace: argocd
+spec:
+ project: default
+ source:
+ repoURL: https://forgejo.riotpiao.homelab.com/rock/riotpiao.git
+ targetRevision: main
+ path: infra/homarr/base
+ destination:
+ server: https://kubernetes.default.svc
+ namespace: dashboard
+ syncPolicy:
+ automated:
+ prune: true
+ selfHeal: true
+ syncOptions:
+ - CreateNamespace=true
+---
+apiVersion: argoproj.io/v1alpha1
+kind: Application
+metadata:
+ name: auth-infra
+ namespace: argocd
+spec:
+ project: default
+ source:
+ repoURL: https://forgejo.riotpiao.homelab.com/rock/riotpiao.git
+ targetRevision: main
+ path: infra/auth-infra/base
+ destination:
+ server: https://kubernetes.default.svc
+ syncPolicy:
+ automated:
+ prune: true
+ selfHeal: true
diff --git a/infra/auth-infra/base/ingress-protected.yaml b/infra/auth-infra/base/ingress-protected.yaml
new file mode 100644
index 0000000..6db9605
--- /dev/null
+++ b/infra/auth-infra/base/ingress-protected.yaml
@@ -0,0 +1,83 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: longhorn-protected
+ namespace: longhorn-system
+ annotations:
+ nginx.ingress.kubernetes.io/auth-url: http://authentik-server.iam.svc.cluster.local/outpost.goauthentik.io/auth/nginx
+ nginx.ingress.kubernetes.io/auth-signin: https://authentik.riotpiao.homelab.com/outpost.goauthentik.io/start?rd=$scheme://$http_host$escaped_request_uri
+ nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - longhorn.riotpiao.homelab.com
+ secretName: longhorn-tls
+ rules:
+ - host: longhorn.riotpiao.homelab.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: longhorn-frontend
+ port:
+ number: 80
+---
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: portainer-protected
+ namespace: dashboard
+ annotations:
+ nginx.ingress.kubernetes.io/auth-url: http://authentik-server.iam.svc.cluster.local/outpost.goauthentik.io/auth/nginx
+ nginx.ingress.kubernetes.io/auth-signin: https://authentik.riotpiao.homelab.com/outpost.goauthentik.io/start?rd=$scheme://$http_host$escaped_request_uri
+ nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - portainer.riotpiao.homelab.com
+ secretName: portainer-tls
+ rules:
+ - host: portainer.riotpiao.homelab.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: portainer
+ port:
+ number: 9000
+---
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: prometheus-protected
+ namespace: monitoring
+ annotations:
+ nginx.ingress.kubernetes.io/auth-url: http://authentik-server.iam.svc.cluster.local/outpost.goauthentik.io/auth/nginx
+ nginx.ingress.kubernetes.io/auth-signin: https://authentik.riotpiao.homelab.com/outpost.goauthentik.io/start?rd=$scheme://$http_host$escaped_request_uri
+ nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - prometheus.riotpiao.homelab.com
+ secretName: prometheus-tls
+ rules:
+ - host: prometheus.riotpiao.homelab.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: prometheus-operated
+ port:
+ number: 9090
diff --git a/infra/auth-infra/base/kustomization.yaml b/infra/auth-infra/base/kustomization.yaml
new file mode 100644
index 0000000..c01543a
--- /dev/null
+++ b/infra/auth-infra/base/kustomization.yaml
@@ -0,0 +1,5 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+- ingress-protected.yaml
+- networkpolicy.yaml
diff --git a/infra/auth-infra/base/networkpolicy.yaml b/infra/auth-infra/base/networkpolicy.yaml
new file mode 100644
index 0000000..3bcb4c9
--- /dev/null
+++ b/infra/auth-infra/base/networkpolicy.yaml
@@ -0,0 +1,50 @@
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: longhorn-ingress-only
+ namespace: longhorn-system
+spec:
+ podSelector:
+ matchLabels:
+ app.kubernetes.io/name: longhorn
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ name: ingress-nginx
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: portainer-ingress-only
+ namespace: dashboard
+spec:
+ podSelector:
+ matchLabels:
+ app: portainer
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ name: ingress-nginx
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: prometheus-ingress-only
+ namespace: monitoring
+spec:
+ podSelector:
+ matchLabels:
+ app.kubernetes.io/name: prometheus
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ name: ingress-nginx
diff --git a/infra/homarr/base/helmrelease.yaml b/infra/homarr/base/helmrelease.yaml
new file mode 100644
index 0000000..1fc6aa1
--- /dev/null
+++ b/infra/homarr/base/helmrelease.yaml
@@ -0,0 +1,24 @@
+apiVersion: helm.cattle.io/v1
+kind: HelmRelease
+metadata:
+ name: homarr
+ namespace: dashboard
+spec:
+ chart:
+ repository: https://homarr-labs.github.io/charts/
+ name: homarr
+ version: "~1"
+ values:
+ env:
+ AUTH_PROVIDERS: "oidc"
+ AUTH_OIDC_CLIENT_ID: "homarr"
+ AUTH_OIDC_ISSUER: "https://authentik.riotpiao.homelab.com/application/o/homarr/"
+ AUTH_OIDC_URI: "https://authentik.riotpiao.homelab.com/application/o/homarr/.well-known/openid-configuration"
+ AUTH_OIDC_GROUPS_ATTRIBUTE: "groups"
+ envFrom:
+ - secretRef:
+ name: homarr-oidc
+ persistence:
+ enabled: true
+ storageClass: longhorn
+ size: 2Gi
diff --git a/infra/homarr/base/ingress.yaml b/infra/homarr/base/ingress.yaml
new file mode 100644
index 0000000..810f339
--- /dev/null
+++ b/infra/homarr/base/ingress.yaml
@@ -0,0 +1,24 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: homarr
+ namespace: dashboard
+ annotations:
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - homarr.riotpiao.homelab.com
+ secretName: homarr-tls
+ rules:
+ - host: homarr.riotpiao.homelab.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: homarr
+ port:
+ number: 3000
diff --git a/infra/homarr/base/kustomization.yaml b/infra/homarr/base/kustomization.yaml
new file mode 100644
index 0000000..735de35
--- /dev/null
+++ b/infra/homarr/base/kustomization.yaml
@@ -0,0 +1,8 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: dashboard
+resources:
+- namespace.yaml
+- secret.yaml
+- helmrelease.yaml
+- ingress.yaml
diff --git a/infra/homarr/base/namespace.yaml b/infra/homarr/base/namespace.yaml
new file mode 100644
index 0000000..4e352cc
--- /dev/null
+++ b/infra/homarr/base/namespace.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: dashboard
+ labels:
+ app.kubernetes.io/name: homarr
+ managed-by: argocd
diff --git a/infra/homarr/base/secret.yaml b/infra/homarr/base/secret.yaml
new file mode 100644
index 0000000..6d2b36f
--- /dev/null
+++ b/infra/homarr/base/secret.yaml
@@ -0,0 +1,8 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: homarr-oidc
+ namespace: dashboard
+type: Opaque
+stringData:
+ AUTH_OIDC_CLIENT_SECRET: "PLACEHOLDER_CHANGE_ME"
diff --git a/infra/kustomization.yaml b/infra/kustomization.yaml
new file mode 100644
index 0000000..fdbe03c
--- /dev/null
+++ b/infra/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+- portfolio/base
+- homarr/base
+- auth-infra/base
diff --git a/infra/portfolio/base/deployment.yaml b/infra/portfolio/base/deployment.yaml
new file mode 100644
index 0000000..96e1cd1
--- /dev/null
+++ b/infra/portfolio/base/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: portfolio
+ namespace: portfolio
+ labels:
+ app.kubernetes.io/name: portfolio
+ app.kubernetes.io/component: web
+spec:
+ replicas: 2
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: portfolio
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: portfolio
+ spec:
+ containers:
+ - name: portfolio
+ image: forgejo.riotpiao.homelab.com/rock/portfolio:latest
+ imagePullPolicy: IfNotPresent
+ ports:
+ - name: http
+ containerPort: 3000
+ protocol: TCP
+ livenessProbe:
+ httpGet:
+ path: /
+ port: http
+ initialDelaySeconds: 10
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 3
+ readinessProbe:
+ httpGet:
+ path: /
+ port: http
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ timeoutSeconds: 3
+ failureThreshold: 2
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
diff --git a/infra/portfolio/base/ingress.yaml b/infra/portfolio/base/ingress.yaml
new file mode 100644
index 0000000..1420c1b
--- /dev/null
+++ b/infra/portfolio/base/ingress.yaml
@@ -0,0 +1,24 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: portfolio
+ namespace: portfolio
+ annotations:
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - portfolio.riotpiao.homelab.com
+ secretName: portfolio-tls
+ rules:
+ - host: portfolio.riotpiao.homelab.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: portfolio
+ port:
+ number: 3000
diff --git a/infra/portfolio/base/kustomization.yaml b/infra/portfolio/base/kustomization.yaml
new file mode 100644
index 0000000..99d0a86
--- /dev/null
+++ b/infra/portfolio/base/kustomization.yaml
@@ -0,0 +1,8 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: portfolio
+resources:
+- namespace.yaml
+- deployment.yaml
+- service.yaml
+- ingress.yaml
diff --git a/infra/portfolio/base/namespace.yaml b/infra/portfolio/base/namespace.yaml
new file mode 100644
index 0000000..e8f0d86
--- /dev/null
+++ b/infra/portfolio/base/namespace.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: portfolio
+ labels:
+ app.kubernetes.io/name: portfolio
+ managed-by: argocd
diff --git a/infra/portfolio/base/service.yaml b/infra/portfolio/base/service.yaml
new file mode 100644
index 0000000..8b89d55
--- /dev/null
+++ b/infra/portfolio/base/service.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: portfolio
+ namespace: portfolio
+ labels:
+ app.kubernetes.io/name: portfolio
+spec:
+ type: ClusterIP
+ ports:
+ - port: 3000
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app.kubernetes.io/name: portfolio
diff --git a/lib/clusterMock.ts b/lib/clusterMock.ts
new file mode 100644
index 0000000..10704d9
--- /dev/null
+++ b/lib/clusterMock.ts
@@ -0,0 +1,183 @@
+/**
+ * Layout placeholder fixtures.
+ *
+ * Shapes mirror the `atlas` DTOs described in docs/PLAN-atlas.md, and the values
+ * are transcribed from the real cluster so the layout is sized against real
+ * cardinality (32 apps, 9 sync waves, ~550 resources).
+ *
+ * Redaction rules from the plan are already applied here: no node IPs, no pod
+ * IPs, no container args, no image tags, no repo URLs, no Secret names.
+ */
+
+export type Health = 'healthy' | 'degraded' | 'progressing'
+export type Sync = 'synced' | 'outofsync'
+
+export const cluster = {
+ distro: 'Talos v1.13.3',
+ kubernetes: 'v1.36.1',
+ snapshotAge: 2.1,
+ generation: 88412,
+} as const
+
+export type Node = {
+ name: string
+ role: string
+ cpu: number
+ memoryGi: number
+ gpu: number
+ pods: number
+ health: Health
+}
+
+export const nodes: Node[] = [
+ { name: 'talos-cp-1', role: 'control-plane', cpu: 8, memoryGi: 16, gpu: 0, pods: 24, health: 'healthy' },
+ { name: 'talos-cp-2', role: 'control-plane', cpu: 8, memoryGi: 16, gpu: 0, pods: 31, health: 'healthy' },
+ { name: 'talos-cp-3', role: 'control-plane', cpu: 8, memoryGi: 16, gpu: 0, pods: 28, health: 'healthy' },
+ { name: 'worker-1', role: 'gpu-node', cpu: 96, memoryGi: 62, gpu: 1, pods: 55, health: 'healthy' },
+]
+
+export type Namespace = {
+ name: string
+ running: number
+ total: number
+}
+
+export const namespaces: Namespace[] = [
+ { name: 'kube-system', running: 21, total: 21 },
+ { name: 'longhorn-system', running: 30, total: 31 },
+ { name: 'sqs', running: 13, total: 19 },
+ { name: 'logging', running: 12, total: 12 },
+ { name: 'monitoring', running: 9, total: 11 },
+ { name: 'temporal', running: 9, total: 10 },
+ { name: 'llm-serving', running: 6, total: 6 },
+ { name: 'iam', running: 6, total: 6 },
+ { name: 'cicd', running: 6, total: 6 },
+ { name: 'argocd', running: 6, total: 8 },
+ { name: 'ingress-nginx', running: 4, total: 4 },
+ { name: 'cert-manager', running: 3, total: 6 },
+ { name: 'api', running: 2, total: 2 },
+ { name: 'storage', running: 2, total: 2 },
+ { name: 'dashboard', running: 2, total: 2 },
+ { name: 'cloudflared', running: 2, total: 2 },
+ { name: 'cnpg-system', running: 1, total: 2 },
+ { name: 'gpu-system', running: 1, total: 1 },
+ { name: 'kserve', running: 1, total: 1 },
+ { name: 'reloader', running: 1, total: 1 },
+ { name: 'sms', running: 0, total: 1 },
+]
+
+export type Model = {
+ name: string
+ replicas: number
+ seqPerReplica: number
+ contextTokens: number
+ ready: boolean
+}
+
+/** Model identifiers and quantization strategy are deliberately not surfaced. */
+export const models: Model[] = [
+ { name: 'reasoning', replicas: 2, seqPerReplica: 4, contextTokens: 16384, ready: true },
+ { name: 'ornith', replicas: 1, seqPerReplica: 4, contextTokens: 16384, ready: true },
+ { name: 'embeddings', replicas: 1, seqPerReplica: 8, contextTokens: 8192, ready: true },
+ { name: 'reranker', replicas: 1, seqPerReplica: 8, contextTokens: 8192, ready: true },
+ { name: 'verifier', replicas: 1, seqPerReplica: 4, contextTokens: 16384, ready: true },
+]
+
+/** `--max-num-seqs=4` x `minReplicas: 2`. The number the whole design is sized against. */
+export const SEQUENCE_SLOTS = 8
+/** Operator headroom: 2 of 8 slots never handed to visitors. */
+export const PUBLIC_SLOT_CAP = 6
+
+export type App = {
+ name: string
+ wave: number | null
+ sync: Sync
+ health: Health
+ resources: number
+}
+
+export const apps: App[] = [
+ { name: 'homelab-root', wave: null, sync: 'synced', health: 'healthy', resources: 31 },
+
+ { name: 'cert-manager', wave: 0, sync: 'synced', health: 'healthy', resources: 47 },
+ { name: 'prometheus-crds', wave: 0, sync: 'synced', health: 'healthy', resources: 10 },
+ { name: 'reloader', wave: 0, sync: 'synced', health: 'healthy', resources: 6 },
+ { name: 'sops-secrets', wave: 0, sync: 'synced', health: 'healthy', resources: 16 },
+
+ { name: 'prometheus', wave: 1, sync: 'synced', health: 'healthy', resources: 68 },
+ { name: 'blackbox-exporter', wave: 1, sync: 'synced', health: 'healthy', resources: 17 },
+ { name: 'ingress-config', wave: 1, sync: 'synced', health: 'healthy', resources: 14 },
+ { name: 'longhorn-config', wave: 1, sync: 'outofsync', health: 'healthy', resources: 12 },
+ { name: 'minio-operator', wave: 1, sync: 'synced', health: 'healthy', resources: 9 },
+ { name: 'cert-manager-issuers', wave: 1, sync: 'synced', health: 'healthy', resources: 7 },
+ { name: 'minio-tenant', wave: 1, sync: 'synced', health: 'healthy', resources: 1 },
+
+ { name: 'monitoring-config', wave: 2, sync: 'synced', health: 'healthy', resources: 24 },
+ { name: 'loki', wave: 2, sync: 'synced', health: 'healthy', resources: 16 },
+ { name: 'grafana', wave: 2, sync: 'synced', health: 'healthy', resources: 11 },
+ { name: 'databases', wave: 2, sync: 'synced', health: 'healthy', resources: 5 },
+ { name: 'promtail', wave: 2, sync: 'synced', health: 'healthy', resources: 5 },
+
+ { name: 'authentik', wave: 3, sync: 'synced', health: 'healthy', resources: 13 },
+ { name: 'iam-jobs', wave: 3, sync: 'synced', health: 'healthy', resources: 9 },
+ { name: 'vault', wave: 3, sync: 'synced', health: 'healthy', resources: 8 },
+ { name: 'forgejo-runner', wave: 3, sync: 'synced', health: 'healthy', resources: 4 },
+
+ { name: 'strimzi-operator', wave: 5, sync: 'synced', health: 'healthy', resources: 27 },
+ { name: 'kmsvc-redis', wave: 5, sync: 'synced', health: 'healthy', resources: 13 },
+
+ { name: 'queue-crd', wave: 6, sync: 'synced', health: 'healthy', resources: 6 },
+ { name: 'kafka-cluster', wave: 6, sync: 'synced', health: 'healthy', resources: 2 },
+
+ { name: 'kong', wave: 7, sync: 'synced', health: 'healthy', resources: 39 },
+ { name: 'management-service', wave: 7, sync: 'synced', health: 'healthy', resources: 6 },
+
+ { name: 'temporal', wave: 8, sync: 'synced', health: 'healthy', resources: 16 },
+ { name: 'sms', wave: 8, sync: 'synced', health: 'degraded', resources: 7 },
+ { name: 'portainer', wave: 8, sync: 'synced', health: 'healthy', resources: 5 },
+ { name: 'homarr', wave: 8, sync: 'synced', health: 'healthy', resources: 3 },
+ { name: 'cloudflared', wave: 8, sync: 'synced', health: 'healthy', resources: 1 },
+]
+
+export const WAVES = [0, 1, 2, 3, 4, 5, 6, 7, 8]
+
+export function appsInWave(wave: number): App[] {
+ return apps.filter((a) => a.wave === wave)
+}
+
+/** Resource kinds for the drill-down panel. Secrets are counted, never named. */
+export const resourceKinds: Record> = {
+ prometheus: [
+ { kind: 'PrometheusRule', count: 24, named: true },
+ { kind: 'ServiceMonitor', count: 18, named: true },
+ { kind: 'Service', count: 9, named: true },
+ { kind: 'ConfigMap', count: 6, named: true },
+ { kind: 'Deployment', count: 4, named: true },
+ { kind: 'ClusterRole', count: 4, named: true },
+ { kind: 'Secret', count: 3, named: false },
+ ],
+ kong: [
+ { kind: 'CustomResourceDefinition', count: 14, named: true },
+ { kind: 'ClusterRole', count: 8, named: true },
+ { kind: 'Service', count: 5, named: true },
+ { kind: 'KongPlugin', count: 5, named: true },
+ { kind: 'Ingress', count: 4, named: true },
+ { kind: 'Secret', count: 3, named: false },
+ ],
+ 'cert-manager': [
+ { kind: 'CustomResourceDefinition', count: 12, named: true },
+ { kind: 'ClusterRole', count: 11, named: true },
+ { kind: 'ClusterRoleBinding', count: 9, named: true },
+ { kind: 'ServiceAccount', count: 6, named: true },
+ { kind: 'Deployment', count: 3, named: true },
+ { kind: 'Service', count: 3, named: true },
+ { kind: 'ValidatingWebhookConfiguration', count: 3, named: true },
+ ],
+}
+
+export const DEFAULT_KINDS = [
+ { kind: 'Service', count: 3, named: true },
+ { kind: 'Deployment', count: 2, named: true },
+ { kind: 'ConfigMap', count: 2, named: true },
+ { kind: 'Secret', count: 1, named: false },
+]
diff --git a/lib/motion.ts b/lib/motion.ts
new file mode 100644
index 0000000..48e5b76
--- /dev/null
+++ b/lib/motion.ts
@@ -0,0 +1,65 @@
+export const DURATION = {
+ fast: 0.15,
+ standard: 0.3,
+ reveal: 0.5,
+ slow: 0.8,
+}
+
+export const EASING = {
+ ease: [0.25, 0.46, 0.45, 0.94],
+ easeOut: [0.33, 1, 0.68, 1],
+}
+
+export const VARIANTS = {
+ // Scroll reveal: fade + slight upward translate
+ reveal: {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: DURATION.reveal, ease: EASING.easeOut },
+ },
+ },
+
+ // Hover lift: card elevation on hover
+ cardHover: {
+ rest: { y: 0 },
+ hover: {
+ y: -8,
+ transition: { duration: DURATION.fast },
+ },
+ },
+
+ // Stagger container for card grids
+ container: {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.1,
+ },
+ },
+ },
+
+ // Child item for stagger
+ item: {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: DURATION.standard },
+ },
+ },
+
+ // Pulse: live indicator dot
+ pulse: {
+ scale: [1, 1.2, 1],
+ opacity: [0.6, 1, 0.6],
+ transition: {
+ duration: 2,
+ repeat: Infinity,
+ ease: 'easeInOut',
+ },
+ },
+}
diff --git a/next-env.d.ts b/next-env.d.ts
new file mode 100644
index 0000000..830fb59
--- /dev/null
+++ b/next-env.d.ts
@@ -0,0 +1,6 @@
+///
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/next.config.js b/next.config.js
new file mode 100644
index 0000000..b408897
--- /dev/null
+++ b/next.config.js
@@ -0,0 +1,6 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ output: 'standalone',
+};
+
+module.exports = nextConfig;
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6964471
--- /dev/null
+++ b/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "riotpiao",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "eslint . --ext .ts,.tsx"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "framer-motion": "^11.0.0",
+ "lucide-react": "^0.344.0",
+ "next": "^15.5.20",
+ "react": "^19.2.7",
+ "react-dom": "^19.2.7",
+ "tailwindcss": "^3.4.0"
+ },
+ "devDependencies": {
+ "@types/node": "20.17.6",
+ "@types/react": "19.2.17",
+ "@typescript-eslint/eslint-plugin": "^8.64.0",
+ "@typescript-eslint/parser": "^8.64.0",
+ "autoprefixer": "^10.4.16",
+ "eslint": "^8.57.1",
+ "eslint-config-next": "^16.2.10",
+ "postcss": "^8.4.32",
+ "typescript": "5.8.2"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..48d8390
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,4247 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ framer-motion:
+ specifier: ^11.0.0
+ version: 11.18.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ lucide-react:
+ specifier: ^0.344.0
+ version: 0.344.0(react@19.2.7)
+ next:
+ specifier: ^15.5.20
+ version: 15.5.20(@babel/core@7.29.7)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ react:
+ specifier: ^19.2.7
+ version: 19.2.7
+ react-dom:
+ specifier: ^19.2.7
+ version: 19.2.7(react@19.2.7)
+ tailwindcss:
+ specifier: ^3.4.0
+ version: 3.4.19
+ devDependencies:
+ '@types/node':
+ specifier: 20.17.6
+ version: 20.17.6
+ '@types/react':
+ specifier: 19.2.17
+ version: 19.2.17
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^8.64.0
+ version: 8.64.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)
+ '@typescript-eslint/parser':
+ specifier: ^8.64.0
+ version: 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ autoprefixer:
+ specifier: ^10.4.16
+ version: 10.5.4(postcss@8.5.19)
+ eslint:
+ specifier: ^8.57.1
+ version: 8.57.1
+ eslint-config-next:
+ specifier: ^16.2.10
+ version: 16.2.10(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)
+ postcss:
+ specifier: ^8.4.32
+ version: 8.5.19
+ typescript:
+ specifier: 5.8.2
+ version: 5.8.2
+
+packages:
+
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ '@babel/code-frame@7.29.7':
+ resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/compat-data@7.29.7':
+ resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.29.7':
+ resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.29.7':
+ resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.29.7':
+ resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-globals@7.29.7':
+ resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.29.7':
+ resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.29.7':
+ resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-string-parser@7.29.7':
+ resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.29.7':
+ resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-option@7.29.7':
+ resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.29.7':
+ resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.7':
+ resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/template@7.29.7':
+ resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.29.7':
+ resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.29.7':
+ resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
+ engines: {node: '>=6.9.0'}
+
+ '@emnapi/core@1.10.0':
+ resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
+
+ '@emnapi/runtime@1.10.0':
+ resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
+
+ '@emnapi/runtime@1.11.2':
+ resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==}
+
+ '@emnapi/wasi-threads@1.2.1':
+ resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
+
+ '@eslint-community/eslint-utils@4.9.1':
+ resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+ '@eslint-community/regexpp@4.12.2':
+ resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ '@eslint/eslintrc@2.1.4':
+ resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ '@eslint/js@8.57.1':
+ resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ '@humanwhocodes/config-array@0.13.0':
+ resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
+ engines: {node: '>=10.10.0'}
+ deprecated: Use @eslint/config-array instead
+
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/object-schema@2.0.3':
+ resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
+ deprecated: Use @eslint/object-schema instead
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@napi-rs/wasm-runtime@1.1.6':
+ resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1
+ '@emnapi/runtime': ^1.7.1
+
+ '@next/env@15.5.20':
+ resolution: {integrity: sha512-dXh51Wvddf8daEyBXryZZEe1FdVxEWx9lgaTseLZUtC1XP/W8Wri+Z+VPOElHlByk23CyqHdc2oVByX7wsTWsw==}
+
+ '@next/eslint-plugin-next@16.2.10':
+ resolution: {integrity: sha512-Gs8D2m21VnJeFo9qvYIIqJH94frWerWYu41BprU1pLtRVF7PCQNLiFZZ3fG+iPuj3K83Cwv/rt+msLOy8Qgu3Q==}
+
+ '@next/swc-darwin-arm64@15.5.20':
+ resolution: {integrity: sha512-in0yXG7/pRBVjWeEl7f7ZZETpletSMFKXVS4GJgHENTPVrJFNJKPrYewa9rpZcvdjwFece5fZP0CK34G4PxowA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@15.5.20':
+ resolution: {integrity: sha512-0hsFshdPnTzGJdDTHeHJ+XPUShOpnyp9pUFDwDhqctsA0Cd8NcIVGRPtptYhgYY9DjkKgCDRkXxmgRc+CgT5Wg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@15.5.20':
+ resolution: {integrity: sha512-DMvkoBtAABOzE6pMZRW/xNm7sKqql3wzzzZJ1R/d/rp4BCxv6LykouD3tHjGY8WdQqGpZs11t+R9AtjPxvvljw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-arm64-musl@15.5.20':
+ resolution: {integrity: sha512-RQmDfeYBtXV2FSId7dfA1hE6M/T6+g7wdbYnFQ47tw/gUBwV+CccLVejNmCGa9yLDitk83foeg8hl/3DjfYQ5g==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-x64-gnu@15.5.20':
+ resolution: {integrity: sha512-DkWLEdKajJwdGt27M3i1VEO2kelTvZrK6Pcb7JvW2BY+nofWm7FBsBNDj7g7Pr1NuQ5PLJvqEqYa20GTsBDnKQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-x64-musl@15.5.20':
+ resolution: {integrity: sha512-rAO5b7pKHvX+ExdmJskusDXTNbiNZfptifIPZItbUx+AOXxxTydVBsPt7Oz84DRd5mY8e0DcE8kvLj3AIfjE6w==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-win32-arm64-msvc@15.5.20':
+ resolution: {integrity: sha512-Hp3zFsN8N8Kj9+vY6L4vnZ9EtA9eXyATu0q4EfGbZTiocgPUNSfz8NWhym6xvaOmHpJ8EuoypuU1WejCPsTFtg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@15.5.20':
+ resolution: {integrity: sha512-T/L7CXpR1M0wij/xbF3rT1+7KvSkfOLr7C+ToHHWZTG2eKmb52C5WvsyGCBNtkVvDEUESWkRUbbqSH4rSbOCYQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@nolyfill/is-core-module@1.0.39':
+ resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
+ engines: {node: '>=12.4.0'}
+
+ '@rtsao/scc@1.1.0':
+ resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
+
+ '@swc/helpers@0.5.15':
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+
+ '@tybys/wasm-util@0.10.3':
+ resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
+
+ '@types/json5@0.0.29':
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+
+ '@types/node@20.17.6':
+ resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==}
+
+ '@types/react@19.2.17':
+ resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==}
+
+ '@typescript-eslint/eslint-plugin@8.64.0':
+ resolution: {integrity: sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^8.64.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/parser@8.64.0':
+ resolution: {integrity: sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/project-service@8.64.0':
+ resolution: {integrity: sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/scope-manager@8.64.0':
+ resolution: {integrity: sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/tsconfig-utils@8.64.0':
+ resolution: {integrity: sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/type-utils@8.64.0':
+ resolution: {integrity: sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/types@8.64.0':
+ resolution: {integrity: sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/typescript-estree@8.64.0':
+ resolution: {integrity: sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/utils@8.64.0':
+ resolution: {integrity: sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/visitor-keys@8.64.0':
+ resolution: {integrity: sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@ungap/structured-clone@1.3.3':
+ resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==}
+
+ '@unrs/resolver-binding-android-arm-eabi@1.12.2':
+ resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==}
+ cpu: [arm]
+ os: [android]
+
+ '@unrs/resolver-binding-android-arm64@1.12.2':
+ resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==}
+ cpu: [arm64]
+ os: [android]
+
+ '@unrs/resolver-binding-darwin-arm64@1.12.2':
+ resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@unrs/resolver-binding-darwin-x64@1.12.2':
+ resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@unrs/resolver-binding-freebsd-x64@1.12.2':
+ resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2':
+ resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2':
+ resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==}
+ cpu: [arm]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-arm64-gnu@1.12.2':
+ resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-arm64-musl@1.12.2':
+ resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-linux-loong64-gnu@1.12.2':
+ resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-loong64-musl@1.12.2':
+ resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2':
+ resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2':
+ resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-riscv64-musl@1.12.2':
+ resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-linux-s390x-gnu@1.12.2':
+ resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-x64-gnu@1.12.2':
+ resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-x64-musl@1.12.2':
+ resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-openharmony-arm64@1.12.2':
+ resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@unrs/resolver-binding-wasm32-wasi@1.12.2':
+ resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+
+ '@unrs/resolver-binding-win32-arm64-msvc@1.12.2':
+ resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@unrs/resolver-binding-win32-ia32-msvc@1.12.2':
+ resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@unrs/resolver-binding-win32-x64-msvc@1.12.2':
+ resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==}
+ cpu: [x64]
+ os: [win32]
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.17.0:
+ resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv@6.15.0:
+ resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-query@5.3.2:
+ resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
+ engines: {node: '>= 0.4'}
+
+ array-buffer-byte-length@1.0.2:
+ resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
+ engines: {node: '>= 0.4'}
+
+ array-includes@3.1.9:
+ resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.findlast@1.2.5:
+ resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.findlastindex@1.2.6:
+ resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flat@1.3.3:
+ resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flatmap@1.3.3:
+ resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.tosorted@1.1.4:
+ resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
+ engines: {node: '>= 0.4'}
+
+ arraybuffer.prototype.slice@1.0.4:
+ resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
+ engines: {node: '>= 0.4'}
+
+ ast-types-flow@0.0.8:
+ resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
+
+ async-function@1.0.0:
+ resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
+ engines: {node: '>= 0.4'}
+
+ autoprefixer@10.5.4:
+ resolution: {integrity: sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
+ available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+ engines: {node: '>= 0.4'}
+
+ axe-core@4.12.1:
+ resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==}
+ engines: {node: '>=4'}
+
+ axobject-query@4.1.0:
+ resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
+ engines: {node: '>= 0.4'}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
+ baseline-browser-mapping@2.10.43:
+ resolution: {integrity: sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ brace-expansion@1.1.16:
+ resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==}
+
+ brace-expansion@5.0.7:
+ resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==}
+ engines: {node: 18 || 20 || >=22}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.28.6:
+ resolution: {integrity: sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bind@1.0.9:
+ resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.4:
+ resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
+ engines: {node: '>= 0.4'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ caniuse-lite@1.0.30001806:
+ resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ damerau-levenshtein@1.0.8:
+ resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
+
+ data-view-buffer@1.0.2:
+ resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
+ engines: {node: '>= 0.4'}
+
+ data-view-byte-length@1.0.2:
+ resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
+ engines: {node: '>= 0.4'}
+
+ data-view-byte-offset@1.0.1:
+ resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
+ engines: {node: '>= 0.4'}
+
+ debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+
+ define-properties@1.2.1:
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+ engines: {node: '>= 0.4'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ doctrine@2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+
+ doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ electron-to-chromium@1.5.393:
+ resolution: {integrity: sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ es-abstract-get@1.0.0:
+ resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==}
+ engines: {node: '>= 0.4'}
+
+ es-abstract@1.24.2:
+ resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==}
+ engines: {node: '>= 0.4'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-iterator-helpers@1.4.0:
+ resolution: {integrity: sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==}
+ engines: {node: '>= 0.4'}
+
+ es-object-atoms@1.1.2:
+ resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ es-shim-unscopables@1.1.0:
+ resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==}
+ engines: {node: '>= 0.4'}
+
+ es-to-primitive@1.3.4:
+ resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==}
+ engines: {node: '>= 0.4'}
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ eslint-config-next@16.2.10:
+ resolution: {integrity: sha512-HSybLOY0QKf39i4FWUqPN0xWiNDi6A6UqJmZtgDkS3zMqjXTqULvj/sueXx3cdCG0mVG+qH6k5/qdegklH1d1w==}
+ peerDependencies:
+ eslint: '>=9.0.0'
+ typescript: '>=3.3.1'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ eslint-import-resolver-node@0.3.10:
+ resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==}
+
+ eslint-import-resolver-typescript@3.10.1:
+ resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '*'
+ eslint-plugin-import: '*'
+ eslint-plugin-import-x: '*'
+ peerDependenciesMeta:
+ eslint-plugin-import:
+ optional: true
+ eslint-plugin-import-x:
+ optional: true
+
+ eslint-module-utils@2.14.0:
+ resolution: {integrity: sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+
+ eslint-plugin-import@2.32.0:
+ resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+
+ eslint-plugin-jsx-a11y@6.10.2:
+ resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9
+
+ eslint-plugin-react-hooks@7.1.1:
+ resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0
+
+ eslint-plugin-react@7.37.5:
+ resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
+
+ eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@5.0.1:
+ resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ eslint@8.57.1:
+ resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
+ hasBin: true
+
+ espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ esquery@1.7.0:
+ resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fastq@1.20.1:
+ resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ file-entry-cache@6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ flat-cache@3.2.0:
+ resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+
+ flatted@3.4.2:
+ resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
+
+ for-each@0.3.5:
+ resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
+ engines: {node: '>= 0.4'}
+
+ fraction.js@5.3.4:
+ resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
+
+ framer-motion@11.18.2:
+ resolution: {integrity: sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==}
+ peerDependencies:
+ '@emotion/is-prop-valid': '*'
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/is-prop-valid':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
+ fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ function.prototype.name@1.2.0:
+ resolution: {integrity: sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==}
+ engines: {node: '>= 0.4'}
+
+ functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+
+ generator-function@2.0.1:
+ resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==}
+ engines: {node: '>= 0.4'}
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ get-symbol-description@1.1.0:
+ resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
+ engines: {node: '>= 0.4'}
+
+ get-tsconfig@4.14.0:
+ resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+
+ globals@13.24.0:
+ resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
+ engines: {node: '>=8'}
+
+ globals@16.4.0:
+ resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==}
+ engines: {node: '>=18'}
+
+ globalthis@1.0.4:
+ resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
+ engines: {node: '>= 0.4'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+
+ has-bigints@1.1.0:
+ resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
+ engines: {node: '>= 0.4'}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+
+ has-proto@1.2.0:
+ resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
+ engines: {node: '>= 0.4'}
+
+ hermes-estree@0.25.1:
+ resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
+
+ hermes-parser@0.25.1:
+ resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ ignore@7.0.6:
+ resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==}
+ engines: {node: '>= 4'}
+
+ import-fresh@3.3.1:
+ resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
+ engines: {node: '>=6'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ internal-slot@1.1.0:
+ resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
+ engines: {node: '>= 0.4'}
+
+ is-array-buffer@3.0.5:
+ resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
+ engines: {node: '>= 0.4'}
+
+ is-async-function@2.1.1:
+ resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
+ engines: {node: '>= 0.4'}
+
+ is-bigint@1.1.0:
+ resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
+ engines: {node: '>= 0.4'}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-boolean-object@1.2.2:
+ resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
+ engines: {node: '>= 0.4'}
+
+ is-bun-module@2.0.0:
+ resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==}
+
+ is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+
+ is-core-module@2.16.2:
+ resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
+ engines: {node: '>= 0.4'}
+
+ is-data-view@1.0.2:
+ resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
+ engines: {node: '>= 0.4'}
+
+ is-date-object@1.1.0:
+ resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
+ engines: {node: '>= 0.4'}
+
+ is-document.all@1.0.0:
+ resolution: {integrity: sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-finalizationregistry@1.1.1:
+ resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
+ engines: {node: '>= 0.4'}
+
+ is-generator-function@1.1.2:
+ resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==}
+ engines: {node: '>= 0.4'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-map@2.0.3:
+ resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
+ engines: {node: '>= 0.4'}
+
+ is-negative-zero@2.0.3:
+ resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
+ engines: {node: '>= 0.4'}
+
+ is-number-object@1.1.1:
+ resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
+ engines: {node: '>= 0.4'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+
+ is-regex@1.2.1:
+ resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
+ engines: {node: '>= 0.4'}
+
+ is-set@2.0.3:
+ resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
+ engines: {node: '>= 0.4'}
+
+ is-shared-array-buffer@1.0.4:
+ resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
+ engines: {node: '>= 0.4'}
+
+ is-string@1.1.1:
+ resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
+ engines: {node: '>= 0.4'}
+
+ is-symbol@1.1.1:
+ resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
+ engines: {node: '>= 0.4'}
+
+ is-typed-array@1.1.15:
+ resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
+ engines: {node: '>= 0.4'}
+
+ is-weakmap@2.0.2:
+ resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
+ engines: {node: '>= 0.4'}
+
+ is-weakref@1.1.1:
+ resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
+ engines: {node: '>= 0.4'}
+
+ is-weakset@2.0.4:
+ resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
+ engines: {node: '>= 0.4'}
+
+ isarray@2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ iterator.prototype@1.1.5:
+ resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
+ engines: {node: '>= 0.4'}
+
+ jiti@1.21.7:
+ resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
+ hasBin: true
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-yaml@4.3.0:
+ resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==}
+ hasBin: true
+
+ jsesc@3.1.0:
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ json5@1.0.2:
+ resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+ hasBin: true
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ jsx-ast-utils@3.3.5:
+ resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
+ engines: {node: '>=4.0'}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ language-subtag-registry@0.3.23:
+ resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==}
+
+ language-tags@1.0.9:
+ resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
+ engines: {node: '>=0.10'}
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ lilconfig@3.1.3:
+ resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
+ lucide-react@0.344.0:
+ resolution: {integrity: sha512-6YyBnn91GB45VuVT96bYCOKElbJzUHqp65vX8cDcu55MQL9T969v4dhGClpljamuI/+KMO9P6w9Acq1CVQGvIQ==}
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ minimatch@10.2.5:
+ resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ engines: {node: 18 || 20 || >=22}
+
+ minimatch@3.1.5:
+ resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ motion-dom@11.18.1:
+ resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==}
+
+ motion-utils@11.18.1:
+ resolution: {integrity: sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ nanoid@3.3.16:
+ resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ napi-postinstall@0.3.4:
+ resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ next@15.5.20:
+ resolution: {integrity: sha512-cvyS3/geydan1xLtE3FA8VCgdoQ/Gg/dlOldFkFCbB5VcVYJV7090hQLBnvTW2PwT76Z/dHdzDZCsVhZpoOlUA==}
+ engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
+ node-exports-info@1.6.2:
+ resolution: {integrity: sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==}
+ engines: {node: '>= 0.4'}
+
+ node-releases@2.0.51:
+ resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==}
+ engines: {node: '>=18'}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
+ object-inspect@1.13.4:
+ resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
+ engines: {node: '>= 0.4'}
+
+ object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+
+ object.assign@4.1.7:
+ resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
+ engines: {node: '>= 0.4'}
+
+ object.entries@1.1.9:
+ resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==}
+ engines: {node: '>= 0.4'}
+
+ object.fromentries@2.0.8:
+ resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
+ engines: {node: '>= 0.4'}
+
+ object.groupby@1.0.3:
+ resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
+ engines: {node: '>= 0.4'}
+
+ object.values@1.2.1:
+ resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
+ engines: {node: '>= 0.4'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ own-keys@1.0.1:
+ resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
+ engines: {node: '>= 0.4'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.2:
+ resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.5:
+ resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
+ engines: {node: '>=12'}
+
+ pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
+ pirates@4.0.7:
+ resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
+ engines: {node: '>= 6'}
+
+ possible-typed-array-names@1.1.0:
+ resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
+ engines: {node: '>= 0.4'}
+
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.1.0:
+ resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
+ postcss-load-config@6.0.1:
+ resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ jiti: '>=1.21.0'
+ postcss: '>=8.0.9'
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+ postcss:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.4:
+ resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.5.19:
+ resolution: {integrity: sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ prop-types@15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ react-dom@19.2.7:
+ resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==}
+ peerDependencies:
+ react: ^19.2.7
+
+ react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+
+ react@19.2.7:
+ resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==}
+ engines: {node: '>=0.10.0'}
+
+ read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ reflect.getprototypeof@1.0.10:
+ resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
+ engines: {node: '>= 0.4'}
+
+ regexp.prototype.flags@1.5.4:
+ resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
+ engines: {node: '>= 0.4'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ resolve@1.22.12:
+ resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
+ resolve@2.0.0-next.7:
+ resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ deprecated: Rimraf versions prior to v4 are no longer supported
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safe-array-concat@1.1.4:
+ resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==}
+ engines: {node: '>=0.4'}
+
+ safe-push-apply@1.0.0:
+ resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
+ engines: {node: '>= 0.4'}
+
+ safe-regex-test@1.1.0:
+ resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
+ engines: {node: '>= 0.4'}
+
+ scheduler@0.27.0:
+ resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ semver@7.8.5:
+ resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+
+ set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+ engines: {node: '>= 0.4'}
+
+ set-proto@1.0.0:
+ resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
+ engines: {node: '>= 0.4'}
+
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ side-channel-list@1.0.1:
+ resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-map@1.0.1:
+ resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-weakmap@1.0.2:
+ resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
+ engines: {node: '>= 0.4'}
+
+ side-channel@1.1.1:
+ resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
+ engines: {node: '>= 0.4'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ stable-hash@0.0.5:
+ resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
+
+ stop-iteration-iterator@1.1.0:
+ resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.includes@2.0.1:
+ resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.matchall@4.0.12:
+ resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.repeat@1.0.0:
+ resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
+
+ string.prototype.trim@1.2.11:
+ resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.trimend@1.0.10:
+ resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.trimstart@1.0.8:
+ resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
+ engines: {node: '>= 0.4'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ sucrase@3.35.1:
+ resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ tailwindcss@3.4.19:
+ resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ ts-api-utils@2.5.0:
+ resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
+ engines: {node: '>=18.12'}
+ peerDependencies:
+ typescript: '>=4.8.4'
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tsconfig-paths@3.15.0:
+ resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+
+ typed-array-buffer@1.0.3:
+ resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-byte-length@1.0.3:
+ resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-byte-offset@1.0.4:
+ resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-length@1.0.8:
+ resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==}
+ engines: {node: '>= 0.4'}
+
+ typescript-eslint@8.64.0:
+ resolution: {integrity: sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ typescript@5.8.2:
+ resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ unbox-primitive@1.1.0:
+ resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
+ engines: {node: '>= 0.4'}
+
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
+ unrs-resolver@1.12.2:
+ resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==}
+
+ update-browserslist-db@1.2.3:
+ resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ which-boxed-primitive@1.1.1:
+ resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
+ engines: {node: '>= 0.4'}
+
+ which-builtin-type@1.2.1:
+ resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
+ engines: {node: '>= 0.4'}
+
+ which-collection@1.0.2:
+ resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
+ engines: {node: '>= 0.4'}
+
+ which-typed-array@1.1.22:
+ resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==}
+ engines: {node: '>= 0.4'}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ zod-validation-error@4.0.2:
+ resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ zod: ^3.25.0 || ^4.0.0
+
+ zod@4.4.3:
+ resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
+
+snapshots:
+
+ '@alloc/quick-lru@5.2.0': {}
+
+ '@babel/code-frame@7.29.7':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.29.7
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/compat-data@7.29.7': {}
+
+ '@babel/core@7.29.7':
+ dependencies:
+ '@babel/code-frame': 7.29.7
+ '@babel/generator': 7.29.7
+ '@babel/helper-compilation-targets': 7.29.7
+ '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7)
+ '@babel/helpers': 7.29.7
+ '@babel/parser': 7.29.7
+ '@babel/template': 7.29.7
+ '@babel/traverse': 7.29.7
+ '@babel/types': 7.29.7
+ '@jridgewell/remapping': 2.3.5
+ convert-source-map: 2.0.0
+ debug: 4.4.3
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/generator@7.29.7':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@babel/types': 7.29.7
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+ jsesc: 3.1.0
+
+ '@babel/helper-compilation-targets@7.29.7':
+ dependencies:
+ '@babel/compat-data': 7.29.7
+ '@babel/helper-validator-option': 7.29.7
+ browserslist: 4.28.6
+ lru-cache: 5.1.1
+ semver: 6.3.1
+
+ '@babel/helper-globals@7.29.7': {}
+
+ '@babel/helper-module-imports@7.29.7':
+ dependencies:
+ '@babel/traverse': 7.29.7
+ '@babel/types': 7.29.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
+ dependencies:
+ '@babel/core': 7.29.7
+ '@babel/helper-module-imports': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+ '@babel/traverse': 7.29.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-string-parser@7.29.7': {}
+
+ '@babel/helper-validator-identifier@7.29.7': {}
+
+ '@babel/helper-validator-option@7.29.7': {}
+
+ '@babel/helpers@7.29.7':
+ dependencies:
+ '@babel/template': 7.29.7
+ '@babel/types': 7.29.7
+
+ '@babel/parser@7.29.7':
+ dependencies:
+ '@babel/types': 7.29.7
+
+ '@babel/template@7.29.7':
+ dependencies:
+ '@babel/code-frame': 7.29.7
+ '@babel/parser': 7.29.7
+ '@babel/types': 7.29.7
+
+ '@babel/traverse@7.29.7':
+ dependencies:
+ '@babel/code-frame': 7.29.7
+ '@babel/generator': 7.29.7
+ '@babel/helper-globals': 7.29.7
+ '@babel/parser': 7.29.7
+ '@babel/template': 7.29.7
+ '@babel/types': 7.29.7
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.29.7':
+ dependencies:
+ '@babel/helper-string-parser': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+
+ '@emnapi/core@1.10.0':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.1
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.10.0':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.11.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/wasi-threads@1.2.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)':
+ dependencies:
+ eslint: 8.57.1
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/regexpp@4.12.2': {}
+
+ '@eslint/eslintrc@2.1.4':
+ dependencies:
+ ajv: 6.15.0
+ debug: 4.4.3
+ espree: 9.6.1
+ globals: 13.24.0
+ ignore: 5.3.2
+ import-fresh: 3.3.1
+ js-yaml: 4.3.0
+ minimatch: 3.1.5
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/js@8.57.1': {}
+
+ '@humanwhocodes/config-array@0.13.0':
+ dependencies:
+ '@humanwhocodes/object-schema': 2.0.3
+ debug: 4.4.3
+ minimatch: 3.1.5
+ transitivePeerDependencies:
+ - supports-color
+
+ '@humanwhocodes/module-importer@1.0.1': {}
+
+ '@humanwhocodes/object-schema@2.0.3': {}
+
+ '@img/colour@1.1.0':
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.11.2
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
+ dependencies:
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@tybys/wasm-util': 0.10.3
+ optional: true
+
+ '@next/env@15.5.20': {}
+
+ '@next/eslint-plugin-next@16.2.10':
+ dependencies:
+ fast-glob: 3.3.1
+
+ '@next/swc-darwin-arm64@15.5.20':
+ optional: true
+
+ '@next/swc-darwin-x64@15.5.20':
+ optional: true
+
+ '@next/swc-linux-arm64-gnu@15.5.20':
+ optional: true
+
+ '@next/swc-linux-arm64-musl@15.5.20':
+ optional: true
+
+ '@next/swc-linux-x64-gnu@15.5.20':
+ optional: true
+
+ '@next/swc-linux-x64-musl@15.5.20':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@15.5.20':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@15.5.20':
+ optional: true
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.20.1
+
+ '@nolyfill/is-core-module@1.0.39': {}
+
+ '@rtsao/scc@1.1.0': {}
+
+ '@swc/helpers@0.5.15':
+ dependencies:
+ tslib: 2.8.1
+
+ '@tybys/wasm-util@0.10.3':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@types/json5@0.0.29': {}
+
+ '@types/node@20.17.6':
+ dependencies:
+ undici-types: 6.19.8
+
+ '@types/react@19.2.17':
+ dependencies:
+ csstype: 3.2.3
+
+ '@typescript-eslint/eslint-plugin@8.64.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)':
+ dependencies:
+ '@eslint-community/regexpp': 4.12.2
+ '@typescript-eslint/parser': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ '@typescript-eslint/scope-manager': 8.64.0
+ '@typescript-eslint/type-utils': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ '@typescript-eslint/utils': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ '@typescript-eslint/visitor-keys': 8.64.0
+ eslint: 8.57.1
+ ignore: 7.0.6
+ natural-compare: 1.4.0
+ ts-api-utils: 2.5.0(typescript@5.8.2)
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 8.64.0
+ '@typescript-eslint/types': 8.64.0
+ '@typescript-eslint/typescript-estree': 8.64.0(typescript@5.8.2)
+ '@typescript-eslint/visitor-keys': 8.64.0
+ debug: 4.4.3
+ eslint: 8.57.1
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/project-service@8.64.0(typescript@5.8.2)':
+ dependencies:
+ '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@5.8.2)
+ '@typescript-eslint/types': 8.64.0
+ debug: 4.4.3
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@8.64.0':
+ dependencies:
+ '@typescript-eslint/types': 8.64.0
+ '@typescript-eslint/visitor-keys': 8.64.0
+
+ '@typescript-eslint/tsconfig-utils@8.64.0(typescript@5.8.2)':
+ dependencies:
+ typescript: 5.8.2
+
+ '@typescript-eslint/type-utils@8.64.0(eslint@8.57.1)(typescript@5.8.2)':
+ dependencies:
+ '@typescript-eslint/types': 8.64.0
+ '@typescript-eslint/typescript-estree': 8.64.0(typescript@5.8.2)
+ '@typescript-eslint/utils': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ debug: 4.4.3
+ eslint: 8.57.1
+ ts-api-utils: 2.5.0(typescript@5.8.2)
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/types@8.64.0': {}
+
+ '@typescript-eslint/typescript-estree@8.64.0(typescript@5.8.2)':
+ dependencies:
+ '@typescript-eslint/project-service': 8.64.0(typescript@5.8.2)
+ '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@5.8.2)
+ '@typescript-eslint/types': 8.64.0
+ '@typescript-eslint/visitor-keys': 8.64.0
+ debug: 4.4.3
+ minimatch: 10.2.5
+ semver: 7.8.5
+ tinyglobby: 0.2.17
+ ts-api-utils: 2.5.0(typescript@5.8.2)
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.64.0(eslint@8.57.1)(typescript@5.8.2)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1)
+ '@typescript-eslint/scope-manager': 8.64.0
+ '@typescript-eslint/types': 8.64.0
+ '@typescript-eslint/typescript-estree': 8.64.0(typescript@5.8.2)
+ eslint: 8.57.1
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/visitor-keys@8.64.0':
+ dependencies:
+ '@typescript-eslint/types': 8.64.0
+ eslint-visitor-keys: 5.0.1
+
+ '@ungap/structured-clone@1.3.3': {}
+
+ '@unrs/resolver-binding-android-arm-eabi@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-android-arm64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-darwin-arm64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-darwin-x64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-freebsd-x64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-loong64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-loong64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-riscv64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-s390x-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-x64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-x64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-openharmony-arm64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-wasm32-wasi@1.12.2':
+ dependencies:
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
+ optional: true
+
+ '@unrs/resolver-binding-win32-arm64-msvc@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-win32-ia32-msvc@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-win32-x64-msvc@1.12.2':
+ optional: true
+
+ acorn-jsx@5.3.2(acorn@8.17.0):
+ dependencies:
+ acorn: 8.17.0
+
+ acorn@8.17.0: {}
+
+ ajv@6.15.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ansi-regex@5.0.1: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ any-promise@1.3.0: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.2
+
+ arg@5.0.2: {}
+
+ argparse@2.0.1: {}
+
+ aria-query@5.3.2: {}
+
+ array-buffer-byte-length@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ is-array-buffer: 3.0.5
+
+ array-includes@3.1.9:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ is-string: 1.1.1
+ math-intrinsics: 1.1.0
+
+ array.prototype.findlast@1.2.5:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.findlastindex@1.2.6:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.flat@1.3.3:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.flatmap@1.3.3:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.tosorted@1.1.4:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-shim-unscopables: 1.1.0
+
+ arraybuffer.prototype.slice@1.0.4:
+ dependencies:
+ array-buffer-byte-length: 1.0.2
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ is-array-buffer: 3.0.5
+
+ ast-types-flow@0.0.8: {}
+
+ async-function@1.0.0: {}
+
+ autoprefixer@10.5.4(postcss@8.5.19):
+ dependencies:
+ browserslist: 4.28.6
+ caniuse-lite: 1.0.30001806
+ fraction.js: 5.3.4
+ picocolors: 1.1.1
+ postcss: 8.5.19
+ postcss-value-parser: 4.2.0
+
+ available-typed-arrays@1.0.7:
+ dependencies:
+ possible-typed-array-names: 1.1.0
+
+ axe-core@4.12.1: {}
+
+ axobject-query@4.1.0: {}
+
+ balanced-match@1.0.2: {}
+
+ balanced-match@4.0.4: {}
+
+ baseline-browser-mapping@2.10.43: {}
+
+ binary-extensions@2.3.0: {}
+
+ brace-expansion@1.1.16:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ brace-expansion@5.0.7:
+ dependencies:
+ balanced-match: 4.0.4
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.28.6:
+ dependencies:
+ baseline-browser-mapping: 2.10.43
+ caniuse-lite: 1.0.30001806
+ electron-to-chromium: 1.5.393
+ node-releases: 2.0.51
+ update-browserslist-db: 1.2.3(browserslist@4.28.6)
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bind@1.0.9:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ get-intrinsic: 1.3.0
+ set-function-length: 1.2.2
+
+ call-bound@1.0.4:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ get-intrinsic: 1.3.0
+
+ callsites@3.1.0: {}
+
+ camelcase-css@2.0.1: {}
+
+ caniuse-lite@1.0.30001806: {}
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ client-only@0.0.1: {}
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ commander@4.1.1: {}
+
+ concat-map@0.0.1: {}
+
+ convert-source-map@2.0.0: {}
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ cssesc@3.0.0: {}
+
+ csstype@3.2.3: {}
+
+ damerau-levenshtein@1.0.8: {}
+
+ data-view-buffer@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-data-view: 1.0.2
+
+ data-view-byte-length@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-data-view: 1.0.2
+
+ data-view-byte-offset@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-data-view: 1.0.2
+
+ debug@3.2.7:
+ dependencies:
+ ms: 2.1.3
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ deep-is@0.1.4: {}
+
+ define-data-property@1.1.4:
+ dependencies:
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ define-properties@1.2.1:
+ dependencies:
+ define-data-property: 1.1.4
+ has-property-descriptors: 1.0.2
+ object-keys: 1.1.1
+
+ detect-libc@2.1.2:
+ optional: true
+
+ didyoumean@1.2.2: {}
+
+ dlv@1.1.3: {}
+
+ doctrine@2.1.0:
+ dependencies:
+ esutils: 2.0.3
+
+ doctrine@3.0.0:
+ dependencies:
+ esutils: 2.0.3
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ electron-to-chromium@1.5.393: {}
+
+ emoji-regex@9.2.2: {}
+
+ es-abstract-get@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ is-callable: 1.2.7
+ object-inspect: 1.13.4
+
+ es-abstract@1.24.2:
+ dependencies:
+ array-buffer-byte-length: 1.0.2
+ arraybuffer.prototype.slice: 1.0.4
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ data-view-buffer: 1.0.2
+ data-view-byte-length: 1.0.2
+ data-view-byte-offset: 1.0.1
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ es-set-tostringtag: 2.1.0
+ es-to-primitive: 1.3.4
+ function.prototype.name: 1.2.0
+ get-intrinsic: 1.3.0
+ get-proto: 1.0.1
+ get-symbol-description: 1.1.0
+ globalthis: 1.0.4
+ gopd: 1.2.0
+ has-property-descriptors: 1.0.2
+ has-proto: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.4
+ internal-slot: 1.1.0
+ is-array-buffer: 3.0.5
+ is-callable: 1.2.7
+ is-data-view: 1.0.2
+ is-negative-zero: 2.0.3
+ is-regex: 1.2.1
+ is-set: 2.0.3
+ is-shared-array-buffer: 1.0.4
+ is-string: 1.1.1
+ is-typed-array: 1.1.15
+ is-weakref: 1.1.1
+ math-intrinsics: 1.1.0
+ object-inspect: 1.13.4
+ object-keys: 1.1.1
+ object.assign: 4.1.7
+ own-keys: 1.0.1
+ regexp.prototype.flags: 1.5.4
+ safe-array-concat: 1.1.4
+ safe-push-apply: 1.0.0
+ safe-regex-test: 1.1.0
+ set-proto: 1.0.0
+ stop-iteration-iterator: 1.1.0
+ string.prototype.trim: 1.2.11
+ string.prototype.trimend: 1.0.10
+ string.prototype.trimstart: 1.0.8
+ typed-array-buffer: 1.0.3
+ typed-array-byte-length: 1.0.3
+ typed-array-byte-offset: 1.0.4
+ typed-array-length: 1.0.8
+ unbox-primitive: 1.1.0
+ which-typed-array: 1.1.22
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-iterator-helpers@1.4.0:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-set-tostringtag: 2.1.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.3.0
+ globalthis: 1.0.4
+ gopd: 1.2.0
+ has-property-descriptors: 1.0.2
+ has-proto: 1.2.0
+ has-symbols: 1.1.0
+ internal-slot: 1.1.0
+ iterator.prototype: 1.1.5
+ math-intrinsics: 1.1.0
+
+ es-object-atoms@1.1.2:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.4
+
+ es-shim-unscopables@1.1.0:
+ dependencies:
+ hasown: 2.0.4
+
+ es-to-primitive@1.3.4:
+ dependencies:
+ es-abstract-get: 1.0.0
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ is-callable: 1.2.7
+ is-date-object: 1.1.0
+ is-symbol: 1.1.1
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ eslint-config-next@16.2.10(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2):
+ dependencies:
+ '@next/eslint-plugin-next': 16.2.10
+ eslint: 8.57.1
+ eslint-import-resolver-node: 0.3.10
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1)
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
+ eslint-plugin-react: 7.37.5(eslint@8.57.1)
+ eslint-plugin-react-hooks: 7.1.1(eslint@8.57.1)
+ globals: 16.4.0
+ typescript-eslint: 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ optionalDependencies:
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - '@typescript-eslint/parser'
+ - eslint-import-resolver-webpack
+ - eslint-plugin-import-x
+ - supports-color
+
+ eslint-import-resolver-node@0.3.10:
+ dependencies:
+ debug: 3.2.7
+ is-core-module: 2.16.2
+ resolve: 2.0.0-next.7
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1):
+ dependencies:
+ '@nolyfill/is-core-module': 1.0.39
+ debug: 4.4.3
+ eslint: 8.57.1
+ get-tsconfig: 4.14.0
+ is-bun-module: 2.0.0
+ stable-hash: 0.0.5
+ tinyglobby: 0.2.17
+ unrs-resolver: 1.12.2
+ optionalDependencies:
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-module-utils@2.14.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
+ dependencies:
+ debug: 3.2.7
+ optionalDependencies:
+ '@typescript-eslint/parser': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ eslint: 8.57.1
+ eslint-import-resolver-node: 0.3.10
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
+ dependencies:
+ '@rtsao/scc': 1.1.0
+ array-includes: 3.1.9
+ array.prototype.findlastindex: 1.2.6
+ array.prototype.flat: 1.3.3
+ array.prototype.flatmap: 1.3.3
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.57.1
+ eslint-import-resolver-node: 0.3.10
+ eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ hasown: 2.0.4
+ is-core-module: 2.16.2
+ is-glob: 4.0.3
+ minimatch: 3.1.5
+ object.fromentries: 2.0.8
+ object.groupby: 1.0.3
+ object.values: 1.2.1
+ semver: 6.3.1
+ string.prototype.trimend: 1.0.10
+ tsconfig-paths: 3.15.0
+ optionalDependencies:
+ '@typescript-eslint/parser': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+
+ eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1):
+ dependencies:
+ aria-query: 5.3.2
+ array-includes: 3.1.9
+ array.prototype.flatmap: 1.3.3
+ ast-types-flow: 0.0.8
+ axe-core: 4.12.1
+ axobject-query: 4.1.0
+ damerau-levenshtein: 1.0.8
+ emoji-regex: 9.2.2
+ eslint: 8.57.1
+ hasown: 2.0.4
+ jsx-ast-utils: 3.3.5
+ language-tags: 1.0.9
+ minimatch: 3.1.5
+ object.fromentries: 2.0.8
+ safe-regex-test: 1.1.0
+ string.prototype.includes: 2.0.1
+
+ eslint-plugin-react-hooks@7.1.1(eslint@8.57.1):
+ dependencies:
+ '@babel/core': 7.29.7
+ '@babel/parser': 7.29.7
+ eslint: 8.57.1
+ hermes-parser: 0.25.1
+ zod: 4.4.3
+ zod-validation-error: 4.0.2(zod@4.4.3)
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-plugin-react@7.37.5(eslint@8.57.1):
+ dependencies:
+ array-includes: 3.1.9
+ array.prototype.findlast: 1.2.5
+ array.prototype.flatmap: 1.3.3
+ array.prototype.tosorted: 1.1.4
+ doctrine: 2.1.0
+ es-iterator-helpers: 1.4.0
+ eslint: 8.57.1
+ estraverse: 5.3.0
+ hasown: 2.0.4
+ jsx-ast-utils: 3.3.5
+ minimatch: 3.1.5
+ object.entries: 1.1.9
+ object.fromentries: 2.0.8
+ object.values: 1.2.1
+ prop-types: 15.8.1
+ resolve: 2.0.0-next.7
+ semver: 6.3.1
+ string.prototype.matchall: 4.0.12
+ string.prototype.repeat: 1.0.0
+
+ eslint-scope@7.2.2:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint-visitor-keys@5.0.1: {}
+
+ eslint@8.57.1:
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1)
+ '@eslint-community/regexpp': 4.12.2
+ '@eslint/eslintrc': 2.1.4
+ '@eslint/js': 8.57.1
+ '@humanwhocodes/config-array': 0.13.0
+ '@humanwhocodes/module-importer': 1.0.1
+ '@nodelib/fs.walk': 1.2.8
+ '@ungap/structured-clone': 1.3.3
+ ajv: 6.15.0
+ chalk: 4.1.2
+ cross-spawn: 7.0.6
+ debug: 4.4.3
+ doctrine: 3.0.0
+ escape-string-regexp: 4.0.0
+ eslint-scope: 7.2.2
+ eslint-visitor-keys: 3.4.3
+ espree: 9.6.1
+ esquery: 1.7.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ globals: 13.24.0
+ graphemer: 1.4.0
+ ignore: 5.3.2
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ is-path-inside: 3.0.3
+ js-yaml: 4.3.0
+ json-stable-stringify-without-jsonify: 1.0.1
+ levn: 0.4.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.5
+ natural-compare: 1.4.0
+ optionator: 0.9.4
+ strip-ansi: 6.0.1
+ text-table: 0.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ espree@9.6.1:
+ dependencies:
+ acorn: 8.17.0
+ acorn-jsx: 5.3.2(acorn@8.17.0)
+ eslint-visitor-keys: 3.4.3
+
+ esquery@1.7.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@5.3.0: {}
+
+ esutils@2.0.3: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-glob@3.3.1:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-glob@3.3.3:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-levenshtein@2.0.6: {}
+
+ fastq@1.20.1:
+ dependencies:
+ reusify: 1.1.0
+
+ fdir@6.5.0(picomatch@4.0.5):
+ optionalDependencies:
+ picomatch: 4.0.5
+
+ file-entry-cache@6.0.1:
+ dependencies:
+ flat-cache: 3.2.0
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ find-up@5.0.0:
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ flat-cache@3.2.0:
+ dependencies:
+ flatted: 3.4.2
+ keyv: 4.5.4
+ rimraf: 3.0.2
+
+ flatted@3.4.2: {}
+
+ for-each@0.3.5:
+ dependencies:
+ is-callable: 1.2.7
+
+ fraction.js@5.3.4: {}
+
+ framer-motion@11.18.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ dependencies:
+ motion-dom: 11.18.1
+ motion-utils: 11.18.1
+ tslib: 2.8.1
+ optionalDependencies:
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+
+ fs.realpath@1.0.0: {}
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ function.prototype.name@1.2.0:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+ hasown: 2.0.4
+ is-callable: 1.2.7
+ is-document.all: 1.0.0
+
+ functions-have-names@1.2.3: {}
+
+ generator-function@2.0.1: {}
+
+ gensync@1.0.0-beta.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.4
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.2
+
+ get-symbol-description@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+
+ get-tsconfig@4.14.0:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob@7.2.3:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.5
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
+ globals@13.24.0:
+ dependencies:
+ type-fest: 0.20.2
+
+ globals@16.4.0: {}
+
+ globalthis@1.0.4:
+ dependencies:
+ define-properties: 1.2.1
+ gopd: 1.2.0
+
+ gopd@1.2.0: {}
+
+ graphemer@1.4.0: {}
+
+ has-bigints@1.1.0: {}
+
+ has-flag@4.0.0: {}
+
+ has-property-descriptors@1.0.2:
+ dependencies:
+ es-define-property: 1.0.1
+
+ has-proto@1.2.0:
+ dependencies:
+ dunder-proto: 1.0.1
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.4:
+ dependencies:
+ function-bind: 1.1.2
+
+ hermes-estree@0.25.1: {}
+
+ hermes-parser@0.25.1:
+ dependencies:
+ hermes-estree: 0.25.1
+
+ ignore@5.3.2: {}
+
+ ignore@7.0.6: {}
+
+ import-fresh@3.3.1:
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ imurmurhash@0.1.4: {}
+
+ inflight@1.0.6:
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
+ inherits@2.0.4: {}
+
+ internal-slot@1.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ hasown: 2.0.4
+ side-channel: 1.1.1
+
+ is-array-buffer@3.0.5:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+
+ is-async-function@2.1.1:
+ dependencies:
+ async-function: 1.0.0
+ call-bound: 1.0.4
+ get-proto: 1.0.1
+ has-tostringtag: 1.0.2
+ safe-regex-test: 1.1.0
+
+ is-bigint@1.1.0:
+ dependencies:
+ has-bigints: 1.1.0
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-boolean-object@1.2.2:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-bun-module@2.0.0:
+ dependencies:
+ semver: 7.8.5
+
+ is-callable@1.2.7: {}
+
+ is-core-module@2.16.2:
+ dependencies:
+ hasown: 2.0.4
+
+ is-data-view@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+ is-typed-array: 1.1.15
+
+ is-date-object@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-document.all@1.0.0:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-extglob@2.1.1: {}
+
+ is-finalizationregistry@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-generator-function@1.1.2:
+ dependencies:
+ call-bound: 1.0.4
+ generator-function: 2.0.1
+ get-proto: 1.0.1
+ has-tostringtag: 1.0.2
+ safe-regex-test: 1.1.0
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-map@2.0.3: {}
+
+ is-negative-zero@2.0.3: {}
+
+ is-number-object@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-number@7.0.0: {}
+
+ is-path-inside@3.0.3: {}
+
+ is-regex@1.2.1:
+ dependencies:
+ call-bound: 1.0.4
+ gopd: 1.2.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.4
+
+ is-set@2.0.3: {}
+
+ is-shared-array-buffer@1.0.4:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-string@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-symbol@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+ has-symbols: 1.1.0
+ safe-regex-test: 1.1.0
+
+ is-typed-array@1.1.15:
+ dependencies:
+ which-typed-array: 1.1.22
+
+ is-weakmap@2.0.2: {}
+
+ is-weakref@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-weakset@2.0.4:
+ dependencies:
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+
+ isarray@2.0.5: {}
+
+ isexe@2.0.0: {}
+
+ iterator.prototype@1.1.5:
+ dependencies:
+ define-data-property: 1.1.4
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ get-proto: 1.0.1
+ has-symbols: 1.1.0
+ set-function-name: 2.0.2
+
+ jiti@1.21.7: {}
+
+ js-tokens@4.0.0: {}
+
+ js-yaml@4.3.0:
+ dependencies:
+ argparse: 2.0.1
+
+ jsesc@3.1.0: {}
+
+ json-buffer@3.0.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-stable-stringify-without-jsonify@1.0.1: {}
+
+ json5@1.0.2:
+ dependencies:
+ minimist: 1.2.8
+
+ json5@2.2.3: {}
+
+ jsx-ast-utils@3.3.5:
+ dependencies:
+ array-includes: 3.1.9
+ array.prototype.flat: 1.3.3
+ object.assign: 4.1.7
+ object.values: 1.2.1
+
+ keyv@4.5.4:
+ dependencies:
+ json-buffer: 3.0.1
+
+ language-subtag-registry@0.3.23: {}
+
+ language-tags@1.0.9:
+ dependencies:
+ language-subtag-registry: 0.3.23
+
+ levn@0.4.1:
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ lilconfig@3.1.3: {}
+
+ lines-and-columns@1.2.4: {}
+
+ locate-path@6.0.0:
+ dependencies:
+ p-locate: 5.0.0
+
+ lodash.merge@4.6.2: {}
+
+ loose-envify@1.4.0:
+ dependencies:
+ js-tokens: 4.0.0
+
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+
+ lucide-react@0.344.0(react@19.2.7):
+ dependencies:
+ react: 19.2.7
+
+ math-intrinsics@1.1.0: {}
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.2
+
+ minimatch@10.2.5:
+ dependencies:
+ brace-expansion: 5.0.7
+
+ minimatch@3.1.5:
+ dependencies:
+ brace-expansion: 1.1.16
+
+ minimist@1.2.8: {}
+
+ motion-dom@11.18.1:
+ dependencies:
+ motion-utils: 11.18.1
+
+ motion-utils@11.18.1: {}
+
+ ms@2.1.3: {}
+
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
+ nanoid@3.3.16: {}
+
+ napi-postinstall@0.3.4: {}
+
+ natural-compare@1.4.0: {}
+
+ next@15.5.20(@babel/core@7.29.7)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ dependencies:
+ '@next/env': 15.5.20
+ '@swc/helpers': 0.5.15
+ caniuse-lite: 1.0.30001806
+ postcss: 8.4.31
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+ styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.7)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 15.5.20
+ '@next/swc-darwin-x64': 15.5.20
+ '@next/swc-linux-arm64-gnu': 15.5.20
+ '@next/swc-linux-arm64-musl': 15.5.20
+ '@next/swc-linux-x64-gnu': 15.5.20
+ '@next/swc-linux-x64-musl': 15.5.20
+ '@next/swc-win32-arm64-msvc': 15.5.20
+ '@next/swc-win32-x64-msvc': 15.5.20
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
+ node-exports-info@1.6.2:
+ dependencies:
+ array.prototype.flatmap: 1.3.3
+ es-errors: 1.3.0
+ object.entries: 1.1.9
+ semver: 6.3.1
+
+ node-releases@2.0.51: {}
+
+ normalize-path@3.0.0: {}
+
+ object-assign@4.1.1: {}
+
+ object-hash@3.0.0: {}
+
+ object-inspect@1.13.4: {}
+
+ object-keys@1.1.1: {}
+
+ object.assign@4.1.7:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+ has-symbols: 1.1.0
+ object-keys: 1.1.1
+
+ object.entries@1.1.9:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ object.fromentries@2.0.8:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-object-atoms: 1.1.2
+
+ object.groupby@1.0.3:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+
+ object.values@1.2.1:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ optionator@0.9.4:
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.5
+
+ own-keys@1.0.1:
+ dependencies:
+ get-intrinsic: 1.3.0
+ object-keys: 1.1.1
+ safe-push-apply: 1.0.0
+
+ p-limit@3.1.0:
+ dependencies:
+ yocto-queue: 0.1.0
+
+ p-locate@5.0.0:
+ dependencies:
+ p-limit: 3.1.0
+
+ parent-module@1.0.1:
+ dependencies:
+ callsites: 3.1.0
+
+ path-exists@4.0.0: {}
+
+ path-is-absolute@1.0.1: {}
+
+ path-key@3.1.1: {}
+
+ path-parse@1.0.7: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.2: {}
+
+ picomatch@4.0.5: {}
+
+ pify@2.3.0: {}
+
+ pirates@4.0.7: {}
+
+ possible-typed-array-names@1.1.0: {}
+
+ postcss-import@15.1.0(postcss@8.5.19):
+ dependencies:
+ postcss: 8.5.19
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.12
+
+ postcss-js@4.1.0(postcss@8.5.19):
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.5.19
+
+ postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.19):
+ dependencies:
+ lilconfig: 3.1.3
+ optionalDependencies:
+ jiti: 1.21.7
+ postcss: 8.5.19
+
+ postcss-nested@6.2.0(postcss@8.5.19):
+ dependencies:
+ postcss: 8.5.19
+ postcss-selector-parser: 6.1.4
+
+ postcss-selector-parser@6.1.4:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.4.31:
+ dependencies:
+ nanoid: 3.3.16
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ postcss@8.5.19:
+ dependencies:
+ nanoid: 3.3.16
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prelude-ls@1.2.1: {}
+
+ prop-types@15.8.1:
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+
+ punycode@2.3.1: {}
+
+ queue-microtask@1.2.3: {}
+
+ react-dom@19.2.7(react@19.2.7):
+ dependencies:
+ react: 19.2.7
+ scheduler: 0.27.0
+
+ react-is@16.13.1: {}
+
+ react@19.2.7: {}
+
+ read-cache@1.0.0:
+ dependencies:
+ pify: 2.3.0
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.2
+
+ reflect.getprototypeof@1.0.10:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ get-proto: 1.0.1
+ which-builtin-type: 1.2.1
+
+ regexp.prototype.flags@1.5.4:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-errors: 1.3.0
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ set-function-name: 2.0.2
+
+ resolve-from@4.0.0: {}
+
+ resolve-pkg-maps@1.0.0: {}
+
+ resolve@1.22.12:
+ dependencies:
+ es-errors: 1.3.0
+ is-core-module: 2.16.2
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ resolve@2.0.0-next.7:
+ dependencies:
+ es-errors: 1.3.0
+ is-core-module: 2.16.2
+ node-exports-info: 1.6.2
+ object-keys: 1.1.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ reusify@1.1.0: {}
+
+ rimraf@3.0.2:
+ dependencies:
+ glob: 7.2.3
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ safe-array-concat@1.1.4:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+ has-symbols: 1.1.0
+ isarray: 2.0.5
+
+ safe-push-apply@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+ isarray: 2.0.5
+
+ safe-regex-test@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-regex: 1.2.1
+
+ scheduler@0.27.0: {}
+
+ semver@6.3.1: {}
+
+ semver@7.8.5: {}
+
+ set-function-length@1.2.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.3.0
+ gopd: 1.2.0
+ has-property-descriptors: 1.0.2
+
+ set-function-name@2.0.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+
+ set-proto@1.0.0:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.5
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+ optional: true
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ side-channel-list@1.0.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-map@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-weakmap@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-map: 1.0.1
+
+ side-channel@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-list: 1.0.1
+ side-channel-map: 1.0.1
+ side-channel-weakmap: 1.0.2
+
+ source-map-js@1.2.1: {}
+
+ stable-hash@0.0.5: {}
+
+ stop-iteration-iterator@1.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ internal-slot: 1.1.0
+
+ string.prototype.includes@2.0.1:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+
+ string.prototype.matchall@4.0.12:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ internal-slot: 1.1.0
+ regexp.prototype.flags: 1.5.4
+ set-function-name: 2.0.2
+ side-channel: 1.1.1
+
+ string.prototype.repeat@1.0.0:
+ dependencies:
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+
+ string.prototype.trim@1.2.11:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-data-property: 1.1.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-object-atoms: 1.1.2
+ has-property-descriptors: 1.0.2
+ safe-regex-test: 1.1.0
+
+ string.prototype.trimend@1.0.10:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ string.prototype.trimstart@1.0.8:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-bom@3.0.0: {}
+
+ strip-json-comments@3.1.1: {}
+
+ styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.7):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.2.7
+ optionalDependencies:
+ '@babel/core': 7.29.7
+
+ sucrase@3.35.1:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ commander: 4.1.1
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.7
+ tinyglobby: 0.2.17
+ ts-interface-checker: 0.1.13
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ tailwindcss@3.4.19:
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.3
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.7
+ lilconfig: 3.1.3
+ micromatch: 4.0.8
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.1.1
+ postcss: 8.5.19
+ postcss-import: 15.1.0(postcss@8.5.19)
+ postcss-js: 4.1.0(postcss@8.5.19)
+ postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.19)
+ postcss-nested: 6.2.0(postcss@8.5.19)
+ postcss-selector-parser: 6.1.4
+ resolve: 1.22.12
+ sucrase: 3.35.1
+ transitivePeerDependencies:
+ - tsx
+ - yaml
+
+ text-table@0.2.0: {}
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.5)
+ picomatch: 4.0.5
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ ts-api-utils@2.5.0(typescript@5.8.2):
+ dependencies:
+ typescript: 5.8.2
+
+ ts-interface-checker@0.1.13: {}
+
+ tsconfig-paths@3.15.0:
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.2
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+
+ tslib@2.8.1: {}
+
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
+
+ type-fest@0.20.2: {}
+
+ typed-array-buffer@1.0.3:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-typed-array: 1.1.15
+
+ typed-array-byte-length@1.0.3:
+ dependencies:
+ call-bind: 1.0.9
+ for-each: 0.3.5
+ gopd: 1.2.0
+ has-proto: 1.2.0
+ is-typed-array: 1.1.15
+
+ typed-array-byte-offset@1.0.4:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.9
+ for-each: 0.3.5
+ gopd: 1.2.0
+ has-proto: 1.2.0
+ is-typed-array: 1.1.15
+ reflect.getprototypeof: 1.0.10
+
+ typed-array-length@1.0.8:
+ dependencies:
+ call-bind: 1.0.9
+ for-each: 0.3.5
+ gopd: 1.2.0
+ is-typed-array: 1.1.15
+ possible-typed-array-names: 1.1.0
+ reflect.getprototypeof: 1.0.10
+
+ typescript-eslint@8.64.0(eslint@8.57.1)(typescript@5.8.2):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.64.0(@typescript-eslint/parser@8.64.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)
+ '@typescript-eslint/parser': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ '@typescript-eslint/typescript-estree': 8.64.0(typescript@5.8.2)
+ '@typescript-eslint/utils': 8.64.0(eslint@8.57.1)(typescript@5.8.2)
+ eslint: 8.57.1
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ typescript@5.8.2: {}
+
+ unbox-primitive@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ has-bigints: 1.1.0
+ has-symbols: 1.1.0
+ which-boxed-primitive: 1.1.1
+
+ undici-types@6.19.8: {}
+
+ unrs-resolver@1.12.2:
+ dependencies:
+ napi-postinstall: 0.3.4
+ optionalDependencies:
+ '@unrs/resolver-binding-android-arm-eabi': 1.12.2
+ '@unrs/resolver-binding-android-arm64': 1.12.2
+ '@unrs/resolver-binding-darwin-arm64': 1.12.2
+ '@unrs/resolver-binding-darwin-x64': 1.12.2
+ '@unrs/resolver-binding-freebsd-x64': 1.12.2
+ '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2
+ '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2
+ '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-arm64-musl': 1.12.2
+ '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-loong64-musl': 1.12.2
+ '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2
+ '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-x64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-x64-musl': 1.12.2
+ '@unrs/resolver-binding-openharmony-arm64': 1.12.2
+ '@unrs/resolver-binding-wasm32-wasi': 1.12.2
+ '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2
+ '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2
+ '@unrs/resolver-binding-win32-x64-msvc': 1.12.2
+
+ update-browserslist-db@1.2.3(browserslist@4.28.6):
+ dependencies:
+ browserslist: 4.28.6
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ util-deprecate@1.0.2: {}
+
+ which-boxed-primitive@1.1.1:
+ dependencies:
+ is-bigint: 1.1.0
+ is-boolean-object: 1.2.2
+ is-number-object: 1.1.1
+ is-string: 1.1.1
+ is-symbol: 1.1.1
+
+ which-builtin-type@1.2.1:
+ dependencies:
+ call-bound: 1.0.4
+ function.prototype.name: 1.2.0
+ has-tostringtag: 1.0.2
+ is-async-function: 2.1.1
+ is-date-object: 1.1.0
+ is-finalizationregistry: 1.1.1
+ is-generator-function: 1.1.2
+ is-regex: 1.2.1
+ is-weakref: 1.1.1
+ isarray: 2.0.5
+ which-boxed-primitive: 1.1.1
+ which-collection: 1.0.2
+ which-typed-array: 1.1.22
+
+ which-collection@1.0.2:
+ dependencies:
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-weakmap: 2.0.2
+ is-weakset: 2.0.4
+
+ which-typed-array@1.1.22:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ for-each: 0.3.5
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-tostringtag: 1.0.2
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ word-wrap@1.2.5: {}
+
+ wrappy@1.0.2: {}
+
+ yallist@3.1.1: {}
+
+ yocto-queue@0.1.0: {}
+
+ zod-validation-error@4.0.2(zod@4.4.3):
+ dependencies:
+ zod: 4.4.3
+
+ zod@4.4.3: {}
diff --git a/postcss.config.mjs b/postcss.config.mjs
new file mode 100644
index 0000000..2e7af2b
--- /dev/null
+++ b/postcss.config.mjs
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/tailwind.config.ts b/tailwind.config.ts
new file mode 100644
index 0000000..cd2786d
--- /dev/null
+++ b/tailwind.config.ts
@@ -0,0 +1,33 @@
+import type { Config } from 'tailwindcss'
+
+export default {
+ content: [
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ theme: {
+ extend: {
+ colors: {
+ void: '#070B14',
+ deck: '#0E1424',
+ riser: '#131B2E',
+ wire: '#1F2A45',
+ 'wire-lit': '#35486F',
+ lamp: '#FFA524',
+ flux: '#4FD1C5',
+ rose: '#FF5C7A',
+ dim: '#6B7DA5',
+ chalk: '#DDE5F7',
+ },
+ fontFamily: {
+ signage: ['var(--font-signage)', 'ui-sans-serif', 'system-ui'],
+ plex: ['var(--font-plex)', 'ui-sans-serif', 'system-ui'],
+ data: ['var(--font-data)', 'ui-monospace', 'monospace'],
+ },
+ letterSpacing: {
+ signage: '0.02em',
+ },
+ },
+ },
+ plugins: [],
+} satisfies Config
diff --git a/tasks/00-decisions.md b/tasks/00-decisions.md
new file mode 100644
index 0000000..a1871b3
--- /dev/null
+++ b/tasks/00-decisions.md
@@ -0,0 +1,37 @@
+# Blocking Decisions
+
+All five must resolve before Phase 1 starts. Source: ADR-0001 review notes.
+
+## 1. Which GitOps repo owns the portfolio?
+
+Two roots exist:
+- `homelab-root` → `git@github.com:Riotpiaole/riotpiao.homelab.com.git`, path `k8s/argocd/apps` (31 child Applications, this is the live one)
+- This repo's `infra/argocd-apps.yaml` → `forgejo.riotpiao.homelab.com` (NXDOMAIN, `portfolio`/`auth-infra` Applications don't exist in cluster)
+
+**Decision needed:** GitHub or Forgejo. Blocks Phase 0.1–0.3.
+
+## 2. Apex 403 cause
+
+`riotpiao.com` resolves via Cloudflare (172.67.196.33 / 104.21.60.115) but returns HTTP 403 at the edge, no origin headers.
+
+**Decision needed:** tunnel route missing, WAF rule, or no origin configured at all. Check Cloudflare tunnel Public Hostnames list + WAF event log (event log names the blocking rule). Blocks Phase 0.5.
+
+## 3. Is homarr still wanted?
+
+Deployed and healthy, but shipped under the abandoned Homarr+Terraform plan.
+
+**Decision needed:** keep, or decommission via GitOps (remove Application, let Argo prune).
+
+## 4. Does chat (Surface D) stay in v1?
+
+8-slot GPU ceiling (`--max-num-seqs=4` × 2 replicas) means chat queues under real traffic — a visible "please wait" is a worse first impression than no chat.
+
+**Decision needed:** ship B+E+C first and treat D as separate follow-up, or commit to D in v1 with the queue UX as-is.
+
+## 5. Where does atlas live?
+
+This repo (`riotpiao`) or the homelab repo. Follows from decision 1 — whichever repo is authoritative for the portfolio's GitOps should also own atlas's manifests.
+
+---
+
+Once answered, update this file with the decisions taken (date + rationale) before starting [01-phase0-unblock.md](01-phase0-unblock.md).
diff --git a/tasks/01-phase0-unblock.md b/tasks/01-phase0-unblock.md
new file mode 100644
index 0000000..e03909e
--- /dev/null
+++ b/tasks/01-phase0-unblock.md
@@ -0,0 +1,39 @@
+# Phase 0 — Unblock
+
+Blocking. Nothing ships until this lands. Requires [00-decisions.md](00-decisions.md) #1 and #2 answered first.
+
+## Tasks
+
+- [ ] **0.1** Resolve which GitOps repo owns the portfolio; delete or correct the losing manifest
+ - Depends on: decision #1
+ - Verify: `kubectl get application portfolio -n argocd` shows one, correct, source
+
+- [ ] **0.2** Point `infra/argocd-apps.yaml` `repoURL` and image reference at real hostnames (fix NXDOMAIN)
+ - Verify: `kubectl get pods -n portfolio` → `2/2 Running`
+
+- [ ] **0.3** Replace `:latest` tag with commit-SHA tag in `infra/portfolio/base/deployment.yaml`; keep `imagePullPolicy: IfNotPresent` (correct once tags are immutable)
+ - Verify: new commit → new tag → Argo rolls out automatically, no manual `kubectl set image`
+
+- [ ] **0.4** Diagnose `forgejo-gitea` stuck `Init:0/3` (3h+) — read init container logs before changing anything
+ - Command: `kubectl logs -n cicd -c `
+ - Verify: pod reaches `Running`, image builds succeed
+
+- [ ] **0.5** Diagnose apex 403 — check Cloudflare tunnel Public Hostnames list and WAF event log
+ - Depends on: decision #2
+ - Verify: `curl -sS -o /dev/null -w '%{http_code}\n' https://riotpiao.com` → `200`
+
+- [ ] **0.6** Add Vitest + Testing Library + `msw`; add `test` and `test:watch` scripts to `package.json`
+ - Verify: `pnpm test` → runner executes, 0 tests, exit 0
+
+- [ ] **0.7** Triage unrelated cluster issues: `sms` Application Degraded (`macos-bluebubbles` Pending 3h), `longhorn-config` OutOfSync
+ - Unrelated to atlas, but delivery tree (Phase 3) will render both red on day one — fix or explicitly accept as known-red
+
+## Phase verify
+
+```bash
+kubectl get pods -n portfolio # 2/2 Running
+curl -sS -o /dev/null -w '%{http_code}\n' https://riotpiao.com # 200
+pnpm test # runner executes, 0 tests, exit 0
+```
+
+Next: [02-phase1-atlas-core.md](02-phase1-atlas-core.md)
diff --git a/tasks/02-phase1-atlas-core.md b/tasks/02-phase1-atlas-core.md
new file mode 100644
index 0000000..7949e06
--- /dev/null
+++ b/tasks/02-phase1-atlas-core.md
@@ -0,0 +1,35 @@
+# Phase 1 — atlas core
+
+~4 days. Every surface depends on this. RED → GREEN → REFACTOR.
+
+## RED (write tests first, confirm they fail)
+
+- [ ] `redact_test.go` — golden test: serialized snapshot contains none of the denied fields, run against a fixture captured from the real cluster
+- [ ] `rbac_test.go` — atlas ServiceAccount receives 403 on `get secrets` in every namespace
+- [ ] `snapshot_test.go` — an informer event produces the expected delta
+
+## GREEN
+
+- [ ] ClusterRole: verbs `get,list,watch` only, explicit resource list — no `secrets`, no `*`, no wildcard apiGroups
+- [ ] client-go informers: kube API (nodes, namespaces, workloads), Argo CD `Application` CRs
+- [ ] Reducer: informer events → in-memory snapshot, redacted **at write time**
+- [ ] DTO construction — allowlist only. Emitted: name, namespace, kind, phase, ready counts, restart count, age, node name, health status, sync status, sync wave, explicit label subset. Never emitted: container env/args, image digests/tags, `spec.source.repoURL`, `spec.source.path`, annotations, pod IPs, cluster IPs, Secret names, `status.conditions[].message`, node internal IPs
+- [ ] Redis publish (snapshot deltas → `kmsvc-redis-master.sqs:6379`)
+- [ ] NetworkPolicy on atlas: egress restricted to kube API, `prometheus-operated.monitoring`, `reasoning-predictor.llm-serving`, `kmsvc-redis-master.sqs`; ingress from `ingress-nginx` only
+- [ ] Container hardening: `runAsNonRoot`, read-only root filesystem, all capabilities dropped, `seccompProfile: RuntimeDefault`
+
+## REFACTOR
+
+- [ ] Run `simplify` skill pass on reducer/DTO code
+- [ ] Confirm no `_ =` on errors, no naked returns, every upstream call carries a `context.Context` (go-error-handling, go-context skills)
+
+## Verify
+
+```bash
+kubectl auth can-i get secrets --as=system:serviceaccount:portfolio:atlas # no
+go test ./... -run TestRedact -v
+go test ./... -run TestRBAC -v
+go test ./... -run TestSnapshot -v
+```
+
+Next: [03-phase2-topology.md](03-phase2-topology.md)
diff --git a/tasks/03-phase2-topology.md b/tasks/03-phase2-topology.md
new file mode 100644
index 0000000..ecdddbe
--- /dev/null
+++ b/tasks/03-phase2-topology.md
@@ -0,0 +1,29 @@
+# Phase 2 — Surface B: cluster topology
+
+~3 days. Proves the snapshot + SSE pipeline end to end.
+
+## RED
+
+- [ ] `stream_test.go` — SSE emits a delta within 5s of a pod state change
+- [ ] `topology.test.tsx` — graph re-renders on delta without a full reload
+
+## GREEN
+
+- [ ] `GET /api/topology` — nodes, namespaces, workload summaries; envelope `{"data": {}, "meta": {"snapshotAge", "generation"}}`; capped 256 KB, `meta.truncated: true` on overflow, never a silent drop
+- [ ] `GET /api/stream` — SSE, session cookie, 2 concurrent/IP, `topology` event type; keepalive comment frame every 30s; `Last-Event-ID` supported for resumable deltas
+- [ ] Frontend: React Flow, force layout, node → namespace → workload
+- [ ] Security headers on all responses: CSP (no `unsafe-inline`), `X-Content-Type-Options: nosniff`, `Referrer-Policy: no-referrer`, HSTS; CORS same-origin only
+- [ ] Rate limiting Tier 1 (Cloudflare edge — WAF, Bot Fight Mode, per-IP rules) + Tier 2 (Kong `rate-limiting`, `policy: redis`, generous profile for topology)
+
+## REFACTOR
+
+- [ ] `simplify` pass on SSE handler + React Flow wiring
+
+## Verify
+
+```bash
+# delete a pod, observe graph update in <5s without reloading
+kubectl delete pod -n
+```
+
+Next: [04-phase3-delivery.md](04-phase3-delivery.md)
diff --git a/tasks/04-phase3-delivery.md b/tasks/04-phase3-delivery.md
new file mode 100644
index 0000000..2ed97d0
--- /dev/null
+++ b/tasks/04-phase3-delivery.md
@@ -0,0 +1,31 @@
+# Phase 3 — Surface E: delivery tree
+
+~3 days. Zero new data sources, zero new attack surface, highest signal — reads as platform engineering, not hobby.
+
+## RED
+
+- [ ] `delivery_test.go` — apps group correctly by `sync-wave`; Secret names absent from output (kind+count only); `repoURL` absent from output
+- [ ] `delivery.test.tsx` — 550-node tree renders under frame budget with virtualization on
+
+## GREEN
+
+- [ ] `GET /api/delivery` — Argo apps, wave-grouped (0→8), resource children lazy; capped 256 KB
+- [ ] `GET /api/delivery/{app}/resources` — cursor-paginated at 100 items (prometheus alone has 68 resources today)
+- [ ] Frontend: React Flow, wave columns left→right from `sync-wave` annotations. Click app → side panel with `react-arborist` virtualized resource tree, lazy-loaded children
+- [ ] Live sync animation `OutOfSync → Syncing → Synced` driven by Application watch (reuse Phase 2 SSE `/api/stream`, add `delivery` event type)
+- [ ] Redaction check specific to this surface: 21 `Secret` resources appear in Argo trees today — render kind+count only, never names (includes `sops-secrets`); `status.conditions[].message` echoes raw errors with internal hostnames — emit condition **type** only
+
+## REFACTOR
+
+- [ ] `simplify` pass on wave-grouping + virtualized tree code
+
+## Verify
+
+```bash
+# trigger an Argo sync, observe wave-ordered animation
+argocd app sync homelab-root
+```
+
+Also in scope for this phase: delete fabricated stats in `app/page.tsx` ("40% CPU reduction", "99.2% uptime", "Mission-critical", "60% latency cut") — wire each card to a real number from `/api/topology` or `/api/delivery`, or remove the claim. Five of six landing cards link to routes that don't exist (`/infrastructure`, `/systems`, `/llm`, `/kafka`, `/opensource`) — fix or remove.
+
+Next: [05-phase4-terminal.md](05-phase4-terminal.md)
diff --git a/tasks/05-phase4-terminal.md b/tasks/05-phase4-terminal.md
new file mode 100644
index 0000000..52906ed
--- /dev/null
+++ b/tasks/05-phase4-terminal.md
@@ -0,0 +1,30 @@
+# Phase 4 — Surface C: terminal
+
+~2 days. First surface accepting user input — injection (A03) is the primary risk here.
+
+## RED
+
+- [ ] `exec_parse_test.go` — fuzz corpus: every non-allowlisted input rejects and performs zero upstream calls
+- [ ] `exec_test.go` — unknown namespace rejects on snapshot membership, not regex
+
+## GREEN
+
+- [ ] `POST /api/exec` — session cookie, 20/min/session; input parses to a closed command enum, anything unmatched rejected before any lookup
+- [ ] Command set: `get nodes`, `get pods `, `get apps`, `top nodes`, `describe pod `, `help`
+- [ ] Namespace and resource-name arguments validated by **set membership against current snapshot**, not regex/escaping
+- [ ] No shell, no `exec`, no `kubectl` binary in the container image
+- [ ] Frontend: reuse [components/InteractiveTerminal.tsx](../components/InteractiveTerminal.tsx), wire to `/api/exec`
+- [ ] Structured logging: every rejected `/api/exec` input logged
+
+## REFACTOR
+
+- [ ] `simplify` pass on the enum parser
+
+## Verify
+
+```bash
+# attempt injection payloads against /api/exec; all rejected, all logged
+curl -X POST https://riotpiao.com/api/exec -d '{"cmd":"get pods; rm -rf /"}'
+```
+
+Next: [06-phase5-chat.md](06-phase5-chat.md)
diff --git a/tasks/06-phase5-chat.md b/tasks/06-phase5-chat.md
new file mode 100644
index 0000000..0c082e2
--- /dev/null
+++ b/tasks/06-phase5-chat.md
@@ -0,0 +1,46 @@
+# Phase 5 — Surface D: chat + rate limiter
+
+~5 days, one PR. Highest risk, highest cost — ships last, ships with its limiter, never after.
+
+Depends on [00-decisions.md](00-decisions.md) #4 (is chat in scope for v1).
+
+## RED
+
+- [ ] `ratelimit_test.go` — 7th concurrent chat queues rather than reaching vLLM
+- [ ] `disconnect_test.go` — client abort cancels the upstream request
+- [ ] `budget_test.go` — 13th message in 24h returns `429` with `Retry-After`
+- [ ] `injection_test.go` — snapshot content cannot alter system-prompt behaviour
+- [ ] `context_test.go` — history truncation keeps total tokens under 16384
+
+## GREEN
+
+- [ ] `POST /api/chat` — session + Turnstile, 12/day/session, 6 global concurrent, SSE token stream
+- [ ] Rate limiting Tier 3 (atlas): global chat semaphore = 6 (2 of 8 GPU slots kept as operator headroom); queue depth 20 then reject `429`; per-session budget 12 msg/24h; per-request timeout 120s hard server-side; disconnect cancels upstream immediately (`req.Context()` threaded to vLLM request)
+- [ ] Queue position streamed as SSE `{"type":"queue","position":N}`
+- [ ] Prompt injection defenses: system prompt is compile-time constant, unreachable by user input; cluster snapshot digest injected in a delimited block explicitly labelled untrusted data; user message always last; **no tool-calling** — model reads pre-built digest, cannot query anything; `max_tokens: 1500` cap
+- [ ] Context budget (16384 total): system prompt ~300, snapshot digest capped at 2000, `max_tokens` 1500, ~12500 for history, truncated oldest-first
+- [ ] Chat SSE events: `{"type":"reasoning"|"content"|"queue"|"done"|"error"}` — render `reasoning_content` in collapsible block (this is the demo)
+- [ ] Frontend: new chat component — collapsible reasoning block, queue position, streaming tokens
+- [ ] Prometheus metrics: `atlas_chat_concurrent`, `atlas_chat_queue_depth`, `atlas_ratelimit_rejections_total`, `atlas_snapshot_age_seconds`
+- [ ] Alertmanager rule: chat queue saturated > 5 min, snapshot age > 60s
+- [ ] `pnpm audit` + `govulncheck` in CI, fail build on high severity
+
+## REFACTOR
+
+- [ ] `simplify` pass on rate limiter + SSE chat handler
+
+## Verify
+
+```bash
+# load test at 20 concurrent clients
+# GPU sequence usage never exceeds 6, no upstream 5xx, queue drains
+```
+
+## Done — atlas v1 shipped
+
+Success criteria (from PLAN-atlas.md):
+- [ ] Protected services redirect unauthenticated to Authentik (if still applicable post decision #3)
+- [ ] Fabricated stats gone, real numbers or removed
+- [ ] `riotpiao.com` is the only public hostname (I1 held)
+- [ ] Golden redaction test passes against live-cluster fixture
+- [ ] Load test: 20 concurrent clients, GPU usage ≤ 6, no 5xx, queue drains
diff --git a/tasks/README.md b/tasks/README.md
new file mode 100644
index 0000000..1197a0c
--- /dev/null
+++ b/tasks/README.md
@@ -0,0 +1,32 @@
+# atlas — Task Breakdown
+
+Source of truth: [docs/PLAN-atlas.md](../docs/PLAN-atlas.md), [docs/adr/ADR-0001-atlas-cluster-visualization.md](../docs/adr/ADR-0001-atlas-cluster-visualization.md)
+
+Supersedes: [PLAN.md](../PLAN.md), [IMPLEMENTATION.md](../IMPLEMENTATION.md) (Homarr + Terraform — abandoned)
+
+## Status
+
+Not started. **5 decisions block Phase 1** — see [00-decisions.md](00-decisions.md).
+
+## Phases
+
+| File | Phase | Est. |
+|---|---|---|
+| [00-decisions.md](00-decisions.md) | Blocking decisions (must answer before Phase 1) | — |
+| [01-phase0-unblock.md](01-phase0-unblock.md) | Phase 0 — unblock deployment | — |
+| [02-phase1-atlas-core.md](02-phase1-atlas-core.md) | Phase 1 — atlas core (RBAC, informers, redaction) | ~4d |
+| [03-phase2-topology.md](03-phase2-topology.md) | Phase 2 — Surface B: cluster topology | ~3d |
+| [04-phase3-delivery.md](04-phase3-delivery.md) | Phase 3 — Surface E: delivery tree | ~3d |
+| [05-phase4-terminal.md](05-phase4-terminal.md) | Phase 4 — Surface C: terminal | ~2d |
+| [06-phase5-chat.md](06-phase5-chat.md) | Phase 5 — Surface D: chat + rate limiter | ~5d |
+
+**Total: ~17 working days.**
+
+## Rules carried from the ADR
+
+- I1: `riotpiao.com` is the only public hostname, ever
+- I2: browser never talks to an internal API directly — atlas is the only origin
+- I3: redaction is allowlist-only, enforced by DTO construction
+- I4: no free-form string reaches an internal system (closed enum, snapshot-membership validation)
+- I5: GPU chat concurrency capped at 6 of 8 sequence slots, disconnect cancels upstream immediately
+- TDD: RED (tests named before code) → GREEN (minimal code) → REFACTOR, per phase
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..af02f5d
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,41 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "lib": [
+ "ES2020",
+ "DOM",
+ "DOM.Iterable"
+ ],
+ "jsx": "preserve",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "paths": {
+ "@/*": [
+ "./*"
+ ]
+ },
+ "allowJs": true,
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ "**/*.tsx",
+ "next-env.d.ts",
+ ".next/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo
new file mode 100644
index 0000000..d94e72a
--- /dev/null
+++ b/tsconfig.tsbuildinfo
@@ -0,0 +1 @@
+{"fileNames":["./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es5.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.dom.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/lib/lib.decorators.legacy.d.ts","./.next/types/routes.d.ts","./node_modules/.pnpm/@types+react@19.2.17/node_modules/@types/react/global.d.ts","./node_modules/.pnpm/csstype@3.2.3/node_modules/csstype/index.d.ts","./node_modules/.pnpm/@types+react@19.2.17/node_modules/@types/react/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/amp.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/amp.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/get-page-files.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/compatibility/index.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/globals.typedarray.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/buffer.buffer.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/header.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/readable.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/file.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/fetch.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/formdata.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/connector.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/client.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/errors.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/dispatcher.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/global-dispatcher.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/global-origin.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/pool-stats.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/pool.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/handlers.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/balanced-pool.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/agent.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/mock-interceptor.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/mock-agent.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/mock-client.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/mock-pool.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/mock-errors.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/proxy-agent.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/retry-handler.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/retry-agent.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/api.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/interceptors.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/util.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/cookies.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/patch.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/websocket.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/eventsource.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/filereader.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/content-type.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/cache.d.ts","./node_modules/.pnpm/undici-types@6.19.8/node_modules/undici-types/index.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/globals.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/assert.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/assert/strict.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/async_hooks.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/buffer.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/child_process.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/cluster.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/console.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/constants.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/crypto.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/dgram.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/dns.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/dns/promises.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/domain.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/dom-events.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/events.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/fs.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/fs/promises.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/http.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/http2.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/https.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/inspector.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/module.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/net.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/os.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/path.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/perf_hooks.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/process.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/punycode.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/querystring.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/readline.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/readline/promises.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/repl.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/sea.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/stream.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/stream/promises.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/stream/consumers.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/stream/web.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/string_decoder.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/test.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/timers.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/timers/promises.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/tls.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/trace_events.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/tty.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/url.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/util.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/v8.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/vm.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/wasi.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/worker_threads.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/zlib.d.ts","./node_modules/.pnpm/@types+node@20.17.6/node_modules/@types/node/index.d.ts","./node_modules/.pnpm/@types+react@19.2.17/node_modules/@types/react/canary.d.ts","./node_modules/.pnpm/@types+react@19.2.17/node_modules/@types/react/experimental.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/fallback.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/config.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/body-streams.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/worker.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/constants.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/require-hook.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/page-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/node-environment.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/trace/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/trace/trace.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/trace/shared.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/trace/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/.pnpm/@next+env@15.5.20/node_modules/@next/env/dist/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/telemetry/storage.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/build-context.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack-config.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-kind.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/swc/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/.pnpm/@types+react@19.2.17/node_modules/@types/react/jsx-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/render-result.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/next-url.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/base-http/node.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/with-router.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/router.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/route-loader.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/page-loader.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/client-page.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/search-params.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/.pnpm/@types+react@19.2.17/node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/.pnpm/@types+react@19.2.17/node_modules/@types/react/compiler-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/adapter.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/templates/pages.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/render.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/base-server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/.pnpm/sharp@0.34.5/node_modules/sharp/lib/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/next-server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/next.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/load-components.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/http.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/utils.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/export/routes/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/export/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/export/worker.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/worker.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/build/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/after/after.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/after/after-context.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/params.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request-meta.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/cli/next-test.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/config-shared.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/base-http/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/pages/_app.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/app.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/cache.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/runtime-config.external.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/config.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/pages/_document.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/document.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dynamic.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/pages/_error.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/error.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/head.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/head.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/cookies.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/headers.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/headers.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/image-component.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/image.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/link.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/link.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/redirect.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/not-found.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/components/navigation.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/navigation.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/router.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/client/script.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/script.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/after/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/root-params.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/server/request/connection.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/server.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/types/global.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/types/compiled.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/image-types/global.d.ts","./next-env.d.ts","./node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/source-map.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/previous-map.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/input.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/css-syntax-error.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/declaration.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/root.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/warning.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/lazy-result.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/no-work-result.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/processor.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/result.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/document.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/rule.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/node.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/comment.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/container.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/at-rule.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/list.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/postcss.d.ts","./node_modules/.pnpm/postcss@8.5.19/node_modules/postcss/lib/postcss.d.mts","./node_modules/.pnpm/tailwindcss@3.4.19/node_modules/tailwindcss/types/generated/corepluginlist.d.ts","./node_modules/.pnpm/tailwindcss@3.4.19/node_modules/tailwindcss/types/generated/colors.d.ts","./node_modules/.pnpm/tailwindcss@3.4.19/node_modules/tailwindcss/types/config.d.ts","./node_modules/.pnpm/tailwindcss@3.4.19/node_modules/tailwindcss/types/index.d.ts","./tailwind.config.ts","./lib/clustermock.ts","./lib/motion.ts","./node_modules/.pnpm/lucide-react@0.344.0_react@19.2.7/node_modules/lucide-react/dist/lucide-react.d.ts","./components/header.tsx","./app/layout.tsx","./node_modules/.pnpm/motion-dom@11.18.1/node_modules/motion-dom/dist/index.d.ts","./node_modules/.pnpm/motion-utils@11.18.1/node_modules/motion-utils/dist/index.d.ts","./node_modules/.pnpm/framer-motion@11.18.2_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/framer-motion/dist/index.d.ts","./components/liveindicator.tsx","./components/featurecard.tsx","./components/typewritertext.tsx","./components/heroblobflow.tsx","./components/interactiveterminal.tsx","./components/experiencetimeline.tsx","./app/page.tsx","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/@next/font/dist/types.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/dist/compiled/@next/font/dist/google/index.d.ts","./node_modules/.pnpm/next@15.5.20_@babel+core@7.29.7_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/next/font/google/index.d.ts","./components/cluster/rail.tsx","./components/cluster/slotmeter.tsx","./components/cluster/ribbon.tsx","./app/cluster/layout.tsx","./components/cluster/panel.tsx","./app/cluster/page.tsx","./app/cluster/chat/page.tsx","./app/cluster/delivery/page.tsx","./app/cluster/terminal/page.tsx","./components/animatedroles.tsx","./components/avatarwithblob.tsx","./components/progressivetext.tsx","./.next/types/cache-life.d.ts","./.next/types/validator.ts","./.next/types/app/layout.ts","./.next/types/app/page.ts"],"fileIdsList":[[65,107,296,483],[65,107,296,493],[65,107,400,401,402,403],[65,107],[48,65,107,450,483,493,500,502,503,504,505],[51,65,107,481,498,501],[51,65,107,479,501],[51,65,107,496,497,499],[51,65,107,479,498,501],[65,107,482],[65,107,481,486,488,490,491,492],[65,107,486],[51,65,107],[65,107,424,434],[51,65,107,479,498],[65,107,479],[65,107,424,481,486,487],[51,65,107,424,481],[51,65,107,481,486,489],[51,65,107,486],[48,65,107,451,452],[65,104,107],[65,106,107],[107],[65,107,112,141],[65,107,108,113,119,120,127,138,149],[65,107,108,109,119,127],[60,61,62,65,107],[65,107,110,150],[65,107,111,112,120,128],[65,107,112,138,146],[65,107,113,115,119,127],[65,106,107,114],[65,107,115,116],[65,107,119],[65,107,117,119],[65,106,107,119],[65,107,119,120,121,138,149],[65,107,119,120,121,134,138,141],[65,102,107,154],[65,107,115,119,122,127,138,149],[65,107,119,120,122,123,127,138,146,149],[65,107,122,124,138,146,149],[63,64,65,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155],[65,107,119,125],[65,107,126,149,154],[65,107,115,119,127,138],[65,107,128],[65,107,129],[65,106,107,130],[65,104,105,106,107,108,109,110,111,112,113,114,115,116,117,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155],[65,107,132],[65,107,133],[65,107,119,134,135],[65,107,134,136,150,152],[65,107,119,138,139,140,141],[65,107,138,140],[65,107,138,139],[65,107,141],[65,107,142],[65,104,107,138],[65,107,119,144,145],[65,107,144,145],[65,107,112,127,138,146],[65,107,147],[65,107,127,148],[65,107,122,133,149],[65,107,112,150],[65,107,138,151],[65,107,126,152],[65,107,153],[65,107,112,119,121,130,138,149,152,154],[65,107,138,155],[51,55,65,107,158,395,443],[51,55,65,107,157,395,443],[49,50,65,107],[51,65,107,221,484,485],[57,65,107],[65,107,398],[65,107,405],[65,107,162,176,177,178,180,392],[65,107,162,201,203,205,206,209,392,394],[65,107,162,166,168,169,170,171,172,381,392,394],[65,107,392],[65,107,177,279,362,371,388],[65,107,162],[65,107,159,388],[65,107,213],[65,107,212,392,394],[65,107,122,261,279,308,449],[65,107,122,272,288,371,387],[65,107,122,323],[65,107,375],[65,107,374,375,376],[65,107,374],[59,65,107,122,159,162,166,169,173,174,175,177,181,189,190,316,341,372,392,395],[65,107,162,179,197,201,202,207,208,392,449],[65,107,179,449],[65,107,190,197,259,392,449],[65,107,449],[65,107,162,179,180,449],[65,107,204,449],[65,107,173,373,380],[65,107,133,221,388],[65,107,221,388],[51,65,107,221],[51,65,107,280],[65,107,276,321,388,431,432],[65,107,368,425,426,427,428,430],[65,107,367],[65,107,367,368],[65,107,170,317,318,319],[65,107,317,320,321],[65,107,429],[65,107,317,321],[51,65,107,163,419],[51,65,107,149],[51,65,107,179,249],[51,65,107,179],[65,107,247,251],[51,65,107,248,397],[65,107,494],[51,55,65,107,122,156,157,158,395,441,442],[65,107,122],[65,107,122,166,228,317,327,342,362,377,378,392,393,449],[65,107,189,379],[65,107,395],[65,107,161],[51,65,107,261,275,287,297,299,387],[65,107,133,261,275,296,297,298,387,448],[65,107,290,291,292,293,294,295],[65,107,292],[65,107,296],[65,107,219,220,221,223],[51,65,107,214,215,216,222],[65,107,219,222],[65,107,217],[65,107,218],[51,65,107,221,248,397],[51,65,107,221,396,397],[51,65,107,221,397],[65,107,342,384],[65,107,384],[65,107,122,393,397],[65,107,284],[65,106,107,283],[65,107,191,229,267,269,271,272,273,274,314,317,387,390,393],[65,107,191,305,317,321],[65,107,272,387],[51,65,107,272,281,282,284,285,286,287,288,289,300,301,302,303,304,306,307,387,388,449],[65,107,266],[65,107,122,133,191,192,228,243,273,314,315,316,321,342,362,383,392,393,394,395,449],[65,107,387],[65,106,107,177,270,273,316,383,385,386,393],[65,107,272],[65,106,107,228,233,262,263,264,265,266,267,268,269,271,387,388],[65,107,122,233,234,262,393,394],[65,107,177,316,317,342,383,387,393],[65,107,122,392,394],[65,107,122,138,390,393,394],[65,107,122,133,149,159,166,179,191,192,194,229,230,235,240,243,269,273,317,327,329,332,334,337,338,339,340,341,362,382,383,388,390,392,393,394],[65,107,122,138],[65,107,162,163,164,166,171,174,179,197,382,390,391,395,397,449],[65,107,122,138,149,209,211,213,214,215,216,223,449],[65,107,133,149,159,201,211,239,240,241,242,269,317,332,341,342,348,351,352,362,383,388,390],[65,107,173,174,189,316,341,383,392],[65,107,122,149,163,166,269,346,390,392],[65,107,260],[65,107,122,349,350,359],[65,107,390,392],[65,107,267,270],[65,107,269,273,382,397],[65,107,122,133,195,201,242,332,342,348,351,354,390],[65,107,122,173,189,201,355],[65,107,162,194,357,382,392],[65,107,122,149,392],[65,107,122,179,193,194,195,206,224,356,358,382,392],[59,65,107,191,273,361,395,397],[65,107,122,133,149,166,173,181,189,192,229,235,239,240,241,242,243,269,317,329,342,343,345,347,362,382,383,388,389,390,397],[65,107,122,138,173,348,353,359,390],[65,107,184,185,186,187,188],[65,107,230,333],[65,107,335],[65,107,333],[65,107,335,336],[65,107,122,166,169,170,228,393],[65,107,122,133,161,163,191,229,243,273,325,326,362,390,394,395,397],[65,107,122,133,149,165,170,269,326,389,393],[65,107,262],[65,107,263],[65,107,264],[65,107,388],[65,107,210,226],[65,107,122,166,210,229],[65,107,225,226],[65,107,227],[65,107,210,211],[65,107,210,244],[65,107,210],[65,107,230,331,389],[65,107,330],[65,107,211,388,389],[65,107,328,389],[65,107,211,388],[65,107,314],[65,107,166,171,229,258,261,267,269,273,275,278,309,312,313,317,361,382,390,393],[65,107,252,255,256,257,276,277,321],[51,65,107,221,310,311],[65,107,370],[65,107,177,234,272,273,284,288,317,361,363,364,365,366,368,369,372,382,387,392],[65,107,321],[65,107,325],[65,107,122,229,245,322,324,327,361,390,395,397],[65,107,252,253,254,255,256,257,276,277,321,396],[59,65,107,122,133,149,192,210,211,243,269,273,359,360,362,382,383,392,393,395],[65,107,234,236,239,383],[65,107,122,230,392],[65,107,233,272],[65,107,232],[65,107,234,235],[65,107,231,233,392],[65,107,122,165,234,236,237,238,392,393],[51,65,107,317,318,320],[65,107,196],[51,65,107,163],[51,65,107,388],[51,59,65,107,243,273,395,397],[65,107,163,419,420],[51,65,107,251],[51,65,107,133,149,161,208,246,248,250,397],[65,107,179,388,393],[65,107,344,388],[65,107,317],[51,65,107,120,122,133,161,197,203,251,395,396],[51,65,107,157,158,395,443],[51,52,53,54,55,65,107],[65,107,112],[65,107,198,199,200],[65,107,198],[51,55,65,107,122,124,133,156,157,158,159,161,192,296,354,392,394,397,443],[65,107,407],[65,107,409],[65,107,411],[65,107,495],[65,107,413],[65,107,415,416,417],[65,107,421],[56,58,65,107,399,404,406,408,410,412,414,418,422,424,434,435,437,447,448,449,450],[65,107,423],[65,107,433],[65,107,248],[65,107,436],[65,106,107,234,236,237,239,287,388,438,439,440,443,444,445,446],[65,107,156],[65,107,469],[65,107,467,469],[65,107,458,466,467,468,470,472],[65,107,456],[65,107,459,464,469,472],[65,107,455,472],[65,107,459,460,463,464,465,472],[65,107,459,460,461,463,464,472],[65,107,456,457,458,459,460,464,465,466,468,469,470,472],[65,107,472],[65,107,454,456,457,458,459,460,461,463,464,465,466,467,468,469,470,471],[65,107,454,472],[65,107,459,461,462,464,465,472],[65,107,463,472],[65,107,464,465,469,472],[65,107,457,467],[65,107,138,156],[65,107,474,475],[65,107,473,476],[65,74,78,107,149],[65,74,107,138,149],[65,69,107],[65,71,74,107,146,149],[65,107,127,146],[65,69,107,156],[65,71,74,107,127,149],[65,66,67,70,73,107,119,138,149],[65,74,81,107],[65,66,72,107],[65,74,95,96,107],[65,70,74,107,141,149,156],[65,95,107,156],[65,68,69,107,156],[65,74,107],[65,68,69,70,71,72,73,74,75,76,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,96,97,98,99,100,101,107],[65,74,89,107],[65,74,81,82,107],[65,72,74,82,83,107],[65,73,107],[65,66,69,74,107],[65,74,78,82,83,107],[65,78,107],[65,72,74,77,107,149],[65,66,71,74,81,107],[65,107,138],[65,69,74,95,107,154,156],[65,107,477]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"07f073f19d67f74d732b1adea08e1dc66b1b58d77cb5b43931dee3d798a2fd53","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"109127396ba37e80f44fd7e87ab4db8d0a3635fe1eb00c6c674e3745a8ef6d68","affectsGlobalScope":true},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"dc782ff85b2cb10075ecffc158af7bfb27ff97bf8491c917efea0c3d622d5ac4","impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","impliedFormat":1},{"version":"05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","impliedFormat":1},{"version":"631eff75b0e35d1b1b31081d55209abc43e16b49426546ab5a9b40bdd40b1f60","impliedFormat":1},{"version":"70521b6ab0dcba37539e5303104f29b721bfb2940b2776da4cc818c07e1fefc1","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fd06258805d26c72f5997e07a23155d322d5f05387adb3744a791fe6a0b042d","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"24bd580b5743dc56402c440dc7f9a4f5d592ad7a419f25414d37a7bfe11e342b","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"6bdc71028db658243775263e93a7db2fd2abfce3ca569c3cca5aee6ed5eb186d","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"4d2b0eb911816f66abe4970898f97a2cfc902bcd743cbfa5017fad79f7ef90d8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"e53a3c2a9f624d90f24bf4588aacd223e7bec1b9d0d479b68d2f4a9e6011147f","impliedFormat":1},{"version":"24b8685c62562f5d98615c5a0c1d05f297cf5065f15246edfe99e81ec4c0e011","impliedFormat":1},{"version":"93507c745e8f29090efb99399c3f77bec07db17acd75634249dc92f961573387","impliedFormat":1},{"version":"339dc5265ee5ed92e536a93a04c4ebbc2128f45eeec6ed29f379e0085283542c","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"ca6d304b929748ea15c33f28c1f159df18a94470b424ab78c52d68d40a41e1e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"a72ffc815104fb5c075106ebca459b2d55d07862a773768fce89efc621b3964b","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"3d77c73be94570813f8cadd1f05ebc3dc5e2e4fdefe4d340ca20cd018724ee36","impliedFormat":1},{"version":"d674383111e06b6741c4ad2db962131b5b0fa4d0294b998566c635e86195a453","affectsGlobalScope":true,"impliedFormat":1},{"version":"f3e58c4c18a031cbb17abec7a4ad0bd5ae9fc70c1f4ba1e7fb921ad87c504aca","impliedFormat":1},{"version":"a3e8bafb2af8e850c644f4be7f5156cf7d23b7bfdc3b786bd4d10ed40329649c","impliedFormat":1},{"version":"35ec8b6760fd7138bbf5809b84551e31028fb2ba7b6dc91d95d098bf212ca8b4","affectsGlobalScope":true,"impliedFormat":1},{"version":"a40826e8476694e90da94aa008283a7de50d1dafd37beada623863f1901cb7fb","impliedFormat":1},{"version":"f77d9188e41291acf14f476e931972460a303e1952538f9546e7b370cb8d0d20","affectsGlobalScope":true,"impliedFormat":1},{"version":"b0c0d1d13be149f790a75b381b413490f98558649428bb916fd2d71a3f47a134","impliedFormat":1},{"version":"3c884d9d9ec454bdf0d5a0b8465bf8297d2caa4d853851d92cc417ac6f30b969","impliedFormat":1},{"version":"5a369483ac4cfbdf0331c248deeb36140e6907db5e1daed241546b4a2055f82c","impliedFormat":1},{"version":"e8f5b5cc36615c17d330eaf8eebbc0d6bdd942c25991f96ef122f246f4ff722f","impliedFormat":1},{"version":"f0bd7e6d931657b59605c44112eaf8b980ba7f957a5051ed21cb93d978cf2f45","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"4d7da7075068195f8f127f41c61e304cdca5aafb1be2d0f4fb67c6b4c3e98d50","affectsGlobalScope":true,"impliedFormat":1},{"version":"a4bdde4e601e9554a844e1e0d0ccfa05e183ef9d82ab3ac25f17c1709033d360","impliedFormat":1},{"version":"ad23fd126ff06e72728dd7bfc84326a8ca8cec2b9d2dac0193d42a777df0e7d8","impliedFormat":1},{"version":"9dd9f50652a176469e85fb65aa081d2e7eb807e2c476f378233de4f1f6604962","impliedFormat":1},{"version":"93bd413918fa921c8729cef45302b24d8b6c7855d72d5bf82d3972595ae8dcbf","impliedFormat":1},{"version":"4ff41188773cbf465807dd2f7059c7494cbee5115608efc297383832a1150c43","impliedFormat":1},{"version":"dccdf1677e531e33f8ac961a68bc537418c9a414797c1ea7e91307501cdc3f5e","impliedFormat":1},{"version":"7edec695cdb707c7146ac34c44ca364469c7ea504344b3206c686e79f61b61a2","affectsGlobalScope":true,"impliedFormat":1},{"version":"d206b4baf4ddcc15d9d69a9a2f4999a72a2c6adeaa8af20fa7a9960816287555","impliedFormat":1},{"version":"93f437e1398a4f06a984f441f7fa7a9f0535c04399619b5c22e0b87bdee182cb","impliedFormat":1},{"version":"afbe24ab0d74694372baa632ecb28bb375be53f3be53f9b07ecd7fc994907de5","impliedFormat":1},{"version":"70731d10d5311bd4cf710ef7f6539b62660f4b0bfdbb3f9fbe1d25fe6366a7fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"a20f1e119615bf7632729fd89b6c0b5ffdc2df3b512d6304146294528e3ebe19","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e043a1bc8fbf2a255bccf9bf27e0f1caf916c3b0518ea34aa72357c0afd42ec","impliedFormat":1},{"version":"137c2894e8f3e9672d401cc0a305dc7b1db7c69511cf6d3970fb53302f9eae09","impliedFormat":1},{"version":"3bc2f1e2c95c04048212c569ed38e338873f6a8593930cf5a7ef24ffb38fc3b6","impliedFormat":1},{"version":"8145e07aad6da5f23f2fcd8c8e4c5c13fb26ee986a79d03b0829b8fce152d8b2","impliedFormat":1},{"version":"f9d9d753d430ed050dc1bf2667a1bab711ccbb1c1507183d794cc195a5b085cc","impliedFormat":1},{"version":"9eece5e586312581ccd106d4853e861aaaa1a39f8e3ea672b8c3847eedd12f6e","impliedFormat":1},{"version":"235bfb54b4869c26f7e98e3d1f68dbfc85acf4cf5c38a4444a006fbf74a8a43d","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"93452d394fdd1dc551ec62f5042366f011a00d342d36d50793b3529bfc9bd633","impliedFormat":1},{"version":"bb715efb4857eb94539eafb420352105a0cff40746837c5140bf6b035dd220ba","affectsGlobalScope":true,"impliedFormat":1},{"version":"1851a3b4db78664f83901bb9cac9e45e03a37bb5933cc5bf37e10bb7e91ab4eb","impliedFormat":1},{"version":"fdedf82878e4c744bc2a1c1e802ae407d63474da51f14a54babe039018e53d8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"08353b04a3501d84fc8d7b49de99f6c1cc26026e6d9d697a18315f3bfe92ed03","affectsGlobalScope":true,"impliedFormat":1},{"version":"578d8bb6dcb2a1c03c4c3f8eb71abc9677e1a5c788b7f24848e3138ce17f3400","impliedFormat":1},{"version":"4f029899f9bae07e225c43aef893590541b2b43267383bf5e32e3a884d219ed5","impliedFormat":1},{"version":"ae56f65caf3be91108707bd8dfbccc2a57a91feb5daabf7165a06a945545ed26","impliedFormat":1},{"version":"a136d5de521da20f31631a0a96bf712370779d1c05b7015d7019a9b2a0446ca9","impliedFormat":1},{"version":"5b566927cad2ed2139655d55d690ffa87df378b956e7fe1c96024c4d9f75c4cf","affectsGlobalScope":true,"impliedFormat":1},{"version":"bce947017cb7a2deebcc4f5ba04cead891ce6ad1602a4438ae45ed9aa1f39104","affectsGlobalScope":true,"impliedFormat":1},{"version":"efeedd8bbc5c0d53e760d8b120a010470722982e6ae14de8d1bcff66ebc2ae71","impliedFormat":1},{"version":"e2c72c065a36bc9ab2a00ac6a6f51e71501619a72c0609defd304d46610487a4","impliedFormat":1},{"version":"d91a7d8b5655c42986f1bdfe2105c4408f472831c8f20cf11a8c3345b6b56c8c","impliedFormat":1},{"version":"616075a6ac578cf5a013ee12964188b4412823796ce0b202c6f1d2e4ca8480d7","affectsGlobalScope":true,"impliedFormat":1},{"version":"e8a979b8af001c9fc2e774e7809d233c8ca955a28756f52ee5dee88ccb0611d2","impliedFormat":1},{"version":"cac793cc47c29e26e4ac3601dcb00b4435ebed26203485790e44f2ad8b6ad847","impliedFormat":1},{"version":"2beff543f6e9a9701df88daeee3cdd70a34b4a1c11cb4c734472195a5cb2af54","impliedFormat":1},{"version":"2e07abf27aa06353d46f4448c0bbac73431f6065eef7113128a5cd804d0c384d","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"829b9e6028b29e6a8b1c01ddb713efe59da04d857089298fa79acbdb3cfcfdef","impliedFormat":1},{"version":"24f8562308dd8ba6013120557fa7b44950b619610b2c6cb8784c79f11e3c4f90","impliedFormat":1},{"version":"5f90b8c733a1bda63e42160b15a2301051e83a6f9d5332a59d16eb12f463270d","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"5178eb4415a172c287c711dc60a619e110c3fd0b7de01ed0627e51a5336aa09c","impliedFormat":1},{"version":"ca6e5264278b53345bc1ce95f42fb0a8b733a09e3d6479c6ccfca55cdc45038c","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"98b18458acb46072947aabeeeab1e410f047e0cacc972943059ca5500b0a5e95","impliedFormat":1},{"version":"361e2b13c6765d7f85bb7600b48fde782b90c7c41105b7dab1f6e7871071ba20","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"b6db56e4903e9c32e533b78ac85522de734b3d3a8541bf24d256058d464bf04b","impliedFormat":1},{"version":"24daa0366f837d22c94a5c0bad5bf1fd0f6b29e1fae92dc47c3072c3fdb2fbd5","impliedFormat":1},{"version":"570bb5a00836ffad3e4127f6adf581bfc4535737d8ff763a4d6f4cc877e60d98","impliedFormat":1},{"version":"889c00f3d32091841268f0b994beba4dceaa5df7573be12c2c829d7c5fbc232c","impliedFormat":1},{"version":"65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"27ab780875bcbb65e09da7496f2ca36288b0c541abaa75c311450a077d54ec15","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"208c9af9429dd3c76f5927b971263174aaa4bc7621ddec63f163640cbd3c473c","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"a23185bc5ef590c287c28a91baf280367b50ae4ea40327366ad01f6f4a8edbc5","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"002eae065e6960458bda3cf695e578b0d1e2785523476f8a9170b103c709cd4f","impliedFormat":1},{"version":"c83bb0c9c5645a46c68356c2f73fdc9de339ce77f7f45a954f560c7e0b8d5ebb","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"6a148329edecbda07c21098639ef4254ef7869fb25a69f58e5d6a8b7b69d4236","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"f63ab283a1c8f5c79fabe7ca4ef85f9633339c4f0e822fce6a767f9d59282af2","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"a54c996c8870ef1728a2c1fa9b8eaec0bf4a8001cd2583c02dd5869289465b10","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"3754982006a3b32c502cff0867ca83584f7a43b1035989ca73603f400de13c96","impliedFormat":1},{"version":"a30ae9bb8a8fa7b90f24b8a0496702063ae4fe75deb27da731ed4a03b2eb6631","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"b838d4c72740eb0afd284bf7575b74c624b105eff2e8c7b4aeead57e7ac320ff","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"e9dd71cf12123419c60dab867d44fbee5c358169f99529121eaef277f5c83531","impliedFormat":1},{"version":"5b6a189ba3a0befa1f5d9cb028eb9eec2af2089c32f04ff50e2411f63d70f25d","impliedFormat":1},{"version":"d6e73f8010935b7b4c7487b6fb13ea197cc610f0965b759bec03a561ccf8423a","impliedFormat":1},{"version":"174f3864e398f3f33f9a446a4f403d55a892aa55328cf6686135dfaf9e171657","impliedFormat":1},{"version":"824c76aec8d8c7e65769688cbee102238c0ef421ed6686f41b2a7d8e7e78a931","impliedFormat":1},{"version":"75b868be3463d5a8cfc0d9396f0a3d973b8c297401d00bfb008a42ab16643f13","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"6dcf60530c25194a9ee0962230e874ff29d34c59605d8e069a49928759a17e0a","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"1a42d2ec31a1fe62fdc51591768695ed4a2dc64c01be113e7ff22890bebb5e3f","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"0c7c947ff881c4274c0800deaa0086971e0bfe51f89a33bd3048eaa3792d4876","affectsGlobalScope":true,"impliedFormat":1},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"15b36126e0089bfef173ab61329e8286ce74af5e809d8a72edcafd0cc049057f","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"72d63643a657c02d3e51cd99a08b47c9b020a565c55f246907050d3c8a5e77fb","impliedFormat":1},{"version":"1d415445ea58f8033ba199703e55ff7483c52ac6742075b803bd3e7bbe9f5d61","impliedFormat":1},{"version":"d6406c629bb3efc31aedb2de809bef471e475c86c7e67f3ef9b676b5d7e0d6b2","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"71d8ba39a9e024d9e4bb922464d18542ed8d2c25ee78efa7890c27213cc6e5d3","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"dafc31e9e8751f437122eb8582b93d477e002839864410ff782504a12f2a550c","impliedFormat":1},{"version":"754498c5208ce3c5134f6eabd49b25cf5e1a042373515718953581636491f3c3","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"633d58a237f4bb25ec7d565e4ffa32cecdcee8660ac12189c4351c52557cee9e","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","impliedFormat":1},{"version":"ce791f6ea807560f08065d1af6014581eeb54a05abd73294777a281b6dfd73c2","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"e17cd049a1448de4944800399daa4a64c5db8657cc9be7ef46be66e2a2cd0e7c","impliedFormat":1},{"version":"43fa6ea8714e18adc312b30450b13562949ba2f205a1972a459180fa54471018","impliedFormat":1},{"version":"6e89c2c177347d90916bad67714d0fb473f7e37fb3ce912f4ed521fe2892cd0d","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"4d4927cbee21750904af7acf940c5e3c491b4d5ebc676530211e389dd375607a","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"8a97e578a9bc40eb4f1b0ca78f476f2e9154ecbbfd5567ee72943bab37fc156a","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"f22d05663d873ee7a600faf78abb67f3f719d32266803440cf11d5db7ac0cab2","impliedFormat":1},{"version":"d93c544ad20197b3976b0716c6d5cd5994e71165985d31dcab6e1f77feb4b8f2","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"a8b1c79a833ee148251e88a2553d02ce1641d71d2921cce28e79678f3d8b96aa","impliedFormat":1},{"version":"126d4f950d2bba0bd45b3a86c76554d4126c16339e257e6d2fabf8b6bf1ce00c","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"2d3cc2211f352f46ea6b7cf2c751c141ffcdf514d6e7ae7ee20b7b6742da313f","impliedFormat":1},{"version":"c75445151ff8b77d9923191efed7203985b1a9e09eccf4b054e7be864e27923d","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"fa8a8fbf91ee2a4779496225f0312aac6635b0f21aa09cdafa4283fe32d519c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e8aef93d79b000deb6ec336b5645c87de167168e184e84521886f9ecc69a4b5","impliedFormat":1},{"version":"c30436b130b6218b7714314dc41d3f459590db4bdf099eecd51cb1bda32109a8","impliedFormat":1},{"version":"20fa37b636fdcc1746ea0738f733d0aed17890d1cd7cb1b2f37010222c23f13e","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"de7052bfee2981443498239a90c04ea5cc07065d5b9bb61b12cb6c84313ad4ef","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"4a2edd238d9104eac35b60d727f1123de5062f452b70ed8e0366cb36387dfdfd","impliedFormat":1},{"version":"ca921bf56756cb6fe957f6af693a35251b134fb932dc13f3dfff0bb7106f80b4","impliedFormat":1},{"version":"fee92c97f1aa59eb7098a0cc34ff4df7e6b11bae71526aca84359a2575f313d8","impliedFormat":1},{"version":"0bd0297484aacea217d0b76e55452862da3c5d9e33b24430e0719d1161657225","impliedFormat":1},{"version":"2ab6d334bcbf2aff3acfc4fd8c73ecd82b981d3c3aa47b3f3b89281772286904","impliedFormat":1},{"version":"d07cbc787a997d83f7bde3877fec5fb5b12ce8c1b7047eb792996ed9726b4dde","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"49179c6a23701c642bd99abe30d996919748014848b738d8e85181fc159685ff","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"8514c62ce38e58457d967e9e73f128eedc1378115f712b9eef7127f7c88f82ae","impliedFormat":1},{"version":"f1289e05358c546a5b664fbb35a27738954ec2cc6eb4137350353099d154fc62","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"1d17ba45cfbe77a9c7e0df92f7d95f3eefd49ee23d1104d0548b215be56945ad","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"bd5f641cc4616eee49497a362c4cb401e9346265bc52670448c4452b4d9be401","impliedFormat":1},{"version":"46273e8c29816125d0d0b56ce9a849cc77f60f9a5ba627447501d214466f0ff3","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"e91f7b1344577a02f051b9b471f33044fef8334a76dc9e1de003d17595a5219b","impliedFormat":1},{"version":"3af3584f79c57853028ef9421ec172539e1fe01853296dc05a9d615ade4ffaf6","impliedFormat":1},{"version":"f82579d87701d639ff4e3930a9b24f4ee13ca74221a9a3a792feb47f01881a9c","impliedFormat":1},{"version":"d7e5d5245a8ba34a274717d085174b2c9827722778129b0081fefd341cca8f55","impliedFormat":1},{"version":"d9d32f94056181c31f553b32ce41d0ef75004912e27450738d57efcd2409c324","impliedFormat":1},{"version":"752513f35f6cff294ffe02d6027c41373adf7bfa35e593dbfd53d95c203635ee","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"1a7e2ea171726446850ec72f4d1525d547ff7e86724cc9e7eec509725752a758","impliedFormat":1},{"version":"8c901126d73f09ecdea4785e9a187d1ac4e793e07da308009db04a7283ec2f37","impliedFormat":1},{"version":"c1de754ab5f3b0f4036d6893c74a0fc984c7fcb07936086f19bbe2974406775b","impliedFormat":1},{"version":"aab290b8e4b7c399f2c09b957666fc95335eb4522b2dd9ead1bf0cb64da6d6ee","impliedFormat":1},{"version":"94fe3281392e1015b22f39535878610b4fa6f1388dc8d78746be3bc4e4bb8950","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"06c25ddfc2242bd06c19f66c9eae4c46d937349a267810f89783680a1d7b5259","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"0427df5c06fafc5fe126d14b9becd24160a288deff40e838bfbd92a35f8d0d00","impliedFormat":1},{"version":"90c54a02432d04e4246c87736e53a6a83084357acfeeba7a489c5422b22f5c7a","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"0a372c2d12a259da78e21b25974d2878502f14d89c6d16b97bd9c5017ab1bc12","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"ec1ca97598eda26b7a5e6c8053623acbd88e43be7c4d29c77ccd57abc4c43999","impliedFormat":1},{"version":"6e2261cd9836b2c25eecb13940d92c024ebed7f8efe23c4b084145cd3a13b8a6","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"a47e6d954d22dd9ebb802e7e431b560ed7c581e79fb885e44dc92ed4f60d4c07","impliedFormat":1},{"version":"f019e57d2491c159d47a107fd90219a1734bdd2e25cd8d1db3c8fae5c6b414c4","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d1c9bf292a54312888a77bb19dba5e2503ad803f5393beafd45d78d2f4fe9b48","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"cb8d8ef7b9ce8ed3e6f1c814fcbf3f90dab0cb8863079236784fc350746e27c4","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"3be035da7bee86b4c3abf392e0edaa44fc6e45092995eefe36b39118c8a84068","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f828825d077c2fa0ea606649faeb122749273a353daab23924fe674e98ba44c","impliedFormat":1},{"version":"2896c2e673a5d3bd9b4246811f79486a073cbb03950c3d252fba10003c57411a","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"407a06ba04eede4074eec470ecba2784cbb3bf4e7de56833b097dd90a2aa0651","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"5c96bad5f78466785cdad664c056e9e2802d5482ca5f862ed19ba34ffbb7b3a4","impliedFormat":1},{"version":"81d8603ac527e75cfec72bb9391228b58f161c2b33514a9d814c7f3ebd3ef466","impliedFormat":1},{"version":"5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","impliedFormat":1},{"version":"bb0cd7862b72f5eba39909c9889d566e198fcaddf7207c16737d0c2246112678","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"bad68fd0401eb90fe7da408565c8aee9c7a7021c2577aec92fa1382e8876071a","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"fec01479923e169fb52bd4f668dbeef1d7a7ea6e6d491e15617b46f2cacfa37d","impliedFormat":1},{"version":"8a8fb3097ba52f0ae6530ec6ab34e43e316506eb1d9aa29420a4b1e92a81442d","impliedFormat":1},{"version":"44e09c831fefb6fe59b8e65ad8f68a7ecc0e708d152cfcbe7ba6d6080c31c61e","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"4655709c9cb3fd6db2b866cab7c418c40ed9533ce8ea4b66b5f17ec2feea46a9","impliedFormat":1},{"version":"87affad8e2243635d3a191fa72ef896842748d812e973b7510a55c6200b3c2a4","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"3eecb25bb467a948c04874d70452b14ae7edb707660aac17dc053e42f2088b00","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"5f0292a40df210ab94b9fb44c8b775c51e96777e14e073900e392b295ca1061b","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"8627ad129bcf56e82adff0ab5951627c993937aa99f5949c33240d690088b803","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"ecbaf0da125974be39c0aac869e403f72f033a4e7fd0d8cd821a8349b4159628","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"ceec3c81b2d81f5e3b855d9367c1d4c664ab5046dff8fd56552df015b7ccbe8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"1d63055b690a582006435ddd3aa9c03aac16a696fac77ce2ed808f3e5a06efab","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},"85ae5aee75f011967cf2d25cbc342f62d69314e9d925f7f4aa3456fc2cffcca6",{"version":"402e5c534fb2b85fa771170595db3ac0dd532112c8fa44fc23f233bc6967488b","impliedFormat":1},{"version":"52dcc257df5119fb66d864625112ce5033ac51a4c2afe376a0b299d2f7f76e4a","impliedFormat":1},{"version":"e5bab5f871ef708d52d47b3e5d0aa72a08ee7a152f33931d9a60809711a2a9a3","impliedFormat":1},{"version":"e16dc2a81595736024a206c7d5c8a39bfe2e6039208ef29981d0d95434ba8fcf","impliedFormat":1},{"version":"cc4a4903fb698ca1d961d4c10dce658aa3a479faf40509d526f122b044eaf6a4","impliedFormat":1},{"version":"19ee8416e6473ed6c7adb868fa796b5653cf0fa2a337658e677eaa0d134388c3","impliedFormat":1},{"version":"1328ab4e442614b28cdb3d4b414cf68325c0da0dca07287a338d0654b7a00261","impliedFormat":1},{"version":"a039dc21f045919f3cbee2ec13812cc6cc3eebc99dae4be00973230f468d19a6","impliedFormat":1},{"version":"3fbe57af01460e49dcd29df55d6931e1672bc6f1be0fb073d11410bc16f9037d","impliedFormat":1},{"version":"f760be449e8562ec5c09bb5187e8e1eabf3c113c0c58cddda53ef8c69f3e2131","impliedFormat":1},{"version":"44325ed13294fce6ab825b82947bbeed2611db7dad9d9135260192f375e5a189","impliedFormat":1},{"version":"e392e8fb5b514eafc585601c1d781485aa6dd6a320e75daf1064a4c6918a1b45","impliedFormat":1},{"version":"46e4a36e8ddbdfb4e7330e11c81c970dc8b218611df9183d39c41c5f8c653b55","impliedFormat":1},{"version":"370bde134aa8c2abc926d0e99d3a4d5d5dba65c6ee65459137e4f02670cbf841","impliedFormat":1},{"version":"6332f565867cf4a740a70e30f31cefba37ef7cebcf74f22eab8d744fde6d193e","impliedFormat":1},{"version":"2977b7884aedc895a1d0c9c210c7cf3272c29d6959a08a6fa3ff71e0aff08175","impliedFormat":1},{"version":"17f2922d41ddd032830a91371c948cd9ce903b35c95adca72271a54584f19b0b","impliedFormat":1},{"version":"3eed76ede2a1a14d7c9bb0a642041282dcc264811139d3dd275c9fe14efc9840","impliedFormat":1},{"version":"354a7f8e1287d9d6b7561bc97fdd8cbc2f7c1dd79e4cb37b942e8a5cfaff1085","impliedFormat":1},{"version":"8d369483f0c2b9ee388129cfdb6a43bc8112b377e86a41884bd06e19ce04f4c1","impliedFormat":99},{"version":"b558c9a18ea4e6e4157124465c3ef1063e64640da139e67be5edb22f534f2f08","impliedFormat":1},{"version":"01374379f82be05d25c08d2f30779fa4a4c41895a18b93b33f14aeef51768692","impliedFormat":1},{"version":"b0dee183d4e65cf938242efaf3d833c6b645afb35039d058496965014f158141","impliedFormat":1},{"version":"c0bbbf84d3fbd85dd60d040c81e8964cc00e38124a52e9c5dcdedf45fea3f213","impliedFormat":1},"9b9ebdcead5cc5f8e798e50e09475a6ca04797794ccd9bbc2cc8d686b9cdd808","7fd6be4d75955be6d1fd17075e4822b658dee11f9d83225362f6884b312bc83a","fdaf6138b6cf8b2f3fb072abaabbeff110b3c191e0ba6929b3a6f7313d7e1100",{"version":"46c9b97d2cf765a080a86b1b9bf1c240f9b02ecc2cc1ef5168f20207d9559c27","impliedFormat":1},"9aaa4b233ce7b56fdc6f0ac29084e357fd59d9fd46903360c4b1a97060d74508","034ae4fc3fa3ef2c62199983dabe4a511227c29a68512e6c79174981b69a86d2",{"version":"38479e9851ea5f43f60baaa6bc894a49dba0a74dd706ce592d32bcb8b59e3be9","affectsGlobalScope":true,"impliedFormat":1},{"version":"9592f843d45105b9335c4cd364b9b2562ce4904e0895152206ac4f5b2d1bb212","impliedFormat":1},{"version":"f9ff719608ace88cae7cb823f159d5fb82c9550f2f7e6e7d0f4c6e41d4e4edb4","affectsGlobalScope":true,"impliedFormat":1},"f94faae0bc512052b1d4aa90842c98502d4aebe5044bbb67d3d2552d999cce2a","95f233e11c2bcc80dc0f755c7857f48ba993b76557a131c44c909b44cbcc08ac","7b5dd0efc2d141ef050b3afa01f96c0097e39221b11ebfaec6de3c1b59d63fd6","c92ad1145a34836bf1a2cba9599cfe0bf845e45abbee192bfc3768dd052a1d29","3a9097df1b2da10feda9839d069571db0919006d4192890047a2ecaffb16072e","7e460f5ec9551d2e0299e454bd933ce6745a473a1af4e9165c4a0fe86548ee21","bcc0d29a64a7f203284a0a1bd0bd1bebb3461e9b4713bfe3c502193e94d8d5fb",{"version":"fe93c474ab38ac02e30e3af073412b4f92b740152cf3a751fdaee8cbea982341","impliedFormat":1},{"version":"476e83e2c9e398265eed2c38773ae9081932b08ea5597b579a7d2e0c690ead56","impliedFormat":1},{"version":"1e00b8bf9e3766c958218cd6144ffe08418286f89ff44ba5a2cc830c03dd22c7","impliedFormat":1},"e1fa7d2e51b1e5964e0c8b6cf33f183a61474bf1d1ed1c5c7bf091079c0eb6ab","87bfcd23f76152b0087f615c14bea11353a62fdbd6801066a67b0bd6d32ecef8",{"version":"8f91ab5d80504b34199ad14708b072218070d67f28ac30d4862e4b7a9c36bd8b","signature":"d180d68c7d633b1dcbab4337bddb37defdb1f619138c213a8b94514447642cb0"},"3759f1af697b70bee30c1c6bdae161a12b636c3c62d5de6aeed7c896e46aea78","f12ad60084fef762769281ad7cfba714b35217d1c2836fbf869f56df804d026e","76ea4e1c849b503ce2928e8e85af543784a3bcce0b93917b4cb8b2e42bdd4ff6","51d3b70e87a070cc6a7c8ccebd1a6d85015d405401c3e3bf3889d72258730717","b676cc8c45a53ad31408b5e9b1fafd5626ea9f6a08232506c769b6fc5501d8b7","9122592bd9a11ba946cdcccaea1df55bf5b8d4b0112b3801292420d9a8c835ca","418ec6051df3ac913c852bdc896383185dcaebd5fb868f2f0e340b18a79c965c","964974a2f5deeee89c241f899870602e9051d1cfa5f68d552fca50daa0b77344","5b340550f3f38178144eec977620b38ed2d53fd407c20a9427c8548ae3d6c430","2552a31fad45a9ed1bde87e51b038dc0e786cd364b597162263abbf57018949b","5b1189a6d3be7e6693601d77d31daad874e82156d164121ac051be5438604a46","f19679bfdc60484b3466ac560ddb176f1780d314f8ecdaa635d0a6e350132218","0014919aa6764083952c0397511d2ad55c49baa4aeec7355fe0047a6548330b1"],"root":[48,453,[478,480],482,483,[487,493],[497,512]],"options":{"allowJs":true,"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":true,"target":7},"referencedMap":[[511,1],[512,2],[509,3],[48,4],[510,5],[503,6],[504,7],[500,8],[502,9],[505,7],[483,10],[493,11],[506,12],[507,12],[501,13],[497,14],[499,15],[498,16],[492,12],[488,17],[482,18],[490,19],[491,20],[487,12],[508,12],[489,20],[479,4],[480,4],[453,21],[203,4],[104,22],[105,22],[106,23],[65,24],[107,25],[108,26],[109,27],[60,4],[63,28],[61,4],[62,4],[110,29],[111,30],[112,31],[113,32],[114,33],[115,34],[116,34],[118,35],[117,36],[119,37],[120,38],[121,39],[103,40],[64,4],[122,41],[123,42],[124,43],[156,44],[125,45],[126,46],[127,47],[128,48],[129,49],[130,50],[131,51],[132,52],[133,53],[134,54],[135,54],[136,55],[137,4],[138,56],[140,57],[139,58],[141,59],[142,60],[143,61],[144,62],[145,63],[146,64],[147,65],[148,66],[149,67],[150,68],[151,69],[152,70],[153,71],[154,72],[155,73],[157,74],[311,4],[158,75],[49,4],[51,76],[310,13],[221,13],[50,4],[486,77],[481,13],[484,4],[485,4],[58,78],[399,79],[404,3],[406,80],[179,81],[207,82],[382,83],[202,84],[190,4],[171,4],[177,4],[372,85],[238,86],[178,4],[341,87],[212,88],[213,89],[309,90],[369,91],[324,92],[376,93],[377,94],[375,95],[374,4],[373,96],[209,97],[180,98],[259,4],[260,99],[175,4],[191,100],[181,101],[243,100],[240,100],[164,100],[205,102],[204,4],[381,103],[391,4],[170,4],[285,104],[286,105],[280,13],[427,4],[288,4],[289,106],[281,107],[433,108],[431,109],[426,4],[368,110],[367,4],[425,111],[282,13],[320,112],[318,113],[428,4],[432,4],[430,114],[429,4],[319,115],[420,116],[423,117],[250,118],[249,119],[248,120],[436,13],[247,121],[232,4],[439,4],[495,122],[494,4],[442,4],[441,13],[443,123],[160,4],[378,124],[379,125],[380,126],[193,4],[169,127],[159,4],[301,13],[162,128],[300,129],[299,130],[290,4],[291,4],[298,4],[293,4],[296,131],[292,4],[294,132],[297,133],[295,132],[176,4],[167,4],[168,100],[222,134],[223,135],[220,136],[218,137],[219,138],[215,4],[307,106],[326,106],[398,139],[407,140],[411,141],[385,142],[384,4],[235,4],[444,143],[394,144],[283,145],[284,146],[275,147],[265,4],[306,148],[266,149],[308,150],[303,151],[302,4],[304,4],[317,152],[386,153],[387,154],[268,155],[272,156],[263,157],[364,158],[393,159],[242,160],[342,161],[165,162],[392,163],[161,84],[216,4],[224,164],[353,165],[214,4],[352,166],[59,4],[347,167],[192,4],[261,168],[343,4],[166,4],[225,4],[351,169],[174,4],[230,170],[271,171],[383,172],[270,4],[350,4],[217,4],[355,173],[356,174],[172,4],[358,175],[360,176],[359,177],[195,4],[349,162],[362,178],[348,179],[354,180],[183,4],[186,4],[184,4],[188,4],[185,4],[187,4],[189,181],[182,4],[334,182],[333,4],[339,183],[335,184],[338,185],[337,185],[340,183],[336,184],[229,186],[327,187],[390,188],[446,4],[415,189],[417,190],[267,4],[416,191],[388,153],[445,192],[287,153],[173,4],[269,193],[226,194],[227,195],[228,196],[258,197],[363,197],[244,197],[328,198],[245,198],[211,199],[210,4],[332,200],[331,201],[330,202],[329,203],[389,204],[279,205],[314,206],[278,207],[312,208],[313,208],[371,209],[370,210],[366,211],[323,212],[325,213],[322,214],[361,215],[316,4],[403,4],[315,216],[365,4],[231,217],[264,124],[262,218],[233,219],[236,220],[440,4],[234,221],[237,221],[401,4],[400,4],[402,4],[438,4],[239,222],[277,13],[57,4],[321,223],[208,4],[197,224],[273,4],[409,13],[419,225],[257,13],[413,106],[256,226],[396,227],[255,225],[163,4],[421,228],[253,13],[254,13],[246,4],[196,4],[252,229],[251,230],[194,231],[274,53],[241,53],[357,4],[345,232],[344,4],[405,4],[305,233],[276,13],[397,234],[52,13],[55,235],[56,236],[53,13],[54,4],[206,237],[201,238],[200,4],[199,239],[198,4],[395,240],[408,241],[410,242],[412,243],[496,244],[414,245],[418,246],[452,247],[422,247],[451,248],[424,249],[434,250],[435,251],[437,252],[447,253],[450,127],[449,4],[448,254],[470,255],[468,256],[469,257],[457,258],[458,256],[465,259],[456,260],[461,261],[471,4],[462,262],[467,263],[473,264],[472,265],[455,266],[463,267],[464,268],[459,269],[466,255],[460,270],[346,271],[454,4],[476,272],[475,4],[474,4],[477,273],[46,4],[47,4],[8,4],[9,4],[11,4],[10,4],[2,4],[12,4],[13,4],[14,4],[15,4],[16,4],[17,4],[18,4],[19,4],[3,4],[20,4],[21,4],[4,4],[22,4],[26,4],[23,4],[24,4],[25,4],[27,4],[28,4],[29,4],[5,4],[30,4],[31,4],[32,4],[33,4],[6,4],[37,4],[34,4],[35,4],[36,4],[38,4],[7,4],[39,4],[44,4],[45,4],[40,4],[41,4],[42,4],[43,4],[1,4],[81,274],[91,275],[80,274],[101,276],[72,277],[71,278],[100,254],[94,279],[99,280],[74,281],[88,282],[73,283],[97,284],[69,285],[68,254],[98,286],[70,287],[75,288],[76,4],[79,288],[66,4],[102,289],[92,290],[83,291],[84,292],[86,293],[82,294],[85,295],[95,254],[77,296],[78,297],[87,298],[67,299],[90,290],[89,288],[93,4],[96,300],[478,301]],"affectedFilesPendingEmit":[511,512,510,503,504,500,502,505,483,493,506,507,501,497,499,498,492,488,482,490,491,487,508,489,479,480,478],"version":"5.8.2"}
\ No newline at end of file