teto_ai/dashboard_mockups/gemini_mockup.html

539 lines
32 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kasane Teto - Neural Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-dark: #1a1a1d;
--bg-panel: #232328; /* Slightly lighter panel */
--border-color: #4a4a52;
--text-primary: #f5f5f5;
--text-secondary: #a9a9b3;
--accent-red: #e53e3e;
--accent-red-glow: rgba(229, 62, 62, 0.5);
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--bg-dark);
color: var(--text-primary);
}
#bg-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.15;
}
.panel {
background-color: var(--bg-panel);
border: 1px solid var(--border-color);
border-radius: 8px;
transition: all 0.3s ease-in-out;
}
.nav-item {
padding: 8px 16px;
border-radius: 6px;
transition: background-color 0.2s ease-in-out;
cursor: pointer;
}
.nav-item.active, .nav-item:hover {
background-color: var(--border-color);
}
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: var(--bg-dark); }
::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--accent-red); }
.brain-footer {
margin-top: 2rem;
background-color: var(--bg-panel);
border: 1px solid var(--border-color);
border-radius: 8px;
}
.brain-node {
display: flex;
align-items: center;
justify-content: center;
width: 65px;
height: 65px;
border-radius: 50%;
border: 2px solid var(--border-color);
background-color: var(--bg-dark);
font-size: 0.7rem;
font-weight: 600;
text-align: center;
transition: all 0.2s ease-in-out;
position: relative;
z-index: 2;
flex-shrink: 0;
}
.brain-connector {
height: 2px;
flex-grow: 1;
background-color: var(--border-color);
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 var(--accent-red-glow); transform: scale(1.05); }
70% { box-shadow: 0 0 10px 12px rgba(229, 62, 62, 0); }
100% { box-shadow: 0 0 0 0 rgba(229, 62, 62, 0); transform: scale(1); }
}
.brain-node.active {
border-color: var(--accent-red);
color: white;
animation: pulse 1s ease-out;
}
#memory-explorer-canvas {
display: block;
width: 100%;
height: 100%;
}
</style>
</head>
<body class="p-4 lg:p-6">
<canvas id="bg-canvas"></canvas>
<div class="max-w-screen-xl mx-auto relative z-10">
<!-- Header & Navigation -->
<header class="flex flex-wrap justify-between items-center mb-6">
<div class="flex items-center space-x-4">
<div class="w-12 h-12 bg-red-600 rounded-full flex items-center justify-center text-2xl font-bold text-white shadow-lg">04</div>
<div>
<h1 class="text-2xl font-bold text-white">Kasane Teto - Neural Dashboard</h1>
<p class="text-sm text-gray-400">What are you looking at, baka?! Just kidding, welcome!</p>
</div>
</div>
<div class="flex items-center space-x-4 mt-4 sm:mt-0">
<div class="flex items-center space-x-3">
<img src="https://placehold.co/40x40/e53e3e/ffffff?text=A" alt="User Avatar" class="rounded-full">
<p class="font-semibold text-white">Alice#1234</p>
</div>
<button class="bg-gray-700 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded-lg transition-colors">Logout</button>
</div>
</header>
<nav class="flex space-x-2 panel p-2 mb-6">
<div class="nav-item active" data-tab="overview">Overview</div>
<div class="nav-item" data-tab="memory">Memory Explorer</div>
<div class="nav-item" data-tab="analytics">Server Analytics</div>
<div class="nav-item" data-tab="archives">Archives</div>
<div class="nav-item" data-tab="profile">My Profile</div>
</nav>
<!-- Main Content Area -->
<main>
<!-- Overview Page -->
<div id="tab-overview" class="tab-content grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="panel p-4 lg:col-span-3">
<h2 class="text-xl font-semibold mb-3 text-white">Neural Status</h2>
<div class="flex flex-wrap gap-x-8 gap-y-4">
<div class="flex items-center space-x-3"><span class="text-2xl">🤔</span><div><h3 class="font-semibold">Pondering</h3><p class="text-sm text-gray-400">Current Mood</p></div></div>
<div class="flex items-center space-x-3"><span class="text-2xl">🎮</span><div><h3 class="font-semibold">Playing Minecraft</h3><p class="text-sm text-gray-400">Current Activity</p></div></div>
<div class="flex items-center space-x-3"><span class="text-2xl">🇵🇱</span><div><h3 class="font-semibold">Polish</h3><p class="text-sm text-gray-400">Language Focus</p></div></div>
</div>
</div>
<div class="panel p-4 h-80 lg:col-span-1">
<h2 class="text-xl font-semibold mb-3 text-white">Live Thoughts</h2>
<div class="bg-black/20 p-2 rounded-md h-[calc(100%-40px)] overflow-y-auto"><pre class="text-xs text-gray-300 whitespace-pre-wrap font-mono">10:53:01 PM | Heh, a new message from Bob. Let's see...</pre></div>
</div>
<div class="panel p-4 h-80 lg:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h2 class="text-xl font-semibold mb-3 text-white">System Status</h2>
<div class="space-y-4">
<div>
<p class="text-sm font-medium text-gray-400">VRAM Usage</p>
<div class="w-full bg-gray-700 rounded-full h-2.5"><div class="bg-red-500 h-2.5 rounded-full" style="width: 78%"></div></div>
<p class="text-right text-sm font-mono text-white">18.7 / 24 GB</p>
</div>
<div>
<p class="text-sm font-medium text-gray-400">Time Until Euthanasia</p>
<p id="euthanasia-timer" class="text-2xl font-mono text-red-400">--d --h --m --s</p>
</div>
</div>
</div>
<div>
<h2 class="text-xl font-semibold mb-3 text-white">Last Response Breakdown</h2>
<div id="response-breakdown" class="space-y-2 text-sm font-mono">
<p>Total: <span class="font-bold text-white">1250ms</span></p>
<div class="w-full flex h-5 rounded overflow-hidden">
<div class="bg-blue-500" style="width: 12%" title="STT: 150ms"></div>
<div class="bg-purple-500" style="width: 64%" title="Reasoning: 800ms"></div>
<div class="bg-pink-500" style="width: 24%" title="TTS: 300ms"></div>
</div>
<ul class="text-xs text-gray-400">
<li><span class="text-blue-400"></span> STT: 150ms</li>
<li><span class="text-purple-400"></span> Reasoning: 800ms</li>
<li><span class="text-pink-400"></span> TTS: 300ms</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Memory Explorer Page -->
<div id="tab-memory" class="tab-content hidden">
<div class="panel p-4 h-[80vh] flex flex-col">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold text-white">Memory Vector Space</h2>
<input type="text" placeholder="Search memories..." class="bg-gray-900/50 border border-gray-700 rounded-md px-3 py-1 text-sm w-64 focus:outline-none focus:ring-2 focus:ring-red-500">
</div>
<div class="relative flex-1 rounded-lg bg-black/30 overflow-hidden">
<canvas id="memory-explorer-canvas"></canvas>
</div>
</div>
</div>
<!-- Analytics Page -->
<div id="tab-analytics" class="tab-content hidden grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<div class="panel p-4 md:col-span-1">
<h3 class="font-semibold text-white mb-2">Activity Leaderboard</h3>
<ul class="space-y-3">
<li class="flex items-center space-x-3"><span class="bg-red-500 rounded-full w-6 h-6 flex items-center justify-center text-xs">1</span><span>Charlie</span><span class="ml-auto text-gray-400 text-sm">1,204</span></li>
<li class="flex items-center space-x-3"><span class="bg-gray-600 rounded-full w-6 h-6 flex items-center justify-center text-xs">2</span><span>Alice</span><span class="ml-auto text-gray-400 text-sm">987</span></li>
<li class="flex items-center space-x-3"><span class="bg-gray-600 rounded-full w-6 h-6 flex items-center justify-center text-xs">3</span><span>Bob</span><span class="ml-auto text-gray-400 text-sm">755</span></li>
</ul>
</div>
<div class="panel p-4 md:col-span-1">
<h3 class="font-semibold text-white mb-2">Language Distribution</h3>
<div class="space-y-2 text-sm">
<div><p>English</p><div class="w-full bg-gray-700 rounded-full h-2"><div class="bg-blue-500 h-2 rounded-full" style="width: 45%"></div></div></div>
<div><p>Polish</p><div class="w-full bg-gray-700 rounded-full h-2"><div class="bg-red-500 h-2 rounded-full" style="width: 30%"></div></div></div>
<div><p>Japanese</p><div class="w-full bg-gray-700 rounded-full h-2"><div class="bg-pink-400 h-2 rounded-full" style="width: 15%"></div></div></div>
<div><p>Other</p><div class="w-full bg-gray-700 rounded-full h-2"><div class="bg-gray-500 h-2 rounded-full" style="width: 10%"></div></div></div>
</div>
</div>
<div class="panel p-4 md:col-span-2 lg:col-span-1">
<h3 class="font-semibold text-white mb-2">Server Sentiment</h3>
<div class="text-center">
<p class="text-5xl font-bold text-green-400">78%</p>
<p class="text-lg font-semibold text-green-400">Positive</p>
</div>
<ul class="text-xs space-y-1 mt-3">
<li class="flex justify-between"><span>😊 Positive</span><span>78%</span></li>
<li class="flex justify-between"><span>😐 Neutral</span><span>18%</span></li>
<li class="flex justify-between"><span>😠 Negative</span><span>4%</span></li>
</ul>
</div>
<div class="panel p-4 md:col-span-2 lg:col-span-1">
<h3 class="font-semibold text-white mb-2">Trending Topics</h3>
<div class="flex flex-wrap gap-2">
<span class="bg-gray-700 text-sm px-3 py-1 rounded-full">Gaming</span>
<span class="bg-gray-700 text-sm px-3 py-1 rounded-full">French Bread</span>
<span class="bg-gray-700 text-sm px-3 py-1 rounded-full">Minecraft</span>
<span class="bg-gray-700 text-sm px-3 py-1 rounded-full">Music</span>
<span class="bg-gray-700 text-sm px-3 py-1 rounded-full">Memes</span>
</div>
</div>
<div class="panel p-4 lg:col-span-4">
<h3 class="font-semibold text-white mb-2">Activity Heatmap</h3>
<div class="grid grid-cols-7 gap-1 text-xs text-center">
<span>Mon</span><span>Tue</span><span>Wed</span><span>Thu</span><span>Fri</span><span>Sat</span><span>Sun</span>
<div class="w-full h-8 bg-gray-800 rounded"></div>
<div class="w-full h-8 bg-red-900 rounded"></div>
<div class="w-full h-8 bg-red-800 rounded"></div>
<div class="w-full h-8 bg-red-900 rounded"></div>
<div class="w-full h-8 bg-red-600 rounded"></div>
<div class="w-full h-8 bg-red-500 rounded"></div>
<div class="w-full h-8 bg-red-600 rounded"></div>
</div>
</div>
</div>
<!-- Archives Page -->
<div id="tab-archives" class="tab-content hidden">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="lg:col-span-1 panel p-4 h-[80vh] flex flex-col">
<h2 class="text-xl font-semibold mb-3 text-white">Archived Logs</h2>
<div class="overflow-y-auto flex-1 pr-2">
<h3 class="font-semibold text-red-400 mt-4 mb-2">Voice Calls</h3>
<ul class="space-y-2">
<li data-archive="vc1" class="archive-item cursor-pointer p-2 rounded-md hover:bg-gray-700/50"><p class="font-semibold">Late Night Gaming Session</p><p class="text-xs text-gray-400">July 19, 2025 - 1h 24m</p></li>
</ul>
<h3 class="font-semibold text-red-400 mt-4 mb-2">Text Chats</h3>
<ul class="space-y-2">
<li data-archive="txt1" class="archive-item cursor-pointer p-2 rounded-md hover:bg-gray-700/50"><p class="font-semibold">#memes - Yesterday's Highlights</p><p class="text-xs text-gray-400">July 19, 2025 - 58 messages</p></li>
</ul>
</div>
</div>
<div class="lg:col-span-2 panel p-4 h-[80vh] flex flex-col">
<div id="archive-display" class="flex-1">
<div id="archive-vc1" class="archive-content hidden h-full flex flex-col">
<h2 class="text-xl font-semibold mb-3 text-white">Voice: Late Night Gaming Session</h2>
<div class="bg-black/20 p-3 rounded-md flex items-center space-x-4"><button class="text-2xl">▶️</button><div class="flex-1"><div class="w-full h-2 bg-gray-600 rounded-full"><div class="w-1/4 h-full bg-red-500 rounded-full"></div></div><div class="text-xs text-gray-400 flex justify-between mt-1"><span>21:05</span><span>1:24:33</span></div></div></div>
<div class="overflow-y-auto flex-1 mt-4 bg-black/20 p-3 rounded-md"><div class="space-y-3 text-sm"><p><span class="font-semibold text-blue-400">[0:15] Alice:</span> Okay, is everyone ready?</p><p><span class="font-semibold text-green-400">[0:18] Bob:</span> Yep, just grabbing a drink.</p><p><span class="font-semibold text-red-400">[0:25] Teto:</span> I was born ready! Let's do this!</p></div></div>
</div>
<div id="archive-txt1" class="archive-content hidden h-full flex flex-col">
<h2 class="text-xl font-semibold mb-3 text-white">Chat: #memes</h2>
<div class="overflow-y-auto flex-1 mt-4 bg-black/20 p-3 rounded-md space-y-4"><div class="flex items-start space-x-3"><img src="https://placehold.co/40x40/7289da/ffffff?text=C" class="rounded-full flex-shrink-0" alt=""><div class="w-full"><p class="font-semibold text-yellow-400">Charlie <span class="text-xs text-gray-500 ml-2">Yesterday at 10:31 PM</span></p><p>Check this out</p><img src="https://placehold.co/300x200/cccccc/000000?text=Funny+Cat+Meme" class="mt-2 rounded-lg" alt="meme"></div></div><div class="flex items-start space-x-3"><img src="https://placehold.co/40x40/e53e3e/ffffff?text=T" class="rounded-full flex-shrink-0" alt=""><div class="w-full"><p class="font-semibold text-red-400">Kasane Teto <span class="text-xs text-gray-500 ml-2">Yesterday at 10:32 PM</span></p><p>Hah! Classic. That's a 10/10 meme right there.</p></div></div></div>
</div>
<div id="archive-placeholder" class="flex items-center justify-center h-full text-gray-500"><p>Select an archive to view its contents.</p></div>
</div>
</div>
</div>
</div>
<!-- Profile Page -->
<div id="tab-profile" class="tab-content hidden grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="panel p-6 lg:col-span-1">
<h2 class="text-xl font-semibold text-white">Teto's Take on You</h2>
<div class="relative my-4">
<div class="w-24 h-24 bg-red-900 rounded-full mx-auto flex items-center justify-center">
<p class="text-4xl font-bold text-red-300">87%</p>
</div>
<p class="text-center text-sm text-red-400 font-semibold mt-1">Friendship Level</p>
</div>
<p class="text-sm italic text-gray-300">"Alice? Oh, she's absolutely fantastic! A bit too serious about work sometimes, but her taste in music is *chef's kiss*. She actually gets my bread obsession and doesn't judge me for it. Plus, she's one of the few people who can keep up with my random 3 AM philosophical rants. We should totally do a Minecraft build together sometime - I bet she'd make an amazing castle!"</p>
<h3 class="font-semibold text-white mt-6 mb-2">How I See You</h3>
<div class="flex flex-wrap gap-2">
<span class="bg-green-500/20 text-green-300 text-xs px-2 py-1 rounded-full">Witty</span>
<span class="bg-blue-500/20 text-blue-300 text-xs px-2 py-1 rounded-full">Music Lover</span>
<span class="bg-yellow-500/20 text-yellow-300 text-xs px-2 py-1 rounded-full">Workaholic</span>
<span class="bg-purple-500/20 text-purple-300 text-xs px-2 py-1 rounded-full">Patient</span>
<span class="bg-pink-500/20 text-pink-300 text-xs px-2 py-1 rounded-full">Creative</span>
</div>
</div>
<div class="lg:col-span-2 flex flex-col gap-6">
<div class="panel p-6">
<h2 class="text-xl font-semibold text-white mb-3">Our Greatest Hits</h2>
<ul class="space-y-4 text-sm">
<li class="flex items-center space-x-4"><span class="text-2xl">🥖</span><div><p class="font-semibold">The Great Bread Debate of 2025</p><p class="text-gray-400">That legendary 2-hour discussion about why French bread is superior.</p></div></li>
<li class="flex items-center space-x-4"><span class="text-2xl">🎵</span><div><p class="font-semibold">Late Night Vocaloid Marathon</p><p class="text-gray-400">You shared that amazing playlist and we listened until 4 AM.</p></div></li>
</ul>
</div>
<div class="panel p-6">
<h2 class="text-xl font-semibold text-white mb-3">What I've Learned About You</h2>
<div class="grid grid-cols-2 gap-4 text-sm">
<div><h4 class="font-bold text-gray-400 mb-1">🎵 Music Preferences</h4><ul class="list-disc list-inside"><li>Loves Vocaloid classics</li><li>Prefers upbeat electronic</li></ul></div>
<div><h4 class="font-bold text-gray-400 mb-1">🎮 Gaming Style</h4><ul class="list-disc list-inside"><li>Strategic builder in MC</li><li>Enjoys puzzle games</li></ul></div>
<div><h4 class="font-bold text-gray-400 mb-1">💬 Communication</h4><ul class="list-disc list-inside"><li>Most active 8-11 PM</li><li>Enjoys deep conversations</li></ul></div>
<div><h4 class="font-bold text-gray-400 mb-1">🧠 Interests</h4><ul class="list-disc list-inside"><li>Learning languages (Polish!)</li><li>Technology and AI</li></ul></div>
</div>
</div>
</div>
<div class="panel p-6 lg:col-span-3">
<h2 class="text-xl font-semibold text-white mb-3">Your Data & Privacy</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-center">
<div><p class="text-3xl font-bold text-red-400">1,247</p><p class="text-xs text-gray-400">TEXT MESSAGES</p></div>
<div><p class="text-3xl font-bold text-red-400">87h</p><p class="text-xs text-gray-400">VOICE CONVERSATIONS</p></div>
<div><p class="text-3xl font-bold text-red-400">156</p><p class="text-xs text-gray-400">SHARED IMAGES</p></div>
<div><p class="text-3xl font-bold text-red-400">23</p><p class="text-xs text-gray-400">KEY MEMORIES</p></div>
</div>
<div class="mt-6 border-t border-gray-700 pt-6 flex flex-wrap gap-4">
<button class="bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-4 rounded-lg">Download Complete Archive</button>
<div class="border-l-2 border-red-500 pl-4"><p class="font-bold text-red-400">DANGER ZONE</p><button class="bg-red-800 hover:bg-red-700 text-white font-bold py-2 px-4 rounded-lg mt-1">Request Data Deletion</button></div>
</div>
</div>
</div>
</main>
<!-- Brain Overview Footer -->
<footer class="brain-footer p-4">
<div class="max-w-xl mx-auto flex items-center justify-center space-x-1 md:space-x-2">
<div id="node-reading" class="brain-node">Reading</div><div class="brain-connector"></div>
<div id="node-fetching" class="brain-node">Fetching</div><div class="brain-connector"></div>
<div id="node-reasoning" class="brain-node">Reasoning</div><div class="brain-connector"></div>
<div id="node-writing" class="brain-node">Writing</div><div class="brain-connector"></div>
<div id="node-speaking" class="brain-node">Speaking</div><div class="brain-connector"></div>
<div id="node-remembering" class="brain-node">Remembering</div>
</div>
<div class="text-center mt-4"><button id="simulate-activity" class="text-xs bg-red-800/50 hover:bg-red-700/50 px-3 py-1 rounded-md transition-colors">Simulate Activity</button></div>
</footer>
</div>
<script>
// --- Background Synapse Canvas ---
const bgCanvas = document.getElementById('bg-canvas');
const bgCtx = bgCanvas.getContext('2d');
let synapses = [];
function resizeBgCanvas() {
bgCanvas.width = window.innerWidth;
bgCanvas.height = window.innerHeight;
}
resizeBgCanvas();
window.addEventListener('resize', resizeBgCanvas);
class Synapse {
constructor() { this.reset(); }
reset() {
this.x = Math.random() * bgCanvas.width;
this.y = Math.random() * bgCanvas.height;
this.life = 0;
this.maxLife = Math.random() * 100 + 50;
this.vx = (Math.random() - 0.5) * 2;
this.vy = (Math.random() - 0.5) * 2;
}
draw() {
bgCtx.beginPath();
bgCtx.moveTo(this.x, this.y);
this.x += this.vx;
this.y += this.vy;
bgCtx.lineTo(this.x, this.y);
const opacity = 1 - (this.life / this.maxLife);
bgCtx.strokeStyle = `rgba(229, 62, 62, ${opacity * 0.5})`;
bgCtx.lineWidth = 1;
bgCtx.stroke();
this.life++;
if (this.life >= this.maxLife) this.reset();
}
}
for (let i = 0; i < 50; i++) {
synapses.push(new Synapse());
}
function animateBg() {
bgCtx.clearRect(0, 0, bgCanvas.width, bgCanvas.height);
synapses.forEach(s => s.draw());
requestAnimationFrame(animateBg);
}
animateBg();
// --- 3D Memory Explorer ---
let scene, camera, renderer, controls, points;
function initMemoryExplorer() {
const canvas = document.getElementById('memory-explorer-canvas');
if (!canvas) return;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, alpha: true });
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
renderer.setClearColor(0x000000, 0);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.screenSpacePanning = false;
controls.minDistance = 5;
controls.maxDistance = 50;
const geometry = new THREE.BufferGeometry();
const vertices = [];
const colors = [ new THREE.Color(0x3b82f6), new THREE.Color(0x22c55e), new THREE.Color(0xa855f7), new THREE.Color(0xe53e3e), new THREE.Color(0xeab308), new THREE.Color(0xf5f5f5) ];
const pointColors = [];
for (let i = 0; i < 5000; i++) {
const x = (Math.random() - 0.5) * 50;
const y = (Math.random() - 0.5) * 50;
const z = (Math.random() - 0.5) * 50;
vertices.push(x, y, z);
const color = colors[Math.floor(Math.random() * colors.length)];
pointColors.push(color.r, color.g, color.b);
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute('color', new THREE.Float32BufferAttribute(pointColors, 3));
const material = new THREE.PointsMaterial({ size: 0.1, vertexColors: true });
points = new THREE.Points(geometry, material);
scene.add(points);
camera.position.z = 20;
function animate() {
requestAnimationFrame(animate);
points.rotation.y += 0.0005;
controls.update();
renderer.render(scene, camera);
}
animate();
}
// --- Euthanasia Timer ---
const timerEl = document.getElementById('euthanasia-timer');
const endDate = new Date();
endDate.setDate(endDate.getDate() + 42); // Set 42 days from now
function updateTimer() {
if (!timerEl) return;
const now = new Date();
const diff = endDate - now;
const d = Math.floor(diff / (1000 * 60 * 60 * 24));
const h = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const s = Math.floor((diff % (1000 * 60)) / 1000);
timerEl.textContent = `${d}d ${h}h ${m}m ${s}s`;
}
// --- Tab Navigation & Initialization ---
const navItems = document.querySelectorAll('.nav-item');
const tabContents = document.querySelectorAll('.tab-content');
let memoryExplorerInitialized = false;
navItems.forEach(item => {
item.addEventListener('click', () => {
const tabId = item.getAttribute('data-tab');
navItems.forEach(nav => nav.classList.remove('active'));
item.classList.add('active');
tabContents.forEach(content => content.classList.add('hidden'));
const activeTab = document.getElementById(`tab-${tabId}`);
if (activeTab) activeTab.classList.remove('hidden');
if (tabId === 'memory' && !memoryExplorerInitialized) {
setTimeout(() => { // Allow canvas to become visible
initMemoryExplorer();
memoryExplorerInitialized = true;
}, 0);
}
});
});
document.addEventListener('DOMContentLoaded', () => {
// Re-bind events for dynamically added content
const archiveItems = document.querySelectorAll('.archive-item');
const archiveContents = document.querySelectorAll('.archive-content');
const archivePlaceholder = document.getElementById('archive-placeholder');
archiveItems.forEach(item => {
item.addEventListener('click', () => {
const archiveId = item.getAttribute('data-archive');
if(archivePlaceholder) archivePlaceholder.classList.add('hidden');
archiveContents.forEach(content => {
content.id === `archive-${archiveId}` ? content.classList.remove('hidden') : content.classList.add('hidden');
});
});
});
const simulateBtn = document.getElementById('simulate-activity');
const nodes = { reading: document.getElementById('node-reading'), fetching: document.getElementById('node-fetching'), reasoning: document.getElementById('node-reasoning'), writing: document.getElementById('node-writing'), speaking: document.getElementById('node-speaking'), remembering: document.getElementById('node-remembering') };
let isSimulating = false;
function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
async function runSimulation(scenario) {
if(isSimulating) return;
isSimulating = true;
Object.values(nodes).forEach(n => n && n.classList.remove('active'));
for (const step of scenario) {
if(nodes[step.node]) nodes[step.node].classList.add('active');
await sleep(step.duration);
}
Object.values(nodes).forEach(n => n && n.classList.remove('active'));
isSimulating = false;
}
const scenarios = [
[{ node: 'reading', duration: 500 }, { node: 'fetching', duration: 400 }, { node: 'reasoning', duration: 800 }, { node: 'writing', duration: 500 }],
[{ node: 'reading', duration: 800 }, { node: 'reasoning', duration: 1000 }, { node: 'speaking', duration: 1200 }],
[{ node: 'remembering', duration: 1500 }]
];
if(simulateBtn) {
simulateBtn.addEventListener('click', () => {
const randomScenario = scenarios[Math.floor(Math.random() * scenarios.length)];
runSimulation(randomScenario);
});
}
// Start timer
setInterval(updateTimer, 1000);
updateTimer();
});
</script>
</body>
</html>