first commit
This commit is contained in:
commit
3dcd8e5e3b
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/versions
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
36
README.md
Normal file
36
README.md
Normal file
@ -0,0 +1,36 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
177
app/expo/page.tsx
Normal file
177
app/expo/page.tsx
Normal file
@ -0,0 +1,177 @@
|
||||
"use client";
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { X } from "lucide-react";
|
||||
import clsx from "clsx";
|
||||
|
||||
// 展台四模块视频配置(请将对应 mp4/webm 文件放入 public/videos/ 下)
|
||||
const videos = [
|
||||
{
|
||||
key: "mechanics",
|
||||
title: "力学 · 单摆高精度测量",
|
||||
src: "/videos/mechanics.mp4",
|
||||
desc: "CV 追踪 + AI 拟合:g 误差压至 0.43%,提取阻尼 γ 与品质因数 Q。探究傅科摆效应。"
|
||||
},
|
||||
{
|
||||
key: "circuit",
|
||||
title: "电路 · 实物 → 虚拟转换",
|
||||
src: "/videos/circuit.mp4",
|
||||
desc: "YOLO 识别元件与连线,自动生成可交互虚拟电路 + AI 问答辅导。"
|
||||
},
|
||||
{
|
||||
key: "electromag",
|
||||
title: "电磁 · 能量转换优化",
|
||||
src: "/videos/electromag.mp4",
|
||||
desc: "视觉 + 单片机测电磁转换效率 + 未来 BO/RL 迭代脉冲参数,提高加速/制动能量效率。"
|
||||
},
|
||||
{
|
||||
key: "optics",
|
||||
title: "光学 · 分光计智能辅助",
|
||||
src: "/videos/optics.mp4",
|
||||
desc: "十字像追踪 + 分步引导 + PID 调节。"
|
||||
}
|
||||
];
|
||||
|
||||
interface VideoStateRef {
|
||||
currentTime: number;
|
||||
wasPlaying: boolean;
|
||||
}
|
||||
|
||||
export default function ExpoPage() {
|
||||
const [active, setActive] = useState<string | null>(null);
|
||||
const timeRefs = useRef<Record<string, VideoStateRef>>({});
|
||||
const containerRefs = useRef<Record<string, HTMLVideoElement | null>>({});
|
||||
|
||||
// 记录时间用于在放大时继续播放(非严格同步,够展示用)
|
||||
const handleBeforeExpand = (key: string) => {
|
||||
const vid = containerRefs.current[key];
|
||||
if (vid) {
|
||||
timeRefs.current[key] = {
|
||||
currentTime: vid.currentTime,
|
||||
wasPlaying: !vid.paused
|
||||
};
|
||||
}
|
||||
setActive(key);
|
||||
};
|
||||
|
||||
const handleRestore = () => {
|
||||
setActive(null);
|
||||
};
|
||||
|
||||
// 在放大的 video 元素上恢复播放进度
|
||||
const expandedVideoRef = useRef<HTMLVideoElement | null>(null);
|
||||
useEffect(() => {
|
||||
if (active && expandedVideoRef.current) {
|
||||
const state = timeRefs.current[active];
|
||||
if (state) {
|
||||
try {
|
||||
expandedVideoRef.current.currentTime = state.currentTime;
|
||||
} catch (_) {
|
||||
/* Safari 某些情况下可能阻止精确跳转,忽略 */
|
||||
}
|
||||
if (state.wasPlaying) expandedVideoRef.current.play().catch(() => {});
|
||||
}
|
||||
}
|
||||
}, [active]);
|
||||
|
||||
// ESC 关闭
|
||||
useEffect(() => {
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape" && active) setActive(null);
|
||||
};
|
||||
window.addEventListener("keydown", onKey);
|
||||
return () => window.removeEventListener("keydown", onKey);
|
||||
}, [active]);
|
||||
|
||||
return (
|
||||
<main className="relative min-h-screen w-full bg-[#05080b] text-slate-100 overflow-hidden select-none">
|
||||
|
||||
{/* 2x2 全屏栅格 */}
|
||||
<div className="grid grid-cols-1 grid-rows-4 md:grid-cols-2 md:grid-rows-2 w-full h-screen">
|
||||
{videos.map(v => (
|
||||
<motion.div
|
||||
key={v.key}
|
||||
layoutId={`card-${v.key}`}
|
||||
className={clsx(
|
||||
"relative group overflow-hidden flex cursor-pointer bg-black",
|
||||
active && active !== v.key && "opacity-25 scale-[0.99] transition"
|
||||
)}
|
||||
onClick={() => handleBeforeExpand(v.key)}
|
||||
>
|
||||
<video
|
||||
ref={el => { containerRefs.current[v.key] = el; }}
|
||||
className="w-full h-full object-contain"
|
||||
src={v.src}
|
||||
playsInline
|
||||
muted
|
||||
autoPlay
|
||||
loop
|
||||
preload="auto"
|
||||
/>
|
||||
{/* 角标信息,默认半透明,悬停/触摸更亮 */}
|
||||
<div className="absolute left-0 top-0 p-2 md:p-3 bg-black/35 backdrop-blur-sm rounded-br-xl md:rounded-br-2xl text-[10px] md:text-xs leading-snug transition group-hover:bg-black/55">
|
||||
<p className="font-semibold text-slate-100/95 mb-0.5 md:mb-1 truncate max-w-[10rem] md:max-w-[14rem]">{v.title}</p>
|
||||
<p className="text-[9px] md:text-[10px] text-slate-300/80 line-clamp-2 md:line-clamp-2 max-w-[12rem] md:max-w-[16rem]">{v.desc}</p>
|
||||
</div>
|
||||
<div className="absolute inset-0 opacity-0 group-hover:opacity-100 transition bg-black/25 flex items-center justify-center text-[11px] tracking-wide font-medium">点击放大</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<AnimatePresence>
|
||||
{active && (
|
||||
<>
|
||||
<motion.div
|
||||
key="backdrop"
|
||||
className="fixed inset-0 bg-black/70 backdrop-blur-sm z-40"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
/>
|
||||
{videos.filter(v => v.key === active).map(v => (
|
||||
<motion.div
|
||||
key={v.key}
|
||||
layoutId={`card-${v.key}`}
|
||||
className="fixed z-50 inset-0 flex flex-col overflow-hidden bg-black"
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
transition={{ type: "spring", stiffness: 180, damping: 22 }}
|
||||
>
|
||||
<div className="relative flex-1 bg-black">
|
||||
<video
|
||||
ref={expandedVideoRef}
|
||||
className="w-full h-full object-contain bg-black"
|
||||
src={v.src}
|
||||
playsInline
|
||||
muted
|
||||
autoPlay
|
||||
loop
|
||||
controls
|
||||
/>
|
||||
<div className="absolute top-0 left-0 right-0 p-3 md:p-5 flex flex-col gap-2 bg-gradient-to-b from-black/70 to-transparent pointer-events-none">
|
||||
<h2 className="text-base md:text-2xl font-semibold tracking-tight drop-shadow">{v.title}</h2>
|
||||
<p className="text-[10px] md:text-sm text-slate-300 max-w-4xl leading-relaxed">{v.desc}</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleRestore}
|
||||
className="absolute top-2 right-2 md:top-4 md:right-4 w-9 h-9 rounded-full bg-black/60 hover:bg-black/80 text-slate-200 flex items-center justify-center border border-white/10 backdrop-blur-sm transition"
|
||||
aria-label="关闭放大"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-2 md:p-3 flex justify-end gap-3 items-center text-[10px] md:text-xs text-slate-400 bg-[#0e1419]/90 border-t border-white/5">
|
||||
<button
|
||||
onClick={handleRestore}
|
||||
className="px-3 py-1 rounded-md bg-sky-600/25 hover:bg-sky-600/40 text-sky-200 font-medium tracking-wide"
|
||||
>返回</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
BIN
app/favicon.ico
Normal file
BIN
app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
89
app/globals.css
Normal file
89
app/globals.css
Normal file
@ -0,0 +1,89 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
:root {
|
||||
--background: #0b0f17; /* 深色主背景 */
|
||||
--background-alt: #111827; /* 次级面板背景 */
|
||||
--foreground: #e5e7ef;
|
||||
--muted: #94a3b8;
|
||||
--accent: #3b82f6;
|
||||
--accent-alt: #6366f1;
|
||||
--radius: 14px;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
/* 强制使用暗色风格,可按需扩展主题切换 */
|
||||
|
||||
body {
|
||||
background: radial-gradient(circle at 35% 20%, #1e293b 0%, #0b0f17 55%) fixed;
|
||||
color: var(--foreground);
|
||||
font-family: var(--font-geist-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
/* Custom gradient backgrounds & animations */
|
||||
.gradient-text {
|
||||
background: linear-gradient(90deg,var(--accent),var(--accent-alt));
|
||||
-webkit-background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.glass {
|
||||
background: linear-gradient(140deg,rgba(255,255,255,0.06),rgba(255,255,255,0.015));
|
||||
backdrop-filter: blur(14px) saturate(140%);
|
||||
border: 1px solid rgba(255,255,255,0.07);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: linear-gradient(160deg,#141a24,#111827 65%);
|
||||
border: 1px solid #1f2937;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
@keyframes floatSlow {
|
||||
0% { transform: translateY(0px) translateX(0px); }
|
||||
50% { transform: translateY(-35px) translateX(10px); }
|
||||
100% { transform: translateY(0px) translateX(0px); }
|
||||
}
|
||||
|
||||
.float-slow { animation: floatSlow 18s ease-in-out infinite; }
|
||||
|
||||
@keyframes pulseRing {
|
||||
0% { transform: scale(.6); opacity: .6; }
|
||||
70% { transform: scale(2.6); opacity: 0; }
|
||||
100% { opacity: 0; }
|
||||
}
|
||||
.pulse-ring::before, .pulse-ring::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 9999px;
|
||||
background: radial-gradient(circle at center,rgba(255,255,255,.35),transparent 70%);
|
||||
animation: pulseRing 6s linear infinite;
|
||||
}
|
||||
.pulse-ring::after { animation-delay: 3s; }
|
||||
|
||||
/* Scroll snap layout for sections */
|
||||
html,body { scroll-behavior: smooth; }
|
||||
.snap-y { scroll-snap-type: y mandatory; }
|
||||
.snap-section { scroll-snap-align: start; }
|
||||
|
||||
::-webkit-scrollbar { width: 10px; }
|
||||
::-webkit-scrollbar-track { background: #111827; }
|
||||
::-webkit-scrollbar-thumb { background: linear-gradient(#374151,#1f2937); border-radius: 20px; }
|
||||
::-webkit-scrollbar-thumb:hover { background: linear-gradient(#475569,#334155); }
|
||||
|
||||
/* 提升文字可读性 */
|
||||
h1,h2,h3,h4 { letter-spacing: 0.02em; }
|
||||
p { color: var(--muted); }
|
||||
|
||||
/* 卡片 hover 简约高亮 */
|
||||
.card-hover { transition: border-color .25s, box-shadow .25s, transform .25s; }
|
||||
.card-hover:hover { border-color: var(--accent); box-shadow: 0 4px 28px -8px rgba(59,130,246,0.35); transform: translateY(-4px); }
|
||||
|
||||
34
app/layout.tsx
Normal file
34
app/layout.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "AI视觉驱动智慧物理实验平台",
|
||||
description: "“AI + CV”双引擎:Web端实时视觉采集、AI参数拟合、误差校正与智能交互的多学科物理实验创新平台",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
484
app/page.tsx
Normal file
484
app/page.tsx
Normal file
@ -0,0 +1,484 @@
|
||||
"use client";
|
||||
import dynamic from "next/dynamic";
|
||||
import { motion } from "framer-motion";
|
||||
import { Cpu, CircuitBoard, Sparkles, Atom, Waves, Camera, Brain } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import clsx from "clsx";
|
||||
|
||||
const Scene = dynamic(() => import("@/components/Scene"), { ssr: false });
|
||||
|
||||
// 已移除浮动花哨徽章组件,保留简洁风格
|
||||
|
||||
const moduleLinks = [
|
||||
{ title: "力学实验模块", href: "#mechanics", icon: Waves, desc: "单摆精密测量 / 大摆角与阻尼修正 / 傅科摆进动 / 多参数智能拟合" },
|
||||
{ title: "电路实验模块", href: "#circuit", icon: CircuitBoard, desc: "YOLO 电路识别 → 拓扑重建 → 虚拟仿真 → AI 智能辅导闭环" },
|
||||
{ title: "电磁学实验模块", href: "#electromag", icon: Atom, desc: "气垫导轨 + 视觉测量 + BO/RL 迭代优化电磁能量转换效率" },
|
||||
{ title: "光学实验模块", href: "#optics", icon: Camera, desc: "分光计视觉十字像追踪 + PID/步骤引导提升调节精度与效率" },
|
||||
];
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="relative w-full h-full text-slate-100 overflow-x-hidden">
|
||||
{/* 3D Background */}
|
||||
<Scene />
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="snap-section min-h-screen relative flex flex-col items-center justify-center px-6 pt-24 text-center">
|
||||
<div className="absolute inset-0 pointer-events-none bg-[radial-gradient(circle_at_40%_30%,rgba(59,130,246,0.25),transparent_65%)]" />
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1 }}
|
||||
className="text-5xl md:text-7xl font-bold leading-tight gradient-text drop-shadow-lg tracking-tight"
|
||||
>
|
||||
AI视觉驱动的智慧物理实验创新平台
|
||||
</motion.h1>
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, delay: 0.3 }}
|
||||
className="mt-8 max-w-3xl mx-auto text-lg md:text-xl leading-relaxed text-slate-300"
|
||||
>
|
||||
“AI + CV”双引擎,重构数据采集、分析、交互与反馈全链路。摆球轨迹追踪、智能电路识别、Web端轻量化、跨平台实时推理,让物理实验进入沉浸式智能时代。
|
||||
</motion.p>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.45 }}
|
||||
className="mt-10 flex flex-wrap items-center justify-center gap-4"
|
||||
>
|
||||
<Link href="/expo" className="group relative">
|
||||
<span className="inline-flex items-center gap-2 rounded-full bg-gradient-to-r from-sky-600/80 to-cyan-500/70 px-6 py-3 text-sm font-semibold tracking-wide text-white shadow-lg shadow-sky-900/30 backdrop-blur-md transition hover:from-sky-500 hover:to-cyan-400 focus:outline-none focus:ring-2 focus:ring-sky-400/70">
|
||||
<Sparkles className="w-4 h-4" /> 展台同步视频演示
|
||||
</span>
|
||||
<span className="pointer-events-none absolute -inset-px rounded-full border border-sky-300/30 group-hover:border-cyan-200/40 transition" />
|
||||
</Link>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ delay: 0.6, type: "spring" }}
|
||||
className="mt-14 flex flex-wrap justify-center gap-6"
|
||||
>
|
||||
{moduleLinks.map((m) => (
|
||||
<Link key={m.title} href={m.href}>
|
||||
<motion.div
|
||||
whileHover={{ y: -6, boxShadow: "0 12px 40px -8px rgba(56,189,248,0.4)" }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className={clsx(
|
||||
"relative group rounded-xl px-6 py-5 w-64 overflow-hidden cursor-pointer transition-all card-hover",
|
||||
"panel"
|
||||
)}
|
||||
>
|
||||
<div className="relative flex items-center gap-3">
|
||||
<m.icon className="w-7 h-7 text-slate-200" />
|
||||
<h3 className="font-semibold tracking-wide text-base text-slate-100">{m.title}</h3>
|
||||
</div>
|
||||
<p className="relative mt-3 text-xs leading-relaxed text-slate-400 min-h-12">{m.desc}</p>
|
||||
<div className="relative mt-4 flex items-center gap-2 text-[10px] text-slate-400">
|
||||
<Sparkles className="w-4 h-4 text-slate-500" /> 查看详情
|
||||
</div>
|
||||
</motion.div>
|
||||
</Link>
|
||||
))}
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Architecture Section */}
|
||||
<section id="architecture" className="snap-section relative py-28 px-6 md:px-16">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="grid md:grid-cols-2 gap-20 items-start">
|
||||
<div>
|
||||
<motion.h2
|
||||
initial={{ opacity: 0, x: -40 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="text-3xl md:text-5xl font-bold gradient-text mb-8"
|
||||
>
|
||||
平台总体设计与核心技术架构
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: 0.3, duration: 0.8 }}
|
||||
className="space-y-6 text-sm leading-relaxed text-slate-400"
|
||||
>
|
||||
<p className="indent-4">
|
||||
本平台以“AI + CV”双引擎驱动:前端浏览器侧完成数据感知、实时视觉解析与轻量推理,后端/边缘协同完成大模型问答与复杂优化计算,形成数据采集—建模拟合—智能校正—反馈交互的闭环。
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-5 pt-4">
|
||||
{[
|
||||
{ t: "CV 感知", d: "Hough/轮廓/YOLO 追踪摆球、电路元件识别" },
|
||||
{ t: "AI 分析", d: "非线性拟合 / 符号回归 / 误差自适应校正" },
|
||||
{ t: "智能交互", d: "Agent 提示步骤 / 故障诊断 / 学习引导" },
|
||||
{ t: "可视化", d: "WebGL & 交互式参数变化动态渲染" },
|
||||
].map((b) => (
|
||||
<div key={b.t} className="relative p-4 rounded-lg panel card-hover">
|
||||
<h4 className="text-sm font-semibold mb-1 text-slate-200">{b.t}</h4>
|
||||
<p className="text-xs text-slate-500 leading-snug">{b.d}</p>
|
||||
<span className="absolute -top-px -left-px h-2 w-2 bg-gradient-to-br from-sky-400 to-fuchsia-500 rounded-full shadow" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="relative panel rounded-2xl p-10 space-y-8 card-hover">
|
||||
<h3 className="text-xl font-semibold flex items-center gap-3 text-slate-100"><Sparkles className="text-sky-400" />“AI + CV”双引擎协同</h3>
|
||||
<ul className="space-y-4 text-xs leading-relaxed text-slate-400">
|
||||
<li>CV 模块:图像序列 → 轨迹/姿态/拓扑;YOLO + 自定义滤波器优化稳定性。</li>
|
||||
<li>AI 模块:特征→参数拟合→误差补偿→智能讲解;支持本地与云端混合推理。</li>
|
||||
<li>数据管线:WebAssembly/OpenCV.js 实时帧处理;TensorFlow.js / WebGPU 加速。</li>
|
||||
<li>交互体验:自然语言问答、实验步骤导航、异常检测提醒。</li>
|
||||
<li>部署形态:纯 Web / 微信小程序 / 边缘一体盒子可拓展。</li>
|
||||
</ul>
|
||||
<div className="grid grid-cols-3 gap-4 pt-2 text-center text-[10px] font-mono">
|
||||
{['Capture','Track','Fit','Correct','Explain','Feedback'].map(s => (
|
||||
<div key={s} className="p-2 rounded-md bg-[#18202b] border border-[#223042]">
|
||||
<span className="text-[10px] text-slate-300 font-semibold tracking-wide">{s}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Module Overview Section */}
|
||||
<section id="modules" className="snap-section relative py-24 px-6 md:px-16">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<motion.h2
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="text-3xl md:text-5xl font-bold gradient-text mb-14 text-center"
|
||||
>
|
||||
四大实验模块 & 未来拓展
|
||||
</motion.h2>
|
||||
<div className="grid lg:grid-cols-4 md:grid-cols-2 gap-10">
|
||||
{moduleLinks.map((m) => (
|
||||
<Link key={m.title} href={m.href} className="group block relative">
|
||||
<div className="relative rounded-xl panel p-6 h-full flex flex-col overflow-hidden card-hover">
|
||||
<div className="flex items-center gap-3">
|
||||
<m.icon className="w-6 h-6 text-slate-200" />
|
||||
<h3 className="font-semibold text-sm tracking-wide text-slate-100">{m.title}</h3>
|
||||
</div>
|
||||
<p className="mt-3 text-[11px] leading-relaxed text-slate-500 flex-1">{m.desc}</p>
|
||||
<div className="mt-4 text-[10px] tracking-wider text-slate-500 flex items-center gap-2">
|
||||
<Sparkles className="w-4 h-4 text-slate-600" /> 内部锚点
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-20 grid md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{ icon: Waves, t: '统一“AI + CV”技术底座', d: '共享采集 → 追踪 → 拟合 → 校正 → 交互流水线,跨力学 / 电学 / 电磁 / 光学复用。' },
|
||||
{ icon: Camera, t: '纯 Web 端实时推理', d: '浏览器即可完成摄像采集 + OpenCV.js 处理 + 轻量模型推理,无需本地安装。' },
|
||||
{ icon: Brain, t: '智能实验助手', d: '误差分析、参数解释、探索性提问引导,支持未来符号回归自动方程发现。' },
|
||||
].map(card => (
|
||||
<div key={card.t} className="relative rounded-xl panel p-6 overflow-hidden card-hover">
|
||||
<card.icon className="w-8 h-8 text-slate-300 mb-4" />
|
||||
<h4 className="font-semibold text-sm mb-2 text-slate-200">{card.t}</h4>
|
||||
<p className="text-[11px] leading-relaxed text-slate-500">{card.d}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Mechanics Module Detail */}
|
||||
<section id="mechanics" className="snap-section relative py-28 px-6 md:px-16">
|
||||
<div className="max-w-6xl mx-auto space-y-10">
|
||||
<h2 className="text-3xl md:text-4xl font-bold gradient-text">力学实验模块 · 单摆 & 傅科摆</h2>
|
||||
<div className="grid lg:grid-cols-3 gap-10">
|
||||
<div className="lg:col-span-2 space-y-8">
|
||||
<div className="space-y-4 text-sm text-slate-400 leading-relaxed">
|
||||
<p>聚焦单摆高精度测量与扩展(大摆角修正 / 阻尼 / 品质因数 / 进动现象),实现从 <span className="text-slate-200">“验证型”</span> 向 <span className="text-slate-200">“探究型 + 参数发现”</span> 转化。</p>
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li><span className="text-slate-200">基础模型:</span> 小角近似 → 解析周期 ;</li>
|
||||
<li><span className="text-slate-200">大摆角修正:</span> 椭圆积分展开(振幅 时周期 +1.7%;时 +3.7%);</li>
|
||||
<li><span className="text-slate-200">空气阻尼:</span> 线性阻尼模型 ,对振幅指数衰减拟合获取 γ & Q;</li>
|
||||
<li><span className="text-slate-200">进动效应:</span> 初步观测傅科摆水平轨迹椭圆长轴缓慢进动,实验相对理论偏差 ≈1.9%。</li>
|
||||
</ul>
|
||||
<p className="text-slate-300">AI 数据处理流水线:</p>
|
||||
<ol className="list-decimal pl-5 space-y-1 text-xs md:text-sm">
|
||||
<li>CV 追踪:HSV 阈值 + 轮廓 + 质心 → 轨迹 (30–240fps)</li>
|
||||
<li>降噪:LSTM / 滤波平滑缺失帧</li>
|
||||
<li>非线性拟合:阻尼简谐 + 大摆角修正同步反演 (A, γ, ω<sub>d</sub>, φ)</li>
|
||||
<li>系统误差校正:大摆角 / 阻尼 / 像素标定统一补偿</li>
|
||||
<li>结果生成:g、γ、Q、误差拆解与置信区间</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-3 gap-4 text-[11px]">
|
||||
{[
|
||||
{ k: 'g 相对误差', v: '0.43%' },
|
||||
{ k: 'Q 典型值', v: '≈ 900+' },
|
||||
{ k: '进动偏差', v: '≈ 1.9%' },
|
||||
{ k: 'FPS 需求', v: '≥ 60 fps' },
|
||||
{ k: '拟合优度 R²', v: '≈ 1.0000' },
|
||||
{ k: 'γ 精度', v: '1e-4 s⁻¹ 级' },
|
||||
].map(x => (
|
||||
<div key={x.k} className="panel p-3 rounded-lg flex flex-col">
|
||||
<span className="text-slate-500">{x.k}</span>
|
||||
<span className="text-slate-200 font-semibold text-sm">{x.v}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-6 text-xs md:text-sm text-slate-500">
|
||||
<h3 className="text-slate-200 font-semibold">误差来源 & 缓解</h3>
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>摆长测量主导:像素-长度标定引入 >50% 误差份额 → 透视校正 + 直尺仰拍。</li>
|
||||
<li>大摆角不修正: 可致 g 低估 ~0.5% → 自动角幅检测触发修正。</li>
|
||||
<li>阻尼 γ 不确定度:衰减峰值回归 + 多周期平均抑制噪声。</li>
|
||||
<li>时间戳漂移:基于浏览器高精度计时 + 丢帧插值。</li>
|
||||
</ul>
|
||||
<h3 className="text-slate-200 font-semibold pt-4">拓展实验</h3>
|
||||
<p>自由落体 / 斜抛 / 弹簧振子共用“轨迹 → 拟合”管线;增加加速度二阶差分平滑与物理约束回填。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Circuit Module Detail */}
|
||||
<section id="circuit" className="snap-section relative py-28 px-6 md:px-16">
|
||||
<div className="max-w-6xl mx-auto space-y-10">
|
||||
<h2 className="text-3xl md:text-4xl font-bold gradient-text">电路实验模块 · 实物 → 虚拟 智能桥接</h2>
|
||||
<div className="grid lg:grid-cols-3 gap-10">
|
||||
<div className="lg:col-span-2 space-y-6 text-sm text-slate-400">
|
||||
<p>面向电路搭建“高错误率 / 低直观 / 教学成本高”痛点,平台构建 <span className="text-slate-200">拍照识别 → 拓扑生成 → 虚拟仿真 → AI 辅导 → 诊断优化</span> 闭环。</p>
|
||||
<h3 className="text-slate-200 font-semibold">识别与转换流程</h3>
|
||||
<ol className="list-decimal pl-5 space-y-1 text-xs md:text-sm">
|
||||
<li>上传实物俯视图:对比度增强 / 去噪预处理</li>
|
||||
<li>YOLO 模型:元件类别 + 位置检测 (置信度 > 90%)</li>
|
||||
<li>导线解析:颜色分割 + 形态学 + 拓扑推断</li>
|
||||
<li>结构化导出:JSON(元件, 参数, 连接) → 虚拟场景重建</li>
|
||||
<li>序列化 / 反序列化:支持再编辑 & 教学复用</li>
|
||||
</ol>
|
||||
<h3 className="text-slate-200 font-semibold pt-2">AI 实验助手 (Agent)</h3>
|
||||
<ul className="list-disc pl-5 space-y-1 text-xs md:text-sm">
|
||||
<li>电路原理答疑:上下文相关自然语言解析</li>
|
||||
<li>故障排查:短路 / 断路 / 量程错误定位 (准确率 >85%)</li>
|
||||
<li>个性化引导:分层次提问 + 练习建议</li>
|
||||
<li>策略建议:参数调优与替代元件推荐</li>
|
||||
</ul>
|
||||
<h3 className="text-slate-200 font-semibold pt-2">功能改造亮点</h3>
|
||||
<p>重构虚拟电表架构:统一量程 / 内阻抽象,支持序列化与自定义显示函数,适配直流电桥 / 复杂测量场景。</p>
|
||||
</div>
|
||||
<div className="space-y-6 text-xs md:text-sm text-slate-500">
|
||||
<h4 className="text-slate-200 font-semibold">价值提升</h4>
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>从“手工搭建”延伸到“智能反馈 + 虚实双轨”体验</li>
|
||||
<li>降低误接线风险,减少元件损耗</li>
|
||||
<li>学习路径个性化:错误模式 → 策略建议</li>
|
||||
</ul>
|
||||
<h4 className="text-slate-200 font-semibold pt-4">核心数据面板</h4>
|
||||
<div className="grid grid-cols-2 gap-3 text-[11px]">
|
||||
{[
|
||||
{ k: '识别置信度', v: '>90%' },
|
||||
{ k: '故障诊断', v: '>85%' },
|
||||
{ k: '转换延迟', v: '< 3 s' },
|
||||
{ k: '数据格式', v: 'JSON 标准化' },
|
||||
].map(x => (
|
||||
<div key={x.k} className="panel p-3 rounded-lg"><p className="text-slate-500">{x.k}</p><p className="text-slate-200 font-semibold">{x.v}</p></div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Electromagnetics Module Detail */}
|
||||
<section id="electromag" className="snap-section relative py-28 px-6 md:px-16">
|
||||
<div className="max-w-6xl mx-auto space-y-10">
|
||||
<h2 className="text-3xl md:text-4xl font-bold gradient-text">电磁学实验模块 · 电磁能量转换优化</h2>
|
||||
<div className="grid lg:grid-cols-3 gap-10">
|
||||
<div className="lg:col-span-2 space-y-6 text-sm text-slate-400">
|
||||
<p>围绕气垫导轨低摩擦环境 + 永磁体滑块 + 线圈 + 可编程电源构建“视觉测量 + 参数智能优化”平台,实现 <span className="text-slate-200">加速 / 制动能量转换效率</span> 最大化。</p>
|
||||
<h3 className="text-slate-200 font-semibold">视觉 & 数据采集</h3>
|
||||
<ul className="list-disc pl-5 space-y-1 text-xs md:text-sm">
|
||||
<li>荧光标签 + HSV 阈值 + 轮廓提取 → 位移序列</li>
|
||||
<li>差分计算速度 / 加速度,功率曲线与感应电压时间同步</li>
|
||||
<li>亚像素插值提升定位至 0.1 px</li>
|
||||
</ul>
|
||||
<h3 className="text-slate-200 font-semibold pt-2">优化算法闭环</h3>
|
||||
<ol className="list-decimal pl-5 space-y-1 text-xs md:text-sm">
|
||||
<li>参数向量:提前量 Δt,脉冲宽度 τ,强度 U/I</li>
|
||||
<li>安全约束:V / I / dI/dt / 线圈温度限幅</li>
|
||||
<li>奖励函数:加速 → v<sub>out</sub>/能耗;制动 → 回收能量/距离</li>
|
||||
<li>冷启动:均匀采样 5–8 组 → 贝叶斯优化拟合响应面</li>
|
||||
<li>迭代 30–50 次收敛至最优策略</li>
|
||||
</ol>
|
||||
<h3 className="text-slate-200 font-semibold pt-2">实验价值</h3>
|
||||
<p>将传统“经验调参”转化为 <span className="text-slate-200">数据驱动小样本优化</span>;可扩展到多线圈同步控制与能量回收策略研究。</p>
|
||||
</div>
|
||||
<div className="space-y-6 text-xs md:text-sm text-slate-500">
|
||||
<h4 className="text-slate-200 font-semibold">主要误差控制</h4>
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>动态模糊:提升快门 / 降低曝光,结合运动补偿滤波</li>
|
||||
<li>时间量化:60 fps → 插值校正 16.67ms 间隔偏差</li>
|
||||
<li>探索噪声:RL 初期随机性通过收敛监测抑制</li>
|
||||
</ul>
|
||||
<div className="grid grid-cols-2 gap-3 text-[11px] pt-2">
|
||||
{[
|
||||
{ k: '像素精度', v: '0.1 px' },
|
||||
{ k: '收敛迭代', v: '≤ 50' },
|
||||
{ k: '参数维度', v: '3~5 可扩展' },
|
||||
{ k: '奖励形式', v: '可插拔' },
|
||||
].map(x => (
|
||||
<div key={x.k} className="panel p-3 rounded-lg"><p className="text-slate-500">{x.k}</p><p className="text-slate-200 font-semibold">{x.v}</p></div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Optics Module Detail */}
|
||||
<section id="optics" className="snap-section relative py-28 px-6 md:px-16">
|
||||
<div className="max-w-6xl mx-auto space-y-10">
|
||||
<h2 className="text-3xl md:text-4xl font-bold gradient-text">光学实验模块 · 分光计智能辅助</h2>
|
||||
<div className="grid lg:grid-cols-3 gap-10">
|
||||
<div className="lg:col-span-2 space-y-6 text-sm text-slate-400">
|
||||
<p>针对分光计“调节耗时 / 精度依赖经验 / 错误代价高”痛点,引入 <span className="text-slate-200">十字像视觉追踪 + 规则/算法混合引导 + PID 精细调节</span>。</p>
|
||||
<h3 className="text-slate-200 font-semibold">系统能力</h3>
|
||||
<ul className="list-disc pl-5 space-y-1 text-xs md:text-sm">
|
||||
<li>十字像偏移检测:HSV 分割 + 卡尔曼预测补帧</li>
|
||||
<li>分步指引:载物台 → 望远镜 → 平行光管层层收敛</li>
|
||||
<li>方向纠错:若偏移增大 → 即时反向提示</li>
|
||||
<li>PID 复合:P 快速靠近 + I 消除残差 + D 减少过冲</li>
|
||||
</ul>
|
||||
<h3 className="text-slate-200 font-semibold pt-2">效果指标</h3>
|
||||
<div className="grid grid-cols-3 gap-4 text-[11px]">
|
||||
{[
|
||||
{ k: '光轴垂直度误差', v: '±1′ (改进自 ±5′)' },
|
||||
{ k: '光谱测量误差', v: '0.8% (原 3%)' },
|
||||
{ k: '调节练习次数', v: '3 次 (原 8 次)' },
|
||||
].map(x => (
|
||||
<div key={x.k} className="panel p-3 rounded-lg"><p className="text-slate-500">{x.k}</p><p className="text-slate-200 font-semibold">{x.v}</p></div>
|
||||
))}
|
||||
</div>
|
||||
<p>通过“实物操作 ↔ 虚拟反馈”双通道,强化对最小偏向角 / 光路可逆性等抽象概念的可视化理解。</p>
|
||||
</div>
|
||||
<div className="space-y-6 text-xs md:text-sm text-slate-500">
|
||||
<h4 className="text-slate-200 font-semibold">算法要点</h4>
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>多源容错:反光 / 暂时遮挡 → 轨迹预测维持稳定</li>
|
||||
<li>操作建议语言模板化,降低认知负荷</li>
|
||||
<li>未来扩展:自动电机微调 + 自监督姿态估计</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Innovation Section */}
|
||||
<section id="innovation" className="snap-section relative py-28 px-6 md:px-16">
|
||||
<div className="max-w-6xl mx-auto space-y-10">
|
||||
<h2 className="text-3xl md:text-4xl font-bold gradient-text">创新点与特色</h2>
|
||||
<div className="grid md:grid-cols-2 gap-12 text-sm text-slate-400">
|
||||
<div className="space-y-5">
|
||||
<h3 className="text-slate-200 font-semibold">平台特色</h3>
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>统一 Web 前端栈:摄像 / 视觉 / 推理 / 可视化 一体化。</li>
|
||||
<li>模块化实验插件:力学 / 电学 / 电磁 / 光学按需加载。</li>
|
||||
<li>AI 贯穿“采集 → 分析 → 交互 → 评估”全链路。</li>
|
||||
<li>纯浏览器运行:降低硬件门槛 & 便于推广。</li>
|
||||
</ul>
|
||||
<h3 className="text-slate-200 font-semibold pt-4">技术统一性</h3>
|
||||
<p>CV 负责“看见”;AI 负责“理解 / 校正 / 解释”;Agent 负责“交互与引导”。三者协同构成可拓展物理实验智能底座。</p>
|
||||
</div>
|
||||
<div className="space-y-5">
|
||||
<h3 className="text-slate-200 font-semibold">核心创新</h3>
|
||||
<ol className="list-decimal pl-5 space-y-2">
|
||||
<li>YOLO + 物理约束拟合:替代人工计时与单一软件辅助。</li>
|
||||
<li>多参数联测:单摆拓展至 (g, γ, Q) & 大摆角修正耦合。</li>
|
||||
<li>虚实转换桥:电路识别 → 拓扑生成 → 仿真联动。</li>
|
||||
<li>小样本优化:BO / RL 迭代探索最优电磁脉冲。</li>
|
||||
<li>可扩展方程发现:预留符号回归 / 自监督接口。</li>
|
||||
<li>统一序列化:虚拟元件 / 轨迹 / 训练日志规范输出。</li>
|
||||
</ol>
|
||||
<h3 className="text-slate-200 font-semibold pt-4">拓展潜力</h3>
|
||||
<p>预期接入:衍射条纹分析、热膨胀追踪、声学驻波测量、流体可视化——形成多学科“AI 实验超集”。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Outlook Section */}
|
||||
<section id="outlook" className="snap-section relative py-28 px-6 md:px-16">
|
||||
<div className="max-w-5xl mx-auto space-y-8 text-sm text-slate-400">
|
||||
<h2 className="text-3xl md:text-4xl font-bold gradient-text">总结与展望</h2>
|
||||
<p>平台验证了“AI + CV” 在物理实验 <span className="text-slate-200">高精度测量 / 多参数挖掘 / 智能交互 / 自适应优化</span> 多维价值:单摆 g 误差压至 0.43%;电路拓扑自动化;电磁脉冲小样本收敛;光学调节效率显著提升。</p>
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li><span className="text-slate-200">技术深化:</span> 引入自监督特征提取、符号回归 (SINDy / AI Feynman) 自动方程发现。</li>
|
||||
<li><span className="text-slate-200">场景拓展:</span> 热学、流体、复杂耦合系统多源数据融合。</li>
|
||||
<li><span className="text-slate-200">智能调参:</span> AI 基于学习目标与实时数据主动推荐实验条件。</li>
|
||||
<li><span className="text-slate-200">教育生态:</span> 数据共享与协作分析社区,支撑探究式教学改革。</li>
|
||||
</ul>
|
||||
<p>目标:建设面向未来理工教育的 <span className="text-slate-200">“全能型 AI 实验基础设施”</span>,让每一位学生以低门槛获得科研级观测与建模能力。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Web Deployment Section */}
|
||||
<section id="web" className="snap-section relative py-24 px-6 md:px-16">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="grid lg:grid-cols-2 gap-20 items-center">
|
||||
<div>
|
||||
<motion.h2
|
||||
initial={{ opacity: 0, x: -40 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="text-3xl md:text-5xl font-bold gradient-text mb-8"
|
||||
>
|
||||
Web 端轻量化与跨平台
|
||||
</motion.h2>
|
||||
<ul className="space-y-4 text-sm text-slate-300/90 leading-relaxed">
|
||||
<li>跨平台:浏览器即实验室,覆盖手机 / PC / 平板 / 小程序。</li>
|
||||
<li>本地推理:TensorFlow.js / WebGPU 使 YOLO / Transformer 部分模型可端侧运行,降低延迟。</li>
|
||||
<li>实时 CV:getUserMedia + OpenCV.js 在纯前端实现图像滤波、边缘检测、轮廓拟合与运动轨迹重建。</li>
|
||||
<li>混合架构:轻量模型前端运行,大模型问答 & 复杂优化通过 API 协同。</li>
|
||||
<li>开放拓展:支持未来热学 / 声学 / 流体等模块的即插式算法集成。</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="relative panel p-10 rounded-2xl card-hover">
|
||||
<h3 className="font-semibold mb-6 flex items-center gap-2 text-slate-100"><Cpu className="text-sky-400" /> 端侧计算栈</h3>
|
||||
<div className="grid grid-cols-2 gap-4 text-[11px] font-mono">
|
||||
{[
|
||||
'WebGL','WebGPU','WASM','OpenCV.js','TensorFlow.js','MediaPipe','YOLOv8-tiny','Edge Agent'
|
||||
].map(s => (
|
||||
<div key={s} className="p-2 rounded-md bg-[#18202b] border border-[#223042] text-center text-slate-300 tracking-wide">
|
||||
{s}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-8 relative">
|
||||
<div className="relative h-40 w-40 mx-auto rounded-full flex items-center justify-center bg-[#18202b] border border-[#223042]">
|
||||
<div className="text-center text-[10px] leading-relaxed text-slate-400">
|
||||
<span className="text-slate-200 font-semibold">Edge Inference Core</span><br />
|
||||
Capture → Track → Fit → Insight
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="relative py-14 text-center text-[11px] text-slate-500">
|
||||
<div className="max-w-5xl mx-auto px-6">
|
||||
<p>© {new Date().getFullYear()} AI 视觉驱动智慧物理实验平台 · 展示页 · 外链为占位符</p>
|
||||
</div>
|
||||
</footer>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
34
biome.json
Normal file
34
biome.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.2.0/schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": true
|
||||
},
|
||||
"files": {
|
||||
"ignoreUnknown": true,
|
||||
"includes": ["**", "!node_modules", "!.next", "!dist", "!build"]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true
|
||||
},
|
||||
"domains": {
|
||||
"next": "recommended",
|
||||
"react": "recommended"
|
||||
}
|
||||
},
|
||||
"assist": {
|
||||
"actions": {
|
||||
"source": {
|
||||
"organizeImports": "on"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
436
bun.lock
Normal file
436
bun.lock
Normal file
@ -0,0 +1,436 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "phylab",
|
||||
"dependencies": {
|
||||
"@react-three/drei": "^9.114.0",
|
||||
"@react-three/fiber": "^9.0.0",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^11.0.0",
|
||||
"lucide-react": "^0.474.0",
|
||||
"next": "15.5.0",
|
||||
"next-themes": "^0.3.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"three": "^0.170.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.2.0",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
||||
|
||||
"@babel/runtime": ["@babel/runtime@7.28.3", "", {}, "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA=="],
|
||||
|
||||
"@biomejs/biome": ["@biomejs/biome@2.2.0", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.2.0", "@biomejs/cli-darwin-x64": "2.2.0", "@biomejs/cli-linux-arm64": "2.2.0", "@biomejs/cli-linux-arm64-musl": "2.2.0", "@biomejs/cli-linux-x64": "2.2.0", "@biomejs/cli-linux-x64-musl": "2.2.0", "@biomejs/cli-win32-arm64": "2.2.0", "@biomejs/cli-win32-x64": "2.2.0" }, "bin": { "biome": "bin/biome" } }, "sha512-3On3RSYLsX+n9KnoSgfoYlckYBoU6VRM22cw1gB4Y0OuUVSYd/O/2saOJMrA4HFfA1Ff0eacOvMN1yAAvHtzIw=="],
|
||||
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.2.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zKbwUUh+9uFmWfS8IFxmVD6XwqFcENjZvEyfOxHs1epjdH3wyyMQG80FGDsmauPwS2r5kXdEM0v/+dTIA9FXAg=="],
|
||||
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.2.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-+OmT4dsX2eTfhD5crUOPw3RPhaR+SKVspvGVmSdZ9y9O/AgL8pla6T4hOn1q+VAFBHuHhsdxDRJgFCSC7RaMOw=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-6eoRdF2yW5FnW9Lpeivh7Mayhq0KDdaDMYOJnH9aT02KuSIX5V1HmWJCQQPwIQbhDh68Zrcpl8inRlTEan0SXw=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-egKpOa+4FL9YO+SMUMLUvf543cprjevNc3CAgDNFLcjknuNMcZ0GLJYa3EGTCR2xIkIUJDVneBV3O9OcIlCEZQ=="],
|
||||
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5UmQx/OZAfJfi25zAnAGHUMuOd+LOsliIt119x2soA2gLggQYrVPA+2kMUxR6Mw5M1deUF/AWWP2qpxgH7Nyfw=="],
|
||||
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-I5J85yWwUWpgJyC1CcytNSGusu2p9HjDnOPAFG4Y515hwRD0jpR9sT9/T1cKHtuCvEQ/sBvx+6zhz9l9wEJGAg=="],
|
||||
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.2.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-n9a1/f2CwIDmNMNkFs+JI0ZjFnMO0jdOyGNtihgUNFnlmd84yIYY2KMTBmMV58ZlVHjgmY5Y6E1hVTnSRieggA=="],
|
||||
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.2.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Nawu5nHjP/zPKTIryh2AavzTc/KEg4um/MxWdXW0A6P/RZOyIpa7+QSjeXwAwX/utJGaCoXRPWtF3m5U/bB3Ww=="],
|
||||
|
||||
"@dimforge/rapier3d-compat": ["@dimforge/rapier3d-compat@0.12.0", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.4.5", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg=="],
|
||||
|
||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.0" }, "os": "darwin", "cpu": "arm64" }, "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg=="],
|
||||
|
||||
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.0" }, "os": "darwin", "cpu": "x64" }, "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.0", "", { "os": "linux", "cpu": "arm" }, "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA=="],
|
||||
|
||||
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ=="],
|
||||
|
||||
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw=="],
|
||||
|
||||
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg=="],
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q=="],
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q=="],
|
||||
|
||||
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.0" }, "os": "linux", "cpu": "arm" }, "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A=="],
|
||||
|
||||
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.0" }, "os": "linux", "cpu": "arm64" }, "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA=="],
|
||||
|
||||
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.0" }, "os": "linux", "cpu": "ppc64" }, "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA=="],
|
||||
|
||||
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.0" }, "os": "linux", "cpu": "s390x" }, "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ=="],
|
||||
|
||||
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.0" }, "os": "linux", "cpu": "x64" }, "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ=="],
|
||||
|
||||
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.0" }, "os": "linux", "cpu": "arm64" }, "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ=="],
|
||||
|
||||
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.0" }, "os": "linux", "cpu": "x64" }, "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ=="],
|
||||
|
||||
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.3", "", { "dependencies": { "@emnapi/runtime": "^1.4.4" }, "cpu": "none" }, "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg=="],
|
||||
|
||||
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ=="],
|
||||
|
||||
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw=="],
|
||||
|
||||
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.3", "", { "os": "win32", "cpu": "x64" }, "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g=="],
|
||||
|
||||
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||
|
||||
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
||||
|
||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.30", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q=="],
|
||||
|
||||
"@mediapipe/tasks-vision": ["@mediapipe/tasks-vision@0.10.17", "", {}, "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg=="],
|
||||
|
||||
"@monogrid/gainmap-js": ["@monogrid/gainmap-js@3.1.0", "", { "dependencies": { "promise-worker-transferable": "^1.0.4" }, "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw=="],
|
||||
|
||||
"@next/env": ["@next/env@15.5.0", "", {}, "sha512-sDaprBAfzCQiOgo2pO+LhnV0Wt2wBgartjrr+dpcTORYVnnXD0gwhHhiiyIih9hQbq+JnbqH4odgcFWhqCGidw=="],
|
||||
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v7Jj9iqC6enxIRBIScD/o0lH7QKvSxq2LM8UTyqJi+S2w2QzhMYjven4vgu/RzgsdtdbpkyCxBTzHl/gN5rTRg=="],
|
||||
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-s2Nk6ec+pmYmAb/utawuURy7uvyYKDk+TRE5aqLRsdnj3AhwC9IKUBmhfnLmY/+P+DnwqpeXEFIKe9tlG0p6CA=="],
|
||||
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-mGlPJMZReU4yP5fSHjOxiTYvZmwPSWn/eF/dcg21pwfmiUCKS1amFvf1F1RkLHPIMPfocxLViNWFvkvDB14Isg=="],
|
||||
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-biWqIOE17OW/6S34t1X8K/3vb1+svp5ji5QQT/IKR+VfM3B7GvlCwmz5XtlEan2ukOUf9tj2vJJBffaGH4fGRw=="],
|
||||
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-zPisT+obYypM/l6EZ0yRkK3LEuoZqHaSoYKj+5jiD9ESHwdr6QhnabnNxYkdy34uCigNlWIaCbjFmQ8FY5AlxA=="],
|
||||
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+t3+7GoU9IYmk+N+FHKBNFdahaReoAktdOpXHFIPOU1ixxtdge26NgQEEkJkCw2dHT9UwwK5zw4mAsURw4E8jA=="],
|
||||
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-d8MrXKh0A+c9DLiy1BUFwtg3Hu90Lucj3k6iKTUdPOv42Ve2UiIG8HYi3UAb8kFVluXxEfdpCoPPCSODk5fDcw=="],
|
||||
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Fe1tGHxOWEyQjmygWkkXSwhFcTJuimrNu52JEuwItrKJVV4iRjbWp9I7zZjwqtiNnQmxoEvoisn8wueFLrNpvQ=="],
|
||||
|
||||
"@react-spring/animated": ["@react-spring/animated@9.7.5", "", { "dependencies": { "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg=="],
|
||||
|
||||
"@react-spring/core": ["@react-spring/core@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w=="],
|
||||
|
||||
"@react-spring/rafz": ["@react-spring/rafz@9.7.5", "", {}, "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw=="],
|
||||
|
||||
"@react-spring/shared": ["@react-spring/shared@9.7.5", "", { "dependencies": { "@react-spring/rafz": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw=="],
|
||||
|
||||
"@react-spring/three": ["@react-spring/three@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/core": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "@react-three/fiber": ">=6.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "three": ">=0.126" } }, "sha512-RxIsCoQfUqOS3POmhVHa1wdWS0wyHAUway73uRLp3GAL5U2iYVNdnzQsep6M2NZ994BlW8TcKuMtQHUqOsy6WA=="],
|
||||
|
||||
"@react-spring/types": ["@react-spring/types@9.7.5", "", {}, "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g=="],
|
||||
|
||||
"@react-three/drei": ["@react-three/drei@9.122.0", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mediapipe/tasks-vision": "0.10.17", "@monogrid/gainmap-js": "^3.0.6", "@react-spring/three": "~9.7.5", "@use-gesture/react": "^10.3.1", "camera-controls": "^2.9.0", "cross-env": "^7.0.3", "detect-gpu": "^5.0.56", "glsl-noise": "^0.0.0", "hls.js": "^1.5.17", "maath": "^0.10.8", "meshline": "^3.3.1", "react-composer": "^5.0.3", "stats-gl": "^2.2.8", "stats.js": "^0.17.0", "suspend-react": "^0.1.3", "three-mesh-bvh": "^0.7.8", "three-stdlib": "^2.35.6", "troika-three-text": "^0.52.0", "tunnel-rat": "^0.1.2", "utility-types": "^3.11.0", "zustand": "^5.0.1" }, "peerDependencies": { "@react-three/fiber": "^8", "react": "^18", "react-dom": "^18", "three": ">=0.137" }, "optionalPeers": ["react-dom"] }, "sha512-SEO/F/rBCTjlLez7WAlpys+iGe9hty4rNgjZvgkQeXFSiwqD4Hbk/wNHMAbdd8vprO2Aj81mihv4dF5bC7D0CA=="],
|
||||
|
||||
"@react-three/fiber": ["@react-three/fiber@9.3.0", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/react-reconciler": "^0.32.0", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-reconciler": "^0.31.0", "react-use-measure": "^2.1.7", "scheduler": "^0.25.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-myPe3YL/C8+Eq939/4qIVEPBW/uxV0iiUbmjfwrs9sGKYDG8ib8Dz3Okq7BQt8P+0k4igedONbjXMQy84aDFmQ=="],
|
||||
|
||||
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/node@4.1.12", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.5.1", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.12" } }, "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ=="],
|
||||
|
||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.12", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.12", "@tailwindcss/oxide-darwin-arm64": "4.1.12", "@tailwindcss/oxide-darwin-x64": "4.1.12", "@tailwindcss/oxide-freebsd-x64": "4.1.12", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.12", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.12", "@tailwindcss/oxide-linux-arm64-musl": "4.1.12", "@tailwindcss/oxide-linux-x64-gnu": "4.1.12", "@tailwindcss/oxide-linux-x64-musl": "4.1.12", "@tailwindcss/oxide-wasm32-wasi": "4.1.12", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.12", "@tailwindcss/oxide-win32-x64-msvc": "4.1.12" } }, "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw=="],
|
||||
|
||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.12", "", { "os": "android", "cpu": "arm64" }, "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg=="],
|
||||
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12", "", { "os": "linux", "cpu": "arm" }, "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.12", "", { "os": "linux", "cpu": "x64" }, "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.12", "", { "os": "linux", "cpu": "x64" }, "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.12", "", { "dependencies": { "@emnapi/core": "^1.4.5", "@emnapi/runtime": "^1.4.5", "@emnapi/wasi-threads": "^1.0.4", "@napi-rs/wasm-runtime": "^0.2.12", "@tybys/wasm-util": "^0.10.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.12", "", { "os": "win32", "cpu": "x64" }, "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA=="],
|
||||
|
||||
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.12", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.12", "@tailwindcss/oxide": "4.1.12", "postcss": "^8.4.41", "tailwindcss": "4.1.12" } }, "sha512-5PpLYhCAwf9SJEeIsSmCDLgyVfdBhdBpzX1OJ87anT9IVR0Z9pjM0FNixCAUAHGnMBGB8K99SwAheXrT0Kh6QQ=="],
|
||||
|
||||
"@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="],
|
||||
|
||||
"@types/draco3d": ["@types/draco3d@1.4.10", "", {}, "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw=="],
|
||||
|
||||
"@types/node": ["@types/node@20.19.11", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow=="],
|
||||
|
||||
"@types/offscreencanvas": ["@types/offscreencanvas@2019.7.3", "", {}, "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A=="],
|
||||
|
||||
"@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.1.7", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw=="],
|
||||
|
||||
"@types/react-reconciler": ["@types/react-reconciler@0.32.0", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-+WHarFkJevhH1s655qeeSEf/yxFST0dVRsmSqUgxG8mMOKqycgYBv2wVpyubBY7MX8KiX5FQ03rNIwrxfm7Bmw=="],
|
||||
|
||||
"@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="],
|
||||
|
||||
"@types/three": ["@types/three@0.179.0", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": "*", "@webgpu/types": "*", "fflate": "~0.8.2", "meshoptimizer": "~0.22.0" } }, "sha512-VgbFG2Pgsm84BqdegZzr7w2aKbQxmgzIu4Dy7/75ygiD/0P68LKmp5ie08KMPNqGTQwIge8s6D1guZf1RnZE0A=="],
|
||||
|
||||
"@types/webxr": ["@types/webxr@0.5.22", "", {}, "sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A=="],
|
||||
|
||||
"@use-gesture/core": ["@use-gesture/core@10.3.1", "", {}, "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw=="],
|
||||
|
||||
"@use-gesture/react": ["@use-gesture/react@10.3.1", "", { "dependencies": { "@use-gesture/core": "10.3.1" }, "peerDependencies": { "react": ">= 16.8.0" } }, "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g=="],
|
||||
|
||||
"@webgpu/types": ["@webgpu/types@0.1.64", "", {}, "sha512-84kRIAGV46LJTlJZWxShiOrNL30A+9KokD7RB3dRCIqODFjodS5tCD5yyiZ8kIReGVZSDfA3XkkwyyOIF6K62A=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
|
||||
|
||||
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
|
||||
|
||||
"camera-controls": ["camera-controls@2.10.1", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-KnaKdcvkBJ1Irbrzl8XD6WtZltkRjp869Jx8c0ujs9K+9WD+1D7ryBsCiVqJYUqt6i/HR5FxT7RLASieUD+Q5w=="],
|
||||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001735", "", {}, "sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w=="],
|
||||
|
||||
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
|
||||
|
||||
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
|
||||
|
||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||
|
||||
"color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
|
||||
|
||||
"cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="],
|
||||
|
||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"detect-gpu": ["detect-gpu@5.0.70", "", { "dependencies": { "webgl-constants": "^1.1.1" } }, "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w=="],
|
||||
|
||||
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
|
||||
|
||||
"draco3d": ["draco3d@1.5.7", "", {}, "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ=="],
|
||||
|
||||
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
|
||||
|
||||
"fflate": ["fflate@0.6.10", "", {}, "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg=="],
|
||||
|
||||
"framer-motion": ["framer-motion@11.18.2", "", { "dependencies": { "motion-dom": "^11.18.1", "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w=="],
|
||||
|
||||
"glsl-noise": ["glsl-noise@0.0.0", "", {}, "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"hls.js": ["hls.js@1.6.10", "", {}, "sha512-16XHorwFNh+hYazYxDNXBLEm5aRoU+oxMX6qVnkbGH3hJil4xLav3/M6NH92VkD1qSOGKXeSm+5unuawPXK6OQ=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
|
||||
|
||||
"is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
|
||||
|
||||
"is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="],
|
||||
|
||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||
|
||||
"its-fine": ["its-fine@2.0.0", "", { "dependencies": { "@types/react-reconciler": "^0.28.9" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng=="],
|
||||
|
||||
"jiti": ["jiti@2.5.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="],
|
||||
|
||||
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
|
||||
"lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
|
||||
|
||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
|
||||
|
||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
|
||||
|
||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="],
|
||||
|
||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="],
|
||||
|
||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="],
|
||||
|
||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="],
|
||||
|
||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="],
|
||||
|
||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="],
|
||||
|
||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="],
|
||||
|
||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="],
|
||||
|
||||
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
|
||||
|
||||
"lucide-react": ["lucide-react@0.474.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA=="],
|
||||
|
||||
"maath": ["maath@0.10.8", "", { "peerDependencies": { "@types/three": ">=0.134.0", "three": ">=0.134.0" } }, "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||
|
||||
"meshline": ["meshline@3.3.1", "", { "peerDependencies": { "three": ">=0.137" } }, "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ=="],
|
||||
|
||||
"meshoptimizer": ["meshoptimizer@0.22.0", "", {}, "sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg=="],
|
||||
|
||||
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
||||
|
||||
"minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="],
|
||||
|
||||
"mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
|
||||
|
||||
"motion-dom": ["motion-dom@11.18.1", "", { "dependencies": { "motion-utils": "^11.18.1" } }, "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw=="],
|
||||
|
||||
"motion-utils": ["motion-utils@11.18.1", "", {}, "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
|
||||
"next": ["next@15.5.0", "", { "dependencies": { "@next/env": "15.5.0", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.0", "@next/swc-darwin-x64": "15.5.0", "@next/swc-linux-arm64-gnu": "15.5.0", "@next/swc-linux-arm64-musl": "15.5.0", "@next/swc-linux-x64-gnu": "15.5.0", "@next/swc-linux-x64-musl": "15.5.0", "@next/swc-win32-arm64-msvc": "15.5.0", "@next/swc-win32-x64-msvc": "15.5.0", "sharp": "^0.34.3" }, "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" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-N1lp9Hatw3a9XLt0307lGB4uTKsXDhyOKQo7uYMzX4i0nF/c27grcGXkLdb7VcT8QPYLBa8ouIyEoUQJ2OyeNQ=="],
|
||||
|
||||
"next-themes": ["next-themes@0.3.0", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18", "react-dom": "^16.8 || ^17 || ^18" } }, "sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w=="],
|
||||
|
||||
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||
|
||||
"potpack": ["potpack@1.0.2", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="],
|
||||
|
||||
"promise-worker-transferable": ["promise-worker-transferable@1.0.4", "", { "dependencies": { "is-promise": "^2.1.0", "lie": "^3.0.2" } }, "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw=="],
|
||||
|
||||
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
||||
|
||||
"react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
|
||||
|
||||
"react-composer": ["react-composer@5.0.3", "", { "dependencies": { "prop-types": "^15.6.0" }, "peerDependencies": { "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, "sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA=="],
|
||||
|
||||
"react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="],
|
||||
|
||||
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||
|
||||
"react-reconciler": ["react-reconciler@0.31.0", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ=="],
|
||||
|
||||
"react-use-measure": ["react-use-measure@2.1.7", "", { "peerDependencies": { "react": ">=16.13", "react-dom": ">=16.13" }, "optionalPeers": ["react-dom"] }, "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg=="],
|
||||
|
||||
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
||||
|
||||
"scheduler": ["scheduler@0.25.0", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="],
|
||||
|
||||
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||
|
||||
"sharp": ["sharp@0.34.3", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.4", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.3", "@img/sharp-darwin-x64": "0.34.3", "@img/sharp-libvips-darwin-arm64": "1.2.0", "@img/sharp-libvips-darwin-x64": "1.2.0", "@img/sharp-libvips-linux-arm": "1.2.0", "@img/sharp-libvips-linux-arm64": "1.2.0", "@img/sharp-libvips-linux-ppc64": "1.2.0", "@img/sharp-libvips-linux-s390x": "1.2.0", "@img/sharp-libvips-linux-x64": "1.2.0", "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", "@img/sharp-libvips-linuxmusl-x64": "1.2.0", "@img/sharp-linux-arm": "0.34.3", "@img/sharp-linux-arm64": "0.34.3", "@img/sharp-linux-ppc64": "0.34.3", "@img/sharp-linux-s390x": "0.34.3", "@img/sharp-linux-x64": "0.34.3", "@img/sharp-linuxmusl-arm64": "0.34.3", "@img/sharp-linuxmusl-x64": "0.34.3", "@img/sharp-wasm32": "0.34.3", "@img/sharp-win32-arm64": "0.34.3", "@img/sharp-win32-ia32": "0.34.3", "@img/sharp-win32-x64": "0.34.3" } }, "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg=="],
|
||||
|
||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"stats-gl": ["stats-gl@2.4.2", "", { "dependencies": { "@types/three": "*", "three": "^0.170.0" } }, "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ=="],
|
||||
|
||||
"stats.js": ["stats.js@0.17.0", "", {}, "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw=="],
|
||||
|
||||
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
|
||||
|
||||
"suspend-react": ["suspend-react@0.1.3", "", { "peerDependencies": { "react": ">=17.0" } }, "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ=="],
|
||||
|
||||
"tailwindcss": ["tailwindcss@4.1.12", "", {}, "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA=="],
|
||||
|
||||
"tapable": ["tapable@2.2.2", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="],
|
||||
|
||||
"tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="],
|
||||
|
||||
"three": ["three@0.170.0", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="],
|
||||
|
||||
"three-mesh-bvh": ["three-mesh-bvh@0.7.8", "", { "peerDependencies": { "three": ">= 0.151.0" } }, "sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw=="],
|
||||
|
||||
"three-stdlib": ["three-stdlib@2.36.0", "", { "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", "@types/webxr": "^0.5.2", "draco3d": "^1.4.1", "fflate": "^0.6.9", "potpack": "^1.0.1" }, "peerDependencies": { "three": ">=0.128.0" } }, "sha512-kv0Byb++AXztEGsULgMAs8U2jgUdz6HPpAB/wDJnLiLlaWQX2APHhiTJIN7rqW+Of0eRgcp7jn05U1BsCP3xBA=="],
|
||||
|
||||
"troika-three-text": ["troika-three-text@0.52.4", "", { "dependencies": { "bidi-js": "^1.0.2", "troika-three-utils": "^0.52.4", "troika-worker-utils": "^0.52.0", "webgl-sdf-generator": "1.1.1" }, "peerDependencies": { "three": ">=0.125.0" } }, "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg=="],
|
||||
|
||||
"troika-three-utils": ["troika-three-utils@0.52.4", "", { "peerDependencies": { "three": ">=0.125.0" } }, "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A=="],
|
||||
|
||||
"troika-worker-utils": ["troika-worker-utils@0.52.0", "", {}, "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="],
|
||||
|
||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
|
||||
|
||||
"utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="],
|
||||
|
||||
"webgl-constants": ["webgl-constants@1.1.1", "", {}, "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="],
|
||||
|
||||
"webgl-sdf-generator": ["webgl-sdf-generator@1.1.1", "", {}, "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||
|
||||
"zustand": ["zustand@5.0.8", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.5", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.4", "tslib": "^2.4.0" }, "bundled": true }, "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.5", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.4", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" }, "bundled": true }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"@types/three/fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="],
|
||||
|
||||
"its-fine/@types/react-reconciler": ["@types/react-reconciler@0.28.9", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="],
|
||||
|
||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||
|
||||
"react-dom/scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
|
||||
|
||||
"tunnel-rat/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="],
|
||||
}
|
||||
}
|
||||
133
components/Scene.tsx
Normal file
133
components/Scene.tsx
Normal file
@ -0,0 +1,133 @@
|
||||
"use client";
|
||||
import { Canvas, useFrame } from "@react-three/fiber";
|
||||
import { Float, OrbitControls, Points, PointMaterial } from "@react-three/drei";
|
||||
import { useMemo, useRef } from "react";
|
||||
import * as THREE from "three";
|
||||
|
||||
function StarsBackground() {
|
||||
const ref = useRef<THREE.Points | null>(null);
|
||||
const positions = useMemo(() => {
|
||||
const p = new Float32Array(6000);
|
||||
for (let i = 0; i < 6000; i += 3) {
|
||||
p[i] = (Math.random() - 0.5) * 60;
|
||||
p[i + 1] = (Math.random() - 0.5) * 60;
|
||||
p[i + 2] = (Math.random() - 0.5) * 60;
|
||||
}
|
||||
return p;
|
||||
}, []);
|
||||
useFrame((_, delta) => {
|
||||
if (ref.current) ref.current.rotation.y += delta * 0.015;
|
||||
});
|
||||
return (
|
||||
<group rotation={[0, 0, Math.PI / 8]}>
|
||||
<Points ref={ref} positions={positions} stride={3} frustumCulled>
|
||||
<PointMaterial
|
||||
transparent
|
||||
color="#60a5fa"
|
||||
size={0.06}
|
||||
sizeAttenuation
|
||||
depthWrite={false}
|
||||
/>
|
||||
</Points>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
function DataCore() {
|
||||
const coreRef = useRef<THREE.Group | null>(null);
|
||||
const orbitRef = useRef<THREE.Group | null>(null);
|
||||
const nodesRef = useRef<THREE.Group | null>(null);
|
||||
|
||||
// Pre-generate node positions on a tilted orbit
|
||||
const nodes = useMemo(() => {
|
||||
const arr: { position: [number, number, number] }[] = [];
|
||||
const radius = 2.4;
|
||||
for (let i = 0; i < 14; i++) {
|
||||
const a = (i / 14) * Math.PI * 2;
|
||||
const tilt = 0.45; // slight vertical variation
|
||||
arr.push({ position: [Math.cos(a) * radius, Math.sin(a) * tilt, Math.sin(a) * radius] });
|
||||
}
|
||||
return arr;
|
||||
}, []);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (coreRef.current) coreRef.current.rotation.y += delta * 0.15;
|
||||
if (orbitRef.current) orbitRef.current.rotation.y -= delta * 0.1;
|
||||
if (nodesRef.current) nodesRef.current.rotation.y += delta * 0.22;
|
||||
});
|
||||
|
||||
return (
|
||||
<group position={[0, 0, -4]}>
|
||||
{/* Central sphere */}
|
||||
<mesh ref={coreRef}>
|
||||
<icosahedronGeometry args={[1.05, 2]} />
|
||||
<meshStandardMaterial
|
||||
color="#3b82f6"
|
||||
emissive="#1e40af"
|
||||
emissiveIntensity={0.85}
|
||||
metalness={0.35}
|
||||
roughness={0.3}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Subtle inner glow shell */}
|
||||
<mesh>
|
||||
<sphereGeometry args={[1.35, 32, 32]} />
|
||||
<meshBasicMaterial color="#60a5fa" transparent opacity={0.08} />
|
||||
</mesh>
|
||||
|
||||
{/* Rotating analytic rings */}
|
||||
<group ref={orbitRef}>
|
||||
{[
|
||||
{ r: 1.75, rot: [Math.PI / 2, 0, 0] },
|
||||
{ r: 2.0, rot: [0.35, 0.6, 0] },
|
||||
{ r: 2.25, rot: [0.9, 0.2, 0.4] },
|
||||
].map((cfg, i) => (
|
||||
<mesh key={i} rotation={cfg.rot as [number, number, number]}>
|
||||
<torusGeometry args={[cfg.r, 0.015, 8, 160]} />
|
||||
<meshStandardMaterial
|
||||
color="#64748b"
|
||||
emissive="#1e293b"
|
||||
emissiveIntensity={0.25}
|
||||
metalness={0.2}
|
||||
roughness={0.4}
|
||||
/>
|
||||
</mesh>
|
||||
))}
|
||||
</group>
|
||||
|
||||
{/* Orbiting nodes */}
|
||||
<group ref={nodesRef}>
|
||||
{nodes.map((n, idx) => (
|
||||
<mesh key={idx} position={n.position}>
|
||||
<sphereGeometry args={[0.09, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
color="#93c5fd"
|
||||
emissive="#1d4ed8"
|
||||
emissiveIntensity={0.6}
|
||||
metalness={0.3}
|
||||
roughness={0.35}
|
||||
/>
|
||||
</mesh>
|
||||
))}
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Scene() {
|
||||
return (
|
||||
<div className="fixed inset-0 -z-10">
|
||||
<Canvas camera={{ position: [0, 0, 16], fov: 65 }}>
|
||||
<StarsBackground />
|
||||
<ambientLight intensity={0.5} />
|
||||
<pointLight position={[8, 6, 8]} intensity={1.4} />
|
||||
<pointLight position={[-6, -4, -6]} intensity={0.6} color="#1e3a8a" />
|
||||
<OrbitControls enableZoom={false} enablePan={false} autoRotate autoRotateSpeed={0.4} />
|
||||
<Float speed={1.2} floatIntensity={1.4} rotationIntensity={0.6}>
|
||||
<DataCore />
|
||||
</Float>
|
||||
</Canvas>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
7
next.config.ts
Normal file
7
next.config.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* config options here */
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
33
package.json
Normal file
33
package.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "phylab",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build --turbopack",
|
||||
"start": "next start",
|
||||
"lint": "biome check",
|
||||
"format": "biome format --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"next": "15.5.0",
|
||||
"three": "^0.170.0",
|
||||
"@react-three/fiber": "^9.0.0",
|
||||
"@react-three/drei": "^9.114.0",
|
||||
"framer-motion": "^11.0.0",
|
||||
"lucide-react": "^0.474.0",
|
||||
"clsx": "^2.1.1",
|
||||
"next-themes": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"tailwindcss": "^4",
|
||||
"@biomejs/biome": "2.2.0"
|
||||
}
|
||||
}
|
||||
5
postcss.config.mjs
Normal file
5
postcss.config.mjs
Normal file
@ -0,0 +1,5 @@
|
||||
const config = {
|
||||
plugins: ["@tailwindcss/postcss"],
|
||||
};
|
||||
|
||||
export default config;
|
||||
BIN
public/videos/mechanics.mp4
Normal file
BIN
public/videos/mechanics.mp4
Normal file
Binary file not shown.
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user