Spaces:
Sleeping
Sleeping
| import React, { useState, useEffect, useCallback, useRef } from 'react'; | |
| import { | |
| Zap, Trash2, RefreshCw, Waves, | |
| ShieldAlert, Binary, BrainCircuit, Dna | |
| } from 'lucide-react'; | |
| import GridCell from './components/GridCell'; | |
| const GRID_SIZE = 8; | |
| const CELL_COUNT = GRID_SIZE * GRID_SIZE; | |
| const MAX_HISTORY = 50; | |
| // Pre-allocate empty arrays to avoid recreating on every clear | |
| const EMPTY_BOOLS = Object.freeze(Array(CELL_COUNT).fill(false)); | |
| const EMPTY_WEIGHTS = Object.freeze(Array(CELL_COUNT).fill(0)); | |
| const FULL_HISTORY = Object.freeze(Array(MAX_HISTORY).fill(100)); | |
| const App = () => { | |
| // ββ Render state (drives UI) ββ | |
| const [signalGrid, setSignalGrid] = useState([...EMPTY_BOOLS]); | |
| const [memoryGrid, setMemoryGrid] = useState([...EMPTY_BOOLS]); | |
| const [weights, setWeights] = useState([...EMPTY_WEIGHTS]); | |
| const [accuracy, setAccuracy] = useState(100); | |
| const [history, setHistory] = useState([...FULL_HISTORY]); | |
| const [glitch, setGlitch] = useState(false); | |
| const [isDrifting, setIsDrifting] = useState(false); | |
| // Slider state (UI display) | |
| const [strength, setStrength] = useState(85); | |
| const [frequency, setFrequency] = useState(50); | |
| const [persistence, setPersistence] = useState(30); | |
| const [crossTalk, setCrossTalk] = useState(20); | |
| const [plasticity, setPlasticity] = useState(40); | |
| // ββ Refs (simulation reads from these β no dependency churn) ββ | |
| const signalRef = useRef(signalGrid); | |
| const memoryRef = useRef(memoryGrid); | |
| const weightsRef = useRef(weights); | |
| const strengthRef = useRef(strength); | |
| const frequencyRef = useRef(frequency); | |
| const persistenceRef = useRef(persistence); | |
| const crossTalkRef = useRef(crossTalk); | |
| const plasticityRef = useRef(plasticity); | |
| const isDriftingRef = useRef(isDrifting); | |
| const simTimerRef = useRef(null); | |
| const driftTimerRef = useRef(null); | |
| const waveCanvasRef = useRef(null); | |
| const waveFrameRef = useRef(null); | |
| const waveFrameCount = useRef(0); | |
| const accuracyRef = useRef(100); | |
| const containerRef = useRef(null); | |
| // Keep refs in sync with state | |
| useEffect(() => { signalRef.current = signalGrid; }, [signalGrid]); | |
| useEffect(() => { strengthRef.current = strength; }, [strength]); | |
| useEffect(() => { frequencyRef.current = frequency; }, [frequency]); | |
| useEffect(() => { persistenceRef.current = persistence; }, [persistence]); | |
| useEffect(() => { crossTalkRef.current = crossTalk; }, [crossTalk]); | |
| useEffect(() => { plasticityRef.current = plasticity; }, [plasticity]); | |
| useEffect(() => { isDriftingRef.current = isDrifting; }, [isDrifting]); | |
| // ββ Actions ββ | |
| const generatePattern = useCallback(() => { | |
| const newGrid = Array.from({ length: CELL_COUNT }, () => Math.random() > 0.8); | |
| setSignalGrid(newGrid); | |
| signalRef.current = newGrid; | |
| setGlitch(true); | |
| setTimeout(() => setGlitch(false), 150); | |
| }, []); | |
| const clearGrids = useCallback(() => { | |
| const s = [...EMPTY_BOOLS]; | |
| const m = [...EMPTY_BOOLS]; | |
| const w = [...EMPTY_WEIGHTS]; | |
| setSignalGrid(s); | |
| setMemoryGrid(m); | |
| setWeights(w); | |
| setHistory([...FULL_HISTORY]); | |
| signalRef.current = s; | |
| memoryRef.current = m; | |
| weightsRef.current = w; | |
| accuracyRef.current = 100; | |
| }, []); | |
| const toggleBlock = useCallback((index) => { | |
| setSignalGrid(prev => { | |
| const next = [...prev]; | |
| next[index] = !next[index]; | |
| signalRef.current = next; | |
| return next; | |
| }); | |
| }, []); | |
| // ββ Signal Drift ββ | |
| useEffect(() => { | |
| const runDrift = () => { | |
| if (!isDriftingRef.current) return; | |
| setSignalGrid(prev => { | |
| const next = [...prev]; | |
| const last = next.pop(); | |
| next.unshift(last); | |
| signalRef.current = next; | |
| return next; | |
| }); | |
| }; | |
| // Restart drift interval when frequency or drift toggle changes | |
| clearInterval(driftTimerRef.current); | |
| if (isDrifting) { | |
| driftTimerRef.current = setInterval(runDrift, 2000 - frequency * 15); | |
| } | |
| return () => clearInterval(driftTimerRef.current); | |
| }, [isDrifting, frequency]); | |
| // ββ Main Simulation Loop (runs once on mount) ββ | |
| useEffect(() => { | |
| const tick = () => { | |
| const signal = signalRef.current; | |
| const prevMemory = memoryRef.current; | |
| const prevWeights = weightsRef.current; | |
| const str = strengthRef.current; | |
| const freq = frequencyRef.current; | |
| const pers = persistenceRef.current; | |
| const ct = crossTalkRef.current; | |
| const plast = plasticityRef.current; | |
| const baseSnrThreshold = (100 - str) / 100; | |
| // Build next memory | |
| const nextGrid = new Array(CELL_COUNT); | |
| for (let i = 0; i < CELL_COUNT; i++) { | |
| const noise = Math.random(); | |
| const shouldUpdate = Math.random() < freq / 100; | |
| if (!shouldUpdate) { | |
| nextGrid[i] = prevMemory[i]; | |
| continue; | |
| } | |
| const localWeight = prevWeights[i] * (plast / 100); | |
| const effectiveThreshold = Math.max(0.01, baseSnrThreshold - localWeight); | |
| if (signal[i]) { | |
| nextGrid[i] = noise > effectiveThreshold; | |
| } else if (prevMemory[i] && Math.random() < pers / 100) { | |
| nextGrid[i] = true; | |
| } else { | |
| nextGrid[i] = noise < effectiveThreshold / 20; | |
| } | |
| } | |
| // Spatial cross-talk | |
| let finalGrid = nextGrid; | |
| if (ct > 0) { | |
| finalGrid = new Array(CELL_COUNT); | |
| for (let i = 0; i < CELL_COUNT; i++) { | |
| if (nextGrid[i]) { | |
| finalGrid[i] = true; | |
| continue; | |
| } | |
| const row = (i / GRID_SIZE) | 0; | |
| const col = i % GRID_SIZE; | |
| let activeNeighbors = 0; | |
| for (let r = -1; r <= 1; r++) { | |
| for (let c = -1; c <= 1; c++) { | |
| if (r === 0 && c === 0) continue; | |
| const nr = row + r, nc = col + c; | |
| if (nr >= 0 && nr < GRID_SIZE && nc >= 0 && nc < GRID_SIZE) { | |
| if (nextGrid[nr * GRID_SIZE + nc]) activeNeighbors++; | |
| } | |
| } | |
| } | |
| finalGrid[i] = Math.random() < activeNeighbors * (ct / 1000); | |
| } | |
| } | |
| // Hebbian weight update | |
| const nextWeights = new Array(CELL_COUNT); | |
| for (let i = 0; i < CELL_COUNT; i++) { | |
| if (signal[i] && finalGrid[i]) { | |
| nextWeights[i] = Math.min(1, prevWeights[i] + 0.02); | |
| } else if (!signal[i] && !finalGrid[i]) { | |
| nextWeights[i] = prevWeights[i]; | |
| } else { | |
| nextWeights[i] = Math.max(0, prevWeights[i] - 0.01); | |
| } | |
| } | |
| // Accuracy | |
| let matches = 0; | |
| for (let i = 0; i < CELL_COUNT; i++) { | |
| if (signal[i] === finalGrid[i]) matches++; | |
| } | |
| const acc = Math.round((matches / CELL_COUNT) * 100); | |
| // Commit to refs | |
| memoryRef.current = finalGrid; | |
| weightsRef.current = nextWeights; | |
| accuracyRef.current = acc; | |
| // Batch state updates | |
| setMemoryGrid(finalGrid); | |
| setWeights(nextWeights); | |
| setAccuracy(acc); | |
| setHistory(prev => { | |
| const next = [...prev]; | |
| next.shift(); | |
| next.push(acc); | |
| return next; | |
| }); | |
| }; | |
| // Adaptive tick rate β re-read frequency ref each cycle | |
| const scheduleNext = () => { | |
| const intervalTime = Math.max(16, 1000 - frequencyRef.current * 9.8); | |
| simTimerRef.current = setTimeout(() => { | |
| tick(); | |
| scheduleNext(); | |
| }, intervalTime); | |
| }; | |
| scheduleNext(); | |
| return () => clearTimeout(simTimerRef.current); | |
| }, []); // mount-only β reads everything from refs | |
| // ββ Waveform Canvas (ResizeObserver + proper rAF cleanup) ββ | |
| useEffect(() => { | |
| const canvas = waveCanvasRef.current; | |
| if (!canvas) return; | |
| const ctx = canvas.getContext('2d'); | |
| const container = canvas.parentElement; | |
| // Sync canvas resolution to container | |
| const resizeCanvas = () => { | |
| const rect = container.getBoundingClientRect(); | |
| const dpr = window.devicePixelRatio || 1; | |
| canvas.width = rect.width * dpr; | |
| canvas.height = rect.height * dpr; | |
| ctx.scale(dpr, dpr); | |
| canvas.style.width = rect.width + 'px'; | |
| canvas.style.height = rect.height + 'px'; | |
| }; | |
| const ro = new ResizeObserver(resizeCanvas); | |
| ro.observe(container); | |
| resizeCanvas(); | |
| const animate = () => { | |
| waveFrameCount.current++; | |
| const frame = waveFrameCount.current; | |
| const w = canvas.width / (window.devicePixelRatio || 1); | |
| const h = canvas.height / (window.devicePixelRatio || 1); | |
| ctx.clearRect(0, 0, w, h); | |
| ctx.beginPath(); | |
| ctx.strokeStyle = accuracyRef.current < 50 ? '#ff0055' : '#00ff9f'; | |
| ctx.lineWidth = 2; | |
| const freq = frequencyRef.current; | |
| const str = strengthRef.current; | |
| const freqMod = freq / 20; | |
| const ampMod = str / 4; | |
| const noiseMod = (100 - str) / 5; | |
| for (let x = 0; x < w; x++) { | |
| const y = h / 2 + | |
| Math.sin(x * 0.05 * freqMod + frame * 0.1) * ampMod + | |
| Math.sin(x * 0.1 + frame * 0.2) * noiseMod; | |
| if (x === 0) ctx.moveTo(x, y); | |
| else ctx.lineTo(x, y); | |
| } | |
| ctx.stroke(); | |
| waveFrameRef.current = requestAnimationFrame(animate); | |
| }; | |
| waveFrameRef.current = requestAnimationFrame(animate); | |
| return () => { | |
| cancelAnimationFrame(waveFrameRef.current); | |
| ro.disconnect(); | |
| }; | |
| }, []); | |
| // ββ Slider helpers ββ | |
| const sliderHandler = useCallback((setter, ref) => (e) => { | |
| const v = parseInt(e.target.value); | |
| setter(v); | |
| ref.current = v; | |
| }, []); | |
| return ( | |
| <div className={`min-h-screen p-4 md:p-6 font-mono selection:bg-[#00ff9f] selection:text-black transition-colors duration-500 ${accuracy < 25 ? 'bg-[#200] text-[#ff0055]' : 'bg-[#020202] text-[#00ff9f]'}`}> | |
| {/* Scanline overlay */} | |
| <div className="fixed inset-0 pointer-events-none z-50 opacity-[0.05] bg-[linear-gradient(rgba(18,16,16,0)_50%,rgba(0,0,0,0.25)_50%),linear-gradient(90deg,rgba(255,0,0,0.06),rgba(0,255,0,0.02),rgba(0,0,255,0.06))] bg-[length:100%_2px,3px_100%]" /> | |
| <div className="max-w-7xl mx-auto space-y-6"> | |
| {/* Header */} | |
| <header className="flex flex-col md:flex-row items-start md:items-center justify-between p-6 bg-[#0a0a0a] border-2 border-[#00ff9f]/20 rounded-sm relative overflow-hidden"> | |
| <div className="z-10 flex items-center gap-5"> | |
| <div className={`p-3 rounded-none shadow-lg transition-colors ${accuracy < 25 ? 'bg-[#ff0055] shadow-[#ff0055]' : 'bg-[#00ff9f] shadow-[#00ff9f]'}`}> | |
| <BrainCircuit size={32} className="text-black" /> | |
| </div> | |
| <div> | |
| <h1 className={`text-4xl font-black uppercase tracking-tighter ${glitch || accuracy < 25 ? 'animate-pulse' : ''}`}> | |
| Synapse_Link <span className="text-white text-2xl font-light opacity-50">HEBB-9</span> | |
| </h1> | |
| <div className="flex items-center gap-3 text-[10px] mt-1 font-bold opacity-60 uppercase"> | |
| <span className="flex items-center gap-1"><Dna size={12} /> PLASTICITY: ACTIVE</span> | |
| <span className={`flex items-center gap-1 ${accuracy < 40 ? 'text-[#ff0055] animate-bounce' : ''}`}> | |
| <ShieldAlert size={12} /> {accuracy < 25 ? 'CRITICAL DECOHERENCE' : 'SIGNAL STABLE'} | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| <div className="mt-4 md:mt-0 flex flex-wrap gap-3"> | |
| <button | |
| onClick={() => setIsDrifting(d => !d)} | |
| className={`px-6 py-3 font-black uppercase tracking-widest text-xs transition-all flex items-center gap-2 ${isDrifting ? 'bg-white text-black' : 'border border-[#00ff9f] text-[#00ff9f]'}`} | |
| > | |
| <Waves size={16} /> {isDrifting ? 'Stop Drift' : 'Enable Drift'} | |
| </button> | |
| <button onClick={generatePattern} className="bg-[#00ff9f] text-black px-6 py-3 font-black uppercase tracking-widest text-xs hover:bg-white transition-all shadow-md flex items-center gap-2"> | |
| <RefreshCw size={16} /> Sync Source | |
| </button> | |
| <button onClick={clearGrids} className="border border-[#ff0055] text-[#ff0055] px-6 py-3 font-black uppercase tracking-widest text-xs hover:bg-[#ff0055] hover:text-black transition-all flex items-center gap-2"> | |
| <Trash2 size={16} /> Purge | |
| </button> | |
| </div> | |
| </header> | |
| {/* Waveform + Fidelity */} | |
| <div className="grid lg:grid-cols-4 gap-6"> | |
| <div className="lg:col-span-3 bg-[#0a0a0a] border border-[#00ff9f]/20 p-4 relative h-32" ref={containerRef}> | |
| <div className="absolute top-2 left-2 text-[8px] opacity-40 uppercase font-black">Bio_Feedback_Wave</div> | |
| <canvas ref={waveCanvasRef} className="w-full h-full" /> | |
| </div> | |
| <div className={`bg-[#0a0a0a] border border-[#00ff9f]/20 p-4 flex flex-col justify-center items-center ${accuracy < 25 ? 'border-[#ff0055]' : ''}`}> | |
| <div className="text-[10px] uppercase opacity-40 font-black mb-1">Engram Fidelity</div> | |
| <div className={`text-4xl font-black italic tracking-tighter ${accuracy < 60 ? 'text-[#ff0055]' : 'text-white'}`}> | |
| {accuracy}.0 | |
| </div> | |
| <div className="w-full bg-[#111] h-1 mt-2"> | |
| <div className="bg-[#00ff9f] h-full transition-all" style={{ width: `${accuracy}%` }} /> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Grids */} | |
| <div className="grid lg:grid-cols-2 gap-8"> | |
| {/* Signal Input */} | |
| <div className="bg-[#0a0a0a] border-l-4 border-[#00ff9f] p-6 relative"> | |
| <div className="flex items-center justify-between mb-6"> | |
| <h3 className="font-black uppercase tracking-widest text-white flex items-center gap-2"> | |
| <Zap size={18} className="text-[#00ff9f]" /> Stimulus Source | |
| </h3> | |
| <div className="text-[10px] opacity-40 font-bold">MANUAL_OVERRIDE_ENABLED</div> | |
| </div> | |
| <div className="grid grid-cols-8 gap-2 aspect-square bg-black/40 p-3 border border-[#00ff9f]/10" role="grid" aria-label="Stimulus grid"> | |
| {signalGrid.map((active, i) => ( | |
| <GridCell key={i} active={active} variant="signal" weight={0} mismatch={false} onClick={() => toggleBlock(i)} /> | |
| ))} | |
| </div> | |
| </div> | |
| {/* Memory Output */} | |
| <div className="bg-[#0a0a0a] border-r-4 border-[#ff0055] p-6 relative"> | |
| <div className="flex items-center justify-between mb-6"> | |
| <h3 className="font-black uppercase tracking-widest text-white flex items-center gap-2"> | |
| <BrainCircuit size={18} className="text-[#ff0055]" /> Synaptic Cache | |
| </h3> | |
| <div className="flex items-center gap-2 text-[8px] font-bold"> | |
| <div className="w-2 h-2 bg-white rounded-full animate-ping" /> | |
| LEARNING_ACTIVE | |
| </div> | |
| </div> | |
| <div className="grid grid-cols-8 gap-2 aspect-square bg-black/40 p-3 border border-[#ff0055]/10" role="grid" aria-label="Synaptic memory grid"> | |
| {memoryGrid.map((active, i) => ( | |
| <GridCell key={i} active={active} variant="memory" weight={weights[i]} mismatch={signalGrid[i] !== active} /> | |
| ))} | |
| </div> | |
| </div> | |
| </div> | |
| {/* Sliders */} | |
| <div className="grid md:grid-cols-3 lg:grid-cols-5 gap-4"> | |
| <div className="bg-[#0a0a0a] p-4 border border-[#00ff9f]/20"> | |
| <label className="flex justify-between text-[10px] font-black uppercase mb-3"> | |
| <span>SNR_Amp</span><span>{strength}%</span> | |
| </label> | |
| <input type="range" min="0" max="100" value={strength} onChange={sliderHandler(setStrength, strengthRef)} className="w-full accent-[#00ff9f]" /> | |
| </div> | |
| <div className="bg-[#0a0a0a] p-4 border border-[#00ff9f]/20"> | |
| <label className="flex justify-between text-[10px] font-black uppercase mb-3"> | |
| <span>Refresh_Hz</span><span>{frequency}%</span> | |
| </label> | |
| <input type="range" min="1" max="100" value={frequency} onChange={sliderHandler(setFrequency, frequencyRef)} className="w-full accent-[#00ff9f]" /> | |
| </div> | |
| <div className="bg-[#0a0a0a] p-4 border border-[#ff0055]/20"> | |
| <label className="flex justify-between text-[10px] font-black uppercase mb-3 text-[#ff0055]"> | |
| <span>Persistence</span><span>{persistence}%</span> | |
| </label> | |
| <input type="range" min="0" max="100" value={persistence} onChange={sliderHandler(setPersistence, persistenceRef)} className="w-full accent-[#ff0055]" /> | |
| </div> | |
| <div className="bg-[#0a0a0a] p-4 border border-[#ff0055]/20"> | |
| <label className="flex justify-between text-[10px] font-black uppercase mb-3 text-[#ff0055]"> | |
| <span>Cross_Talk</span><span>{crossTalk}%</span> | |
| </label> | |
| <input type="range" min="0" max="100" value={crossTalk} onChange={sliderHandler(setCrossTalk, crossTalkRef)} className="w-full accent-[#ff0055]" /> | |
| </div> | |
| <div className="bg-[#111] p-4 border border-white/20"> | |
| <label className="flex justify-between text-[10px] font-black uppercase mb-3 text-white"> | |
| <span>Plasticity</span><span>{plasticity}%</span> | |
| </label> | |
| <input type="range" min="0" max="100" value={plasticity} onChange={sliderHandler(setPlasticity, plasticityRef)} className="w-full accent-white" /> | |
| </div> | |
| </div> | |
| {/* Telemetry Graph */} | |
| <div className="bg-[#0a0a0a] border border-[#00ff9f]/10 p-4 h-20 flex items-end gap-1 relative overflow-hidden" aria-label="Fidelity history"> | |
| <div className="absolute inset-0 bg-gradient-to-t from-[#ff0055]/10 to-transparent pointer-events-none" /> | |
| {history.map((val, i) => ( | |
| <div key={i} className={`flex-1 transition-all ${val < 50 ? 'bg-[#ff0055]' : 'bg-[#00ff9f]/40'}`} style={{ height: `${val}%` }} /> | |
| ))} | |
| </div> | |
| {/* Footer */} | |
| <footer className="p-4 bg-[#0a0a0a] border border-white/5 text-[9px] uppercase tracking-tighter opacity-60 grid grid-cols-2 gap-4"> | |
| <div className="flex gap-2"><Binary size={12} /> DATA_PAGING: STOCHASTIC_GRADIENT_ENABLED</div> | |
| <div className="text-right">SYNAPTIC_WEIGHTS_NORMALIZED // HEBBIAN_COEFFICIENT: {(plasticity / 100).toFixed(2)}</div> | |
| </footer> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default App; | |