webxos/ionicocean
___ ___ ___ ___ ___ ___ ___ ___ ___ / /\ / /\ ___ / /\ / /\ / /\ / /\ / /\ / /\ /__/\ / /::\ / /::| /__/\ / /::\ / /::\ / /::\ / /::\ / /::\ / /::| \__\:\ / /:/\:\ / /:|:| \__\:\ / /:/\:\ /… See the full description on the dataset page: https://huggingface.co/datasets/webxos/ionicocean.
288
1<!DOCTYPE html>2<html lang="en">3<head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>IONICSPHERE v7.0 - Real-Time Quantum Simulator</title>7 8 <!-- Libraries -->9 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>10 <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.min.js"></script>11 <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest/dist/tf.min.js"></script>12 <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>13 <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>14 <script src="https://cdn.jsdelivr.net/npm/gpu.js@latest/dist/gpu-browser.min.js"></script>15 16 <style>17 * {18 margin: 0;19 padding: 0;20 box-sizing: border-box;21 }22 23 body {24 font-family: 'Courier New', monospace;25 background: #000000;26 color: #00ff00;27 overflow: hidden;28 height: 100vh;29 display: flex;30 flex-direction: column;31 }32 33 /* Header */34 #header {35 background: rgba(0, 20, 0, 0.95);36 border-bottom: 2px solid #00ff00;37 padding: 10px 20px;38 display: flex;39 justify-content: space-between;40 align-items: center;41 z-index: 100;42 height: 60px;43 box-shadow: 0 0 20px rgba(0, 255, 0, 0.3);44 }45 46 .logo {47 font-size: 24px;48 font-weight: bold;49 color: #00ff00;50 text-shadow: 0 0 10px #00ff00;51 letter-spacing: 2px;52 }53 54 .status-indicator {55 display: flex;56 align-items: center;57 gap: 10px;58 }59 60 .live-dot {61 width: 12px;62 height: 12px;63 border-radius: 50%;64 background: #ff0000;65 box-shadow: 0 0 10px #ff0000;66 animation: pulse 1s infinite;67 }68 69 .live-dot.active {70 background: #00ff00;71 box-shadow: 0 0 15px #00ff00;72 }73 74 .header-buttons {75 display: flex;76 gap: 10px;77 }78 79 .header-btn {80 background: transparent;81 border: 1px solid #00ff00;82 color: #00ff00;83 padding: 8px 15px;84 font-family: 'Courier New', monospace;85 cursor: pointer;86 font-size: 14px;87 transition: all 0.3s;88 }89 90 .header-btn:hover {91 background: rgba(0, 255, 0, 0.1);92 box-shadow: 0 0 10px #00ff00;93 }94 95 .header-btn.active {96 background: rgba(0, 255, 0, 0.2);97 box-shadow: 0 0 15px #00ff00;98 animation: neonPulse 1.5s infinite alternate;99 }100 101 /* Main Content */102 #main-content {103 display: flex;104 flex: 1;105 overflow: hidden;106 }107 108 /* Terminal */109 #terminal-container {110 flex: 0 0 500px;111 background: rgba(0, 10, 0, 0.95);112 border-right: 2px solid #00ff00;113 display: flex;114 flex-direction: column;115 z-index: 10;116 box-shadow: 5px 0 15px rgba(0, 255, 0, 0.2);117 }118 119 #terminal {120 flex: 1;121 padding: 20px;122 overflow-y: auto;123 font-size: 14px;124 line-height: 1.4;125 }126 127 .terminal-line {128 margin-bottom: 5px;129 white-space: pre-wrap;130 word-break: break-word;131 }132 133 .terminal-line.prompt {134 color: #00ff00;135 }136 137 .terminal-line.output {138 color: #00cc00;139 }140 141 .terminal-line.system {142 color: #00ffff;143 }144 145 .terminal-line.error {146 color: #ff0000;147 }148 149 .terminal-line.warning {150 color: #ffff00;151 }152 153 .terminal-line.success {154 color: #00ff00;155 text-shadow: 0 0 5px #00ff00;156 }157 158 .terminal-input {159 background: rgba(0, 20, 0, 0.8);160 border: 1px solid #00ff00;161 border-left: none;162 border-right: none;163 border-bottom: none;164 padding: 15px 20px;165 color: #00ff00;166 font-family: 'Courier New', monospace;167 font-size: 14px;168 width: 100%;169 outline: none;170 }171 172 .terminal-input:focus {173 background: rgba(0, 30, 0, 0.9);174 box-shadow: inset 0 0 10px rgba(0, 255, 0, 0.3);175 }176 177 /* Visualization */178 #visualization {179 flex: 1;180 position: relative;181 background: #000;182 }183 184 #threeCanvas {185 position: absolute;186 top: 0;187 left: 0;188 width: 100%;189 height: 100%;190 display: block;191 }192 193 /* Stats Panel */194 #stats-panel {195 position: absolute;196 bottom: 20px;197 right: 20px;198 background: rgba(0, 20, 0, 0.9);199 border: 2px solid #00ff00;200 padding: 15px;201 font-size: 12px;202 width: 300px;203 z-index: 5;204 backdrop-filter: blur(5px);205 }206 207 .stat-row {208 display: flex;209 justify-content: space-between;210 margin: 6px 0;211 padding: 3px 0;212 border-bottom: 1px solid rgba(0, 255, 0, 0.1);213 }214 215 .stat-label {216 color: #00cc00;217 }218 219 .stat-value {220 color: #00ff00;221 font-weight: bold;222 }223 224 /* Training Panel */225 #training-panel {226 position: absolute;227 top: 20px;228 right: 20px;229 background: rgba(0, 20, 0, 0.9);230 border: 2px solid #00ff00;231 padding: 15px;232 font-size: 12px;233 width: 350px;234 z-index: 5;235 backdrop-filter: blur(5px);236 }237 238 .training-progress {239 width: 100%;240 height: 10px;241 background: rgba(0, 0, 0, 0.5);242 border: 1px solid #00ff00;243 margin: 10px 0;244 overflow: hidden;245 }246 247 .training-progress-fill {248 height: 100%;249 background: linear-gradient(90deg, #00ff00, #00cc00);250 width: 0%;251 transition: width 0.5s ease-out;252 }253 254 /* Animations */255 @keyframes pulse {256 0%, 100% { opacity: 1; }257 50% { opacity: 0.5; }258 }259 260 @keyframes neonPulse {261 0% { box-shadow: 0 0 10px #00ff00; }262 100% { box-shadow: 0 0 20px #00ff00, 0 0 30px #00ff00; }263 }264 265 @keyframes blink {266 0%, 100% { opacity: 1; }267 50% { opacity: 0; }268 }269 270 .cursor {271 animation: blink 1s infinite;272 }273 274 /* Scrollbar */275 #terminal::-webkit-scrollbar {276 width: 10px;277 }278 279 #terminal::-webkit-scrollbar-track {280 background: rgba(0, 20, 0, 0.5);281 }282 283 #terminal::-webkit-scrollbar-thumb {284 background: #00ff00;285 border-radius: 5px;286 }287 288 /* Model Status */289 .model-status {290 display: inline-block;291 padding: 2px 8px;292 border-radius: 3px;293 font-size: 11px;294 margin-left: 5px;295 }296 297 .status-training {298 background: rgba(255, 255, 0, 0.2);299 color: #ffff00;300 }301 302 .status-ready {303 background: rgba(0, 255, 0, 0.2);304 color: #00ff00;305 }306 </style>307</head>308<body>309 <!-- Header -->310 <div id="header">311 <div class="logo">IONICSPHERE v7.0</div>312 313 <div class="status-indicator">314 <div class="live-dot" id="liveDot"></div>315 <span id="statusText">INITIALIZING</span>316 </div>317 318 <div class="header-buttons">319 <button class="header-btn" onclick="runSimulation()" id="runBtn">▶ RUN SIM</button>320 <button class="header-btn" onclick="toggleTraining()" id="trainBtn">🧠 TRAIN</button>321 <button class="header-btn" onclick="exportEverything()">📦 EXPORT ALL</button>322 </div>323 </div>324 325 <!-- Main Content -->326 <div id="main-content">327 <!-- Terminal -->328 <div id="terminal-container">329 <div id="terminal">330 <div class="terminal-line system">========================================</div>331 <div class="terminal-line system"> REAL-TIME IONIC SIMULATOR v7.0</div>332 <div class="terminal-line system"> TensorFlow.js + Three.js Integration</div>333 <div class="terminal-line system">========================================</div>334 <div class="terminal-line output">Initializing quantum simulation matrix...</div>335 <div class="terminal-line output">Loading TensorFlow.js neural kernel...</div>336 <div class="terminal-line output">Generating 10,240 synthetic ions...</div>337 <div class="terminal-line output">Type 'help' for available commands</div>338 <div class="terminal-line prompt">$ <span id="currentLine"></span><span class="cursor">█</span></div>339 </div>340 <input type="text" id="commandInput" class="terminal-input" placeholder="Type command (help, train, export, clear, status, reset)...">341 </div>342 343 <!-- Visualization -->344 <div id="visualization">345 <canvas id="threeCanvas"></canvas>346 347 <!-- Training Panel -->348 <div id="training-panel">349 <div class="stat-row">350 <span class="stat-label">NEURAL TRAINING:</span>351 <span class="stat-value" id="trainingStatus">IDLE</span>352 </div>353 <div class="stat-row">354 <span class="stat-label">EPOCH:</span>355 <span class="stat-value" id="epochDisplay">0</span>356 </div>357 <div class="stat-row">358 <span class="stat-label">LOSS:</span>359 <span class="stat-value" id="lossDisplay">0.0000</span>360 </div>361 <div class="stat-row">362 <span class="stat-label">ACCURACY:</span>363 <span class="stat-value" id="accuracyDisplay">0.0%</span>364 </div>365 <div class="training-progress">366 <div id="trainingProgress" class="training-progress-fill"></div>367 </div>368 <div class="stat-row">369 <span class="stat-label">BATCH SIZE:</span>370 <span class="stat-value" id="batchDisplay">32</span>371 </div>372 </div>373 374 <!-- Stats Panel -->375 <div id="stats-panel">376 <div class="stat-row">377 <span class="stat-label">SIMULATION:</span>378 <span class="stat-value" id="simStatus">PAUSED</span>379 </div>380 <div class="stat-row">381 <span class="stat-label">FPS:</span>382 <span class="stat-value" id="fpsCounter">0</span>383 </div>384 <div class="stat-row">385 <span class="stat-label">IONS:</span>386 <span class="stat-value" id="ionCount">10,240</span>387 </div>388 <div class="stat-row">389 <span class="stat-label">SIM TIME:</span>390 <span class="stat-value" id="simTime">0.0s</span>391 </div>392 <div class="stat-row">393 <span class="stat-label">CAPTURED DATA:</span>394 <span class="stat-value" id="dataCount">0</span>395 </div>396 <div class="stat-row">397 <span class="stat-label">GPU ACCEL:</span>398 <span class="stat-value" id="gpuStatus">ACTIVE</span>399 </div>400 </div>401 </div>402 </div>403 404 <script>405 // ==================== GLOBAL STATE ====================406 let simulationRunning = false;407 let trainingActive = false;408 let animationId = null;409 let trainingAnimationId = null;410 let simulationTime = 0;411 let lastFrameTime = performance.now();412 let frameCount = 0;413 let fps = 0;414 let epochCount = 0;415 let trainingLoss = 0;416 let trainingAccuracy = 0;417 let currentBatch = 0;418 419 // Real-time data collection420 let capturedData = {421 positions: [],422 velocities: [],423 trainingLog: [],424 frames: [],425 modelStates: [],426 timestamps: []427 };428 429 // TensorFlow.js Model430 let tfModel = null;431 let trainingData = [];432 let validationData = [];433 434 // Three.js components435 let scene, camera, renderer, controls, particles, ocean;436 let particleCount = 10240;437 438 // Command history439 let commandHistory = [];440 let historyIndex = -1;441 442 // GPU.js kernel for physics443 let gpu = new GPU();444 let physicsKernel = null;445 446 // ==================== TENSORFLOW.JS MODEL ====================447 async function createNeuralModel() {448 printLine('[TENSORFLOW] Creating neural network...', 'system');449 450 try {451 // Create a model for predicting ion stability452 tfModel = tf.sequential();453 454 // Input: 5 features (position xyz + velocity xy)455 tfModel.add(tf.layers.dense({456 units: 32,457 inputShape: [5],458 activation: 'relu',459 kernelInitializer: 'heNormal'460 }));461 462 tfModel.add(tf.layers.dropout({rate: 0.2}));463 464 tfModel.add(tf.layers.dense({465 units: 16,466 activation: 'relu'467 }));468 469 tfModel.add(tf.layers.dense({470 units: 8,471 activation: 'relu'472 }));473 474 // Output: stability prediction (0-1)475 tfModel.add(tf.layers.dense({476 units: 1,477 activation: 'sigmoid'478 }));479 480 // Compile model481 tfModel.compile({482 optimizer: tf.train.adam(0.001),483 loss: 'binaryCrossentropy',484 metrics: ['accuracy']485 });486 487 printLine('[TENSORFLOW] Model created successfully', 'success');488 printLine('[TENSORFLOW] Architecture: 5→32→16→8→1', 'output');489 printLine('[TENSORFLOW] Optimizer: Adam (0.001)', 'output');490 491 return true;492 } catch (error) {493 printLine(`[TENSORFLOW] Error: ${error.message}`, 'error');494 return false;495 }496 }497 498 async function generateTrainingData() {499 printLine('[DATA] Generating synthetic training data...', 'system');500 501 trainingData = [];502 validationData = [];503 504 // Generate 1000 synthetic samples505 for (let i = 0; i < 1000; i++) {506 const features = [507 Math.random(), // position x508 Math.random(), // position y509 Math.random(), // position z510 (Math.random() - 0.5) * 2, // velocity x511 (Math.random() - 0.5) * 2 // velocity y512 ];513 514 // Label: 1 if stable (based on position and velocity), 0 if unstable515 const stability = (features[1] > 0.3 && Math.abs(features[3]) < 0.5) ? 1 : 0;516 517 if (i < 800) {518 trainingData.push({features, label: stability});519 } else {520 validationData.push({features, label: stability});521 }522 }523 524 printLine(`[DATA] Generated ${trainingData.length} training samples`, 'success');525 printLine(`[DATA] Generated ${validationData.length} validation samples`, 'success');526 }527 528 async function trainModelStep() {529 if (!tfModel || !trainingActive || trainingData.length === 0) return;530 531 try {532 // Prepare batch data533 const batchSize = 32;534 const batchStart = currentBatch * batchSize;535 const batchEnd = Math.min(batchStart + batchSize, trainingData.length);536 537 if (batchStart >= trainingData.length) {538 currentBatch = 0;539 epochCount++;540 printLine(`[TRAINING] Epoch ${epochCount} completed`, 'system');541 updateTrainingUI();542 return;543 }544 545 const batchData = trainingData.slice(batchStart, batchEnd);546 547 // Convert to tensors548 const features = batchData.map(d => d.features);549 const labels = batchData.map(d => d.label);550 551 const xs = tf.tensor2d(features);552 const ys = tf.tensor2d(labels, [labels.length, 1]);553 554 // Train for one step555 const history = await tfModel.fit(xs, ys, {556 batchSize: batchSize,557 epochs: 1,558 shuffle: true,559 verbose: 0560 });561 562 // Update metrics563 const loss = history.history.loss[0];564 const accuracy = history.history.acc ? history.history.acc[0] : 0;565 566 trainingLoss = loss;567 trainingAccuracy = accuracy;568 569 // Store training log570 capturedData.trainingLog.push({571 epoch: epochCount,572 batch: currentBatch,573 loss: loss,574 accuracy: accuracy,575 timestamp: Date.now()576 });577 578 // Update UI579 updateTrainingUI();580 581 // Cleanup582 xs.dispose();583 ys.dispose();584 585 currentBatch++;586 587 } catch (error) {588 printLine(`[TRAINING] Error: ${error.message}`, 'error');589 }590 }591 592 function updateTrainingUI() {593 document.getElementById('trainingStatus').textContent = trainingActive ? 'TRAINING' : 'IDLE';594 document.getElementById('epochDisplay').textContent = epochCount;595 document.getElementById('lossDisplay').textContent = trainingLoss.toFixed(4);596 document.getElementById('accuracyDisplay').textContent = (trainingAccuracy * 100).toFixed(1) + '%';597 document.getElementById('batchDisplay').textContent = currentBatch;598 599 const progress = ((currentBatch * 32) / trainingData.length) * 100;600 document.getElementById('trainingProgress').style.width = progress + '%';601 }602 603 // ==================== REAL-TIME DATA CAPTURE ====================604 function captureFrameData() {605 if (!particles || !simulationRunning) return;606 607 const positions = particles.geometry.attributes.position.array;608 const velocities = particles.userData.velocities;609 610 // Capture every 60 frames (~1 second at 60fps)611 if (frameCount % 60 === 0) {612 capturedData.positions.push(Float32Array.from(positions));613 capturedData.velocities.push(Float32Array.from(velocities));614 capturedData.timestamps.push(Date.now());615 capturedData.modelStates.push({616 epoch: epochCount,617 loss: trainingLoss,618 accuracy: trainingAccuracy619 });620 621 document.getElementById('dataCount').textContent = capturedData.positions.length;622 623 if (capturedData.positions.length % 10 === 0) {624 printLine(`[CAPTURE] Stored ${capturedData.positions.length} data frames`, 'system');625 }626 }627 }628 629 function captureThreeJSFrame() {630 if (!renderer) return;631 632 const canvas = document.getElementById('threeCanvas');633 const dataURL = canvas.toDataURL('image/png');634 635 capturedData.frames.push({636 timestamp: Date.now(),637 epoch: epochCount,638 dataURL: dataURL,639 metrics: {640 loss: trainingLoss,641 accuracy: trainingAccuracy,642 fps: fps643 }644 });645 646 printLine(`[CAPTURE] Screenshot captured (epoch ${epochCount})`, 'system');647 }648 649 // ==================== THREE.JS SIMULATION ====================650 async function initThreeJS() {651 printLine('[THREE.JS] Initializing 3D visualization...', 'system');652 653 try {654 // Scene655 scene = new THREE.Scene();656 scene.background = new THREE.Color(0x000022);657 658 // Camera659 camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);660 camera.position.set(0, 50, 100);661 662 // Renderer663 const canvas = document.getElementById('threeCanvas');664 renderer = new THREE.WebGLRenderer({ 665 canvas, 666 antialias: true,667 powerPreference: "high-performance"668 });669 renderer.setSize(canvas.clientWidth, canvas.clientHeight);670 renderer.setPixelRatio(window.devicePixelRatio);671 672 // Controls673 controls = new THREE.OrbitControls(camera, renderer.domElement);674 controls.enableDamping = true;675 controls.dampingFactor = 0.05;676 677 // Lighting678 const ambientLight = new THREE.AmbientLight(0x0044aa, 0.5);679 scene.add(ambientLight);680 681 const directionalLight = new THREE.DirectionalLight(0x00ffff, 0.8);682 directionalLight.position.set(10, 20, 15);683 scene.add(directionalLight);684 685 // Create ocean686 createOcean();687 688 // Create particles689 createIons();690 691 // Initialize GPU.js kernel for physics692 initPhysicsKernel();693 694 printLine('[THREE.JS] Visualization ready', 'success');695 return true;696 697 } catch (error) {698 printLine(`[THREE.JS] Error: ${error.message}`, 'error');699 return false;700 }701 }702 703 function createOcean() {704 const geometry = new THREE.PlaneGeometry(200, 200, 64, 64);705 const material = new THREE.MeshPhongMaterial({706 color: 0x0066ff,707 transparent: true,708 opacity: 0.7,709 wireframe: false710 });711 712 ocean = new THREE.Mesh(geometry, material);713 ocean.rotation.x = -Math.PI / 2;714 scene.add(ocean);715 }716 717 function createIons() {718 const geometry = new THREE.BufferGeometry();719 const positions = new Float32Array(particleCount * 3);720 const colors = new Float32Array(particleCount * 3);721 722 for (let i = 0; i < particleCount; i++) {723 const i3 = i * 3;724 725 // Distribute in a sphere726 const radius = 50 + Math.random() * 30;727 const theta = Math.random() * Math.PI * 2;728 const phi = Math.acos(2 * Math.random() - 1);729 730 positions[i3] = radius * Math.sin(phi) * Math.cos(theta);731 positions[i3 + 1] = radius * Math.sin(phi) * Math.sin(theta);732 positions[i3 + 2] = radius * Math.cos(phi);733 734 // Color coding based on position735 colors[i3] = 0.2 + positions[i3] / 100;736 colors[i3 + 1] = 0.4 + positions[i3 + 1] / 100;737 colors[i3 + 2] = 0.8 + positions[i3 + 2] / 100;738 }739 740 geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));741 geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));742 743 const material = new THREE.PointsMaterial({744 size: 2.0,745 vertexColors: true,746 transparent: true,747 opacity: 0.8,748 blending: THREE.AdditiveBlending749 });750 751 particles = new THREE.Points(geometry, material);752 scene.add(particles);753 754 // Store velocities755 particles.userData.velocities = new Float32Array(particleCount * 3);756 particles.userData.originalPositions = positions.slice();757 758 for (let i = 0; i < particleCount * 3; i++) {759 particles.userData.velocities[i] = (Math.random() - 0.5) * 0.2;760 }761 762 printLine(`[IONS] Created ${particleCount.toLocaleString()} particles`, 'success');763 }764 765 function initPhysicsKernel() {766 try {767 physicsKernel = gpu.createKernel(function(positions, velocities, time) {768 const i = this.thread.x * 3;769 770 // Brownian motion with time-based variation771 const noise = Math.sin(time + positions[i]) * 0.05;772 773 return [774 positions[i] + velocities[i] + noise,775 positions[i + 1] + velocities[i + 1] + noise,776 positions[i + 2] + velocities[i + 2] + noise777 ];778 }).setOutput([particleCount]);779 780 printLine('[GPU.JS] Physics kernel initialized', 'success');781 } catch (error) {782 printLine('[GPU.JS] Using CPU fallback for physics', 'warning');783 physicsKernel = null;784 }785 }786 787 function updateSimulation(deltaTime) {788 if (!simulationRunning || !particles || !ocean) return;789 790 simulationTime += deltaTime;791 792 // Update FPS counter793 frameCount++;794 const currentTime = performance.now();795 if (currentTime - lastFrameTime >= 1000) {796 fps = Math.round((frameCount * 1000) / (currentTime - lastFrameTime));797 frameCount = 0;798 lastFrameTime = currentTime;799 800 document.getElementById('fpsCounter').textContent = fps;801 document.getElementById('simTime').textContent = simulationTime.toFixed(1) + 's';802 }803 804 // Update ocean waves805 updateOcean(deltaTime);806 807 // Update ions using GPU.js if available808 updateIons(deltaTime);809 810 // Capture real-time data811 captureFrameData();812 813 // Update controls814 controls.update();815 }816 817 function updateOcean(deltaTime) {818 const positionAttribute = ocean.geometry.attributes.position;819 const time = simulationTime;820 821 for (let i = 0; i < positionAttribute.count; i++) {822 const i3 = i * 3;823 const x = positionAttribute.array[i3];824 const z = positionAttribute.array[i3 + 2];825 826 const wave = Math.sin(x * 0.05 + time) * 2 +827 Math.cos(z * 0.03 + time * 0.7) * 1.5;828 829 positionAttribute.array[i3 + 1] = wave;830 }831 832 positionAttribute.needsUpdate = true;833 }834 835 function updateIons(deltaTime) {836 const positions = particles.geometry.attributes.position.array;837 const velocities = particles.userData.velocities;838 839 if (physicsKernel) {840 // Use GPU.js for physics841 try {842 const result = physicsKernel(positions, velocities, simulationTime);843 844 for (let i = 0; i < particleCount; i++) {845 const i3 = i * 3;846 const newPos = result[i];847 848 positions[i3] = newPos[0];849 positions[i3 + 1] = newPos[1];850 positions[i3 + 2] = newPos[2];851 852 // Add restoring force toward center853 const dx = positions[i3];854 const dy = positions[i3 + 1];855 const dz = positions[i3 + 2];856 const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);857 858 if (distance > 80) {859 const force = 0.01;860 velocities[i3] -= dx * force;861 velocities[i3 + 1] -= dy * force;862 velocities[i3 + 2] -= dz * force;863 }864 }865 } catch (error) {866 // Fallback to CPU867 updateIonsCPU(deltaTime);868 }869 } else {870 updateIonsCPU(deltaTime);871 }872 873 particles.geometry.attributes.position.needsUpdate = true;874 }875 876 function updateIonsCPU(deltaTime) {877 const positions = particles.geometry.attributes.position.array;878 const velocities = particles.userData.velocities;879 880 for (let i = 0; i < particleCount; i++) {881 const i3 = i * 3;882 883 // Brownian motion884 velocities[i3] += (Math.random() - 0.5) * 0.1 * deltaTime;885 velocities[i3 + 1] += (Math.random() - 0.5) * 0.1 * deltaTime;886 velocities[i3 + 2] += (Math.random() - 0.5) * 0.1 * deltaTime;887 888 // Damping889 velocities[i3] *= 0.99;890 velocities[i3 + 1] *= 0.99;891 velocities[i3 + 2] *= 0.99;892 893 // Update positions894 positions[i3] += velocities[i3] * deltaTime * 30;895 positions[i3 + 1] += velocities[i3 + 1] * deltaTime * 30;896 positions[i3 + 2] += velocities[i3 + 2] * deltaTime * 30;897 898 // Keep within bounds899 const radius = Math.sqrt(900 positions[i3] * positions[i3] +901 positions[i3 + 1] * positions[i3 + 1] +902 positions[i3 + 2] * positions[i3 + 2]903 );904 905 if (radius > 80) {906 velocities[i3] *= -0.5;907 velocities[i3 + 1] *= -0.5;908 velocities[i3 + 2] *= -0.5;909 }910 }911 }912 913 // ==================== ANIMATION LOOP ====================914 function animationLoop() {915 const currentTime = performance.now();916 const deltaTime = (currentTime - (scene.userData.lastTime || currentTime)) / 1000;917 scene.userData.lastTime = currentTime;918 919 updateSimulation(deltaTime);920 921 if (trainingActive) {922 trainModelStep();923 }924 925 renderer.render(scene, camera);926 animationId = requestAnimationFrame(animationLoop);927 }928 929 // ==================== COMMAND LINE INTERFACE ====================930 function printLine(text, type = 'output') {931 const line = document.createElement('div');932 line.className = `terminal-line ${type}`;933 line.textContent = text;934 document.getElementById('terminal').appendChild(line);935 scrollTerminal();936 }937 938 function printPrompt() {939 const prompt = document.createElement('div');940 prompt.className = 'terminal-line prompt';941 prompt.innerHTML = '$ <span id="currentLine"></span><span class="cursor">█</span>';942 document.getElementById('terminal').appendChild(prompt);943 scrollTerminal();944 }945 946 function scrollTerminal() {947 const terminal = document.getElementById('terminal');948 terminal.scrollTop = terminal.scrollHeight;949 }950 951 function clearTerminal() {952 document.getElementById('terminal').innerHTML = '';953 printLine('[SYSTEM] Terminal cleared', 'system');954 printPrompt();955 }956 957 function showHelp() {958 printLine('Available commands:', 'system');959 printLine(' help - Show this help message');960 printLine(' run - Start simulation');961 printLine(' pause - Pause simulation');962 printLine(' train [epochs]- Toggle/start training (optional epochs)');963 printLine(' stop - Stop training');964 printLine(' capture - Capture screenshot');965 printLine(' status - Show system status');966 printLine(' export - Export all data as ZIP');967 printLine(' clear - Clear terminal');968 printLine(' reset - Reset simulation');969 }970 971 function handleCommand(command) {972 const parts = command.trim().split(' ');973 const cmd = parts[0].toLowerCase();974 const args = parts.slice(1);975 976 switch(cmd) {977 case 'help':978 showHelp();979 break;980 981 case 'run':982 runSimulation();983 break;984 985 case 'pause':986 pauseSimulation();987 break;988 989 case 'train':990 if (args[0]) {991 printLine(`[TRAINING] Training for ${args[0]} epochs...`, 'system');992 }993 toggleTraining();994 break;995 996 case 'stop':997 toggleTraining(false);998 break;999 1000 case 'capture':1001 captureThreeJSFrame();1002 break;1003 1004 case 'status':1005 showStatus();1006 break;1007 1008 case 'export':1009 exportEverything();1010 break;1011 1012 case 'clear':1013 clearTerminal();1014 break;1015 1016 case 'reset':1017 resetSimulation();1018 break;1019 1020 case 'model':1021 printLine(`[MODEL] Architecture: 5→32→16→8→1`, 'system');1022 printLine(`[MODEL] Epochs: ${epochCount}`, 'output');1023 printLine(`[MODEL] Loss: ${trainingLoss.toFixed(4)}`, 'output');1024 printLine(`[MODEL] Accuracy: ${(trainingAccuracy * 100).toFixed(1)}%`, 'output');1025 break;1026 1027 case 'data':1028 printLine(`[DATA] Captured frames: ${capturedData.positions.length}`, 'system');1029 printLine(`[DATA] Training samples: ${trainingData.length}`, 'output');1030 printLine(`[DATA] Validation samples: ${validationData.length}`, 'output');1031 break;1032 1033 case '':1034 // Empty command1035 break;1036 1037 default:1038 printLine(`Command not found: ${cmd}. Type 'help' for available commands.`, 'error');1039 break;1040 }1041 }1042 1043 function showStatus() {1044 printLine('=== SYSTEM STATUS ===', 'system');1045 printLine(`Simulation: ${simulationRunning ? 'RUNNING' : 'PAUSED'}`);1046 printLine(`Training: ${trainingActive ? 'ACTIVE' : 'INACTIVE'}`);1047 printLine(`Epochs: ${epochCount}`);1048 printLine(`Loss: ${trainingLoss.toFixed(4)}`);1049 printLine(`Accuracy: ${(trainingAccuracy * 100).toFixed(1)}%`);1050 printLine(`FPS: ${fps}`);1051 printLine(`Sim Time: ${simulationTime.toFixed(1)}s`);1052 printLine(`Ions: ${particleCount.toLocaleString()}`);1053 printLine(`Captured Data: ${capturedData.positions.length} frames`);1054 }1055 1056 // ==================== SIMULATION CONTROL ====================1057 function runSimulation() {1058 if (!simulationRunning) {1059 simulationRunning = true;1060 document.getElementById('runBtn').classList.add('active');1061 document.getElementById('liveDot').classList.add('active');1062 document.getElementById('statusText').textContent = 'RUNNING';1063 document.getElementById('simStatus').textContent = 'RUNNING';1064 1065 if (!animationId) {1066 scene.userData.lastTime = performance.now();1067 animationId = requestAnimationFrame(animationLoop);1068 }1069 1070 printLine('[SIMULATION] Started real-time quantum simulation', 'success');1071 }1072 }1073 1074 function pauseSimulation() {1075 simulationRunning = false;1076 document.getElementById('runBtn').classList.remove('active');1077 document.getElementById('liveDot').classList.remove('active');1078 document.getElementById('statusText').textContent = 'PAUSED';1079 document.getElementById('simStatus').textContent = 'PAUSED';1080 1081 printLine('[SIMULATION] Paused', 'system');1082 }1083 1084 function toggleTraining(start = true) {1085 if (start && !trainingActive) {1086 trainingActive = true;1087 document.getElementById('trainBtn').classList.add('active');1088 printLine('[TRAINING] Started real-time neural training', 'success');1089 printLine('[TRAINING] Using live particle data as input', 'output');1090 } else if (!start && trainingActive) {1091 trainingActive = false;1092 document.getElementById('trainBtn').classList.remove('active');1093 printLine('[TRAINING] Stopped', 'system');1094 } else {1095 trainingActive = !trainingActive;1096 document.getElementById('trainBtn').classList.toggle('active');1097 printLine(`[TRAINING] ${trainingActive ? 'Started' : 'Stopped'}`, 'system');1098 }1099 1100 updateTrainingUI();1101 }1102 1103 function resetSimulation() {1104 simulationRunning = false;1105 trainingActive = false;1106 simulationTime = 0;1107 epochCount = 0;1108 trainingLoss = 0;1109 trainingAccuracy = 0;1110 currentBatch = 0;1111 1112 document.getElementById('runBtn').classList.remove('active');1113 document.getElementById('trainBtn').classList.remove('active');1114 document.getElementById('liveDot').classList.remove('active');1115 document.getElementById('statusText').textContent = 'STANDBY';1116 document.getElementById('simStatus').textContent = 'STANDBY';1117 1118 // Reset particles1119 if (particles && particles.userData.originalPositions) {1120 const positions = particles.geometry.attributes.position.array;1121 const original = particles.userData.originalPositions;1122 for (let i = 0; i < positions.length; i++) {1123 positions[i] = original[i];1124 }1125 particles.geometry.attributes.position.needsUpdate = true;1126 }1127 1128 capturedData = {1129 positions: [],1130 velocities: [],1131 trainingLog: [],1132 frames: [],1133 modelStates: [],1134 timestamps: []1135 };1136 1137 updateTrainingUI();1138 document.getElementById('dataCount').textContent = '0';1139 1140 printLine('[SYSTEM] Full reset complete', 'system');1141 }1142 1143 // ==================== EXPORT SYSTEM ====================1144 async function exportEverything() {1145 printLine('[EXPORT] Creating unified package...', 'system');1146 1147 try {1148 const zip = new JSZip();1149 1150 // 1. Model metadata1151 const modelMetadata = {1152 name: "IonicQuantumSimulator_v7.0",1153 version: "7.0",1154 export_date: new Date().toISOString(),1155 epochs_trained: epochCount,1156 final_loss: trainingLoss,1157 final_accuracy: trainingAccuracy,1158 particle_count: particleCount,1159 simulation_time: simulationTime,1160 features: ["position_x", "position_y", "position_z", "velocity_x", "velocity_y"],1161 architecture: "5→32→16→8→1",1162 optimizer: "adam",1163 learning_rate: 0.001,1164 batch_size: 321165 };1166 zip.file("model_metadata.json", JSON.stringify(modelMetadata, null, 2));1167 1168 // 2. Training log1169 zip.file("training_log.json", JSON.stringify(capturedData.trainingLog, null, 2));1170 1171 // 3. Captured particle data (compressed)1172 const particleData = {1173 metadata: {1174 frames: capturedData.positions.length,1175 particles_per_frame: particleCount,1176 total_positions: capturedData.positions.length * particleCount * 3,1177 timestamps: capturedData.timestamps1178 },1179 positions: capturedData.positions.map(arr => Array.from(arr)),1180 velocities: capturedData.velocities.map(arr => Array.from(arr)),1181 model_states: capturedData.modelStates1182 };1183 zip.file("particle_data.json", JSON.stringify(particleData, null, 2));1184 1185 // 4. Screenshots1186 if (capturedData.frames.length > 0) {1187 const framesFolder = zip.folder("screenshots");1188 capturedData.frames.forEach((frame, index) => {1189 const base64Data = frame.dataURL.split(',')[1];1190 framesFolder.file(`frame_${index}_epoch_${frame.epoch}.png`, base64Data, {base64: true});1191 });1192 }1193 1194 // 5. TensorFlow.js model weights1195 if (tfModel) {1196 const weights = await tfModel.save(tf.io.withSaveHandler(async (artifacts) => {1197 const weightData = {1198 modelTopology: artifacts.modelTopology,1199 weightSpecs: artifacts.weightSpecs,1200 weightData: Array.from(new Uint8Array(artifacts.weightData))