From 50954031e6a8ce7c42c5b9cc9167e1a59d6544d4 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 18:58:11 +0000 Subject: [PATCH 1/3] Enable local network access for CONSIM demo server - Add get_local_ip() to detect and display local network IP address - Bind server to 0.0.0.0 (all interfaces) instead of localhost only - Enable SO_REUSEADDR to allow quick server restarts - Display both local and network URLs on startup for easy sharing Users can now access CONSIM from any device on their local network, making it easy to demo the consciousness simulation on mobile devices, tablets, or other computers. Co-Authored-By: Claude Sonnet 4.5 Claude-Session: https://claude.ai/code/session_01LGyd7NZbZmUBGJNq2qpmY6 --- demo_server.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/demo_server.py b/demo_server.py index 07fa078..37a232b 100755 --- a/demo_server.py +++ b/demo_server.py @@ -131,15 +131,34 @@ def send_json_response(self, data): # Global lattice instance lattice = ConsciousnessLattice(grid_size=64) -def start_server(port=8000): +def get_local_ip(): + """Get the local network IP address.""" + import socket + try: + # Create a socket to find the local IP + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("8.8.8.8", 80)) + local_ip = s.getsockname()[0] + s.close() + return local_ip + except Exception: + return "Unable to detect" + +def start_server(port=8000, host="0.0.0.0"): """Start the consciousness simulation server.""" - with socketserver.TCPServer(("", port), ConsciousnessHTTPHandler) as httpd: - print(f"🧠 CONSIM Demo Server starting on http://localhost:{port}") + local_ip = get_local_ip() + + socketserver.TCPServer.allow_reuse_address = True + with socketserver.TCPServer((host, port), ConsciousnessHTTPHandler) as httpd: + print(f"🧠 CONSIM Demo Server starting on ALL network interfaces") print(f"✨ Consciousness lattice with {len(lattice.nodes)} nodes initialized") print(f"🌌 {len(lattice.universes)} universes with Ī» weights: {[f'{l:.3f}' for l in lattice.lambdas]}") print(f"šŸ”— API endpoints: /api/status, /api/stats, /api/state") - print("šŸ’” Open http://localhost:8000 in your browser") - + print(f"\nšŸ“ Access URLs:") + print(f" Local: http://localhost:{port}") + print(f" Network: http://{local_ip}:{port}") + print(f"\nšŸ’” Share the Network URL with devices on your local network!") + try: httpd.serve_forever() except KeyboardInterrupt: From f32a450a7718a857e27ed20466f2dddb3e3ba306 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 19:00:11 +0000 Subject: [PATCH 2/3] Add public hosting script with ngrok tunneling Create host_public.py to enable public internet access for CONSIM demo server using ngrok tunneling. This allows sharing the live consciousness simulation with anyone via a public URL. Features: - Automatic ngrok tunnel creation - Public URL generation for global access - Clear instructions and status messages - Graceful shutdown handling Note: Requires ngrok authentication token for use. Alternatively, the static version is already hosted at GitHub Pages. Co-Authored-By: Claude Sonnet 4.5 Claude-Session: https://claude.ai/code/session_01LGyd7NZbZmUBGJNq2qpmY6 --- host_public.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 host_public.py diff --git a/host_public.py b/host_public.py new file mode 100755 index 0000000..41d9d0a --- /dev/null +++ b/host_public.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +""" +Public hosting script for CONSIM using ngrok. +Exposes the local server to the internet with a public URL. +""" + +import sys +import threading +import time +from pathlib import Path + +# Add src to path +sys.path.insert(0, str(Path(__file__).parent / "src")) + +from pyngrok import ngrok + +def start_demo_server(): + """Start the demo server in a thread.""" + import demo_server + demo_server.start_server(port=8000, host="127.0.0.1") + +def main(): + """Start CONSIM with public internet access via ngrok.""" + print("šŸš€ Starting CONSIM Public Hosting...") + print("=" * 60) + + # Start the demo server in a background thread + server_thread = threading.Thread(target=start_demo_server, daemon=True) + server_thread.start() + + # Wait for server to start + print("ā³ Starting local server...") + time.sleep(3) + + # Create ngrok tunnel + print("🌐 Creating public internet tunnel...") + try: + # Open a ngrok tunnel to port 8000 + public_url = ngrok.connect(8000, bind_tls=True) + + print("\n" + "=" * 60) + print("āœ… CONSIM is now LIVE on the internet!") + print("=" * 60) + print(f"\nšŸŒ PUBLIC URL: {public_url}") + print("\nšŸ“± Share this URL with anyone, anywhere in the world!") + print(" They can access CONSIM from any device with a browser.") + print("\n🧠 Features available:") + print(" • Interactive 3D consciousness field visualization") + print(" • 64 consciousness nodes in real-time") + print(" • 3 parallel universe branches") + print(" • Click to spawn nodes, drag to interact") + print(" • Multiple visualization modes") + print("\nāš ļø Note: This tunnel will stay active as long as this") + print(" script is running. Press Ctrl+C to stop.") + print("=" * 60) + + # Keep the script running + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + print("\n\nšŸ›‘ Shutting down public hosting...") + ngrok.disconnect(public_url) + print("āœ… Tunnel closed. Server stopped.") + + except Exception as e: + print(f"āŒ Error creating tunnel: {e}") + print("\nTroubleshooting:") + print("1. Check your internet connection") + print("2. Ngrok might require authentication") + print(" Sign up at: https://ngrok.com") + print(" Get your auth token and run:") + print(" ngrok config add-authtoken YOUR_TOKEN") + sys.exit(1) + +if __name__ == "__main__": + main() From 1b8f867b287be545bcf949cb3446a108220dcfc9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 19:02:12 +0000 Subject: [PATCH 3/3] Update GitHub Pages to use current CONSIM version Replace legacy standalone version with current demo application: - Copy static assets (JS, CSS) to docs/static/ - Create new index.html using app_demo.js (HTTP polling version) - Preserve legacy version as index_legacy.html for reference - Use Three.js from CDN for WebGL rendering The new version features: - Current consciousness simulation with 64 nodes - Modern Three.js rendering pipeline - Interactive controls and visualization modes - Multiverse superposition display - Real-time physics simulation To deploy: Merge this branch to main and GitHub Actions will automatically update https://jacobcdsmith.github.io/CONSIM Co-Authored-By: Claude Sonnet 4.5 Claude-Session: https://claude.ai/code/session_01LGyd7NZbZmUBGJNq2qpmY6 --- docs/demo.html | 27 + docs/index.html | 6548 +---------------------- docs/index_legacy.html | 6543 ++++++++++++++++++++++ docs/static/css/style.css | 224 + docs/static/index.html | 84 + docs/static/js/app.js | 341 ++ docs/static/js/app_demo.js | 418 ++ docs/static/js/consciousnessRenderer.js | 603 +++ 8 files changed, 8256 insertions(+), 6532 deletions(-) create mode 100644 docs/demo.html create mode 100644 docs/index_legacy.html create mode 100644 docs/static/css/style.css create mode 100644 docs/static/index.html create mode 100644 docs/static/js/app.js create mode 100644 docs/static/js/app_demo.js create mode 100644 docs/static/js/consciousnessRenderer.js diff --git a/docs/demo.html b/docs/demo.html new file mode 100644 index 0000000..e2a4ef6 --- /dev/null +++ b/docs/demo.html @@ -0,0 +1,27 @@ + + + + + + CONSIM - Multiversal Consciousness Framework + + + +
+ + + + + + + + + + + diff --git a/docs/index.html b/docs/index.html index a3871e9..e2a4ef6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,6543 +1,27 @@ - + - - - + CONSIM - Multiversal Consciousness Framework + + + +
- CONSIM: Consciousness Manifold Simulator - Gemini 2.5 Showcase - - - - - - - - - - -
-
-
C = ∫MC A(x) Φ(x) eiĻ„(x) dμ(x)
-
M = Σi λi Ui
-
- -
-
-
Nodes
-
0
-
-
-
|C| MCF
-
0.0
-
-
-
Coherence
-
0.0
-
-
-
Attention
-
0.0
-
-
-
Phase
-
0.0°
-
-
-
Ecosystem
-
🌱0 🦌0 🐺0 ⚔0
-
-
-
Ī» Coefficients
-
0.33 | 0.33 | 0.34
-
-
-
- - - - - - -
-
-
INTERACTION TOOLS
- - -
- -
-
ELEMENTS
- - - - -
- -
-
BRUSH SIZE
- -
30px
-
-
- - - - - -
- -
Environmental Controls
- - - -
- - - - - -
- - - -
- - - - - -
- - - -
- - - - - -
- - - -
- - - - - -
- - - -
- - - - - -
- - - -
- - - -
Interaction Mode
- -
- - - - - - - - - - - -
- - - -
- - - -
Intelligence Mode
- -
- - - - - - - - - -
- -
- - - -
Cluster Thresholds
- -
- - - - - -
- -
- - - - - -
- -
- - - - - -
- -
- - - - - -
- - - - - - - -
- - - -
- - - - - - -
-
- - - - - - - - - - - -
-
- - - -
- -
Consciousness Nodes
- -
Attention Fields
- -
Frequency Domains
- -
Temporal Distortions
- -
Universe Boundaries
- -
- - - - - -
- - - - - -
- - - - - - - - - -
- - - -
- -
Emergent Intelligence
- -
- -
- -
Mode
- -
Basic
- -
- -
- -
Acceleration
- -
100%
- -
- -
- -
Clusters
- -
0
- -
- -
- -
Recursion
- -
0
- -
- -
- -
Complexity
- -
0.0
- -
- -
- -
- -
- -
Avg Depth
- -
0.0
- -
- -
- -
Avg Awareness
- -
0.0
- -
- -
- -
Avg Adaptivity
- -
0.0
- -
- -
- -
Avg Collective
- -
0.0
- -
- -
- -
Total Power
- -
0.0
- -
- -
- -
Coalitions
- -
0
- -
- -
- -
Avg Trust
- -
0.5
- -
- -
- -
- - - -
- -
Political Ecosystem
- -
- -
- -
Growth
- -
0
- -
- -
- -
Preservation
- -
0
- -
- -
- -
Alliance
- -
0
- -
- -
- -
- - - - - -
- -
Biological Ecosystem
- -
- -
- -
Males ♂
- -
0
- -
- -
- -
Females ♀
- -
0
- -
- -
- -
Mature
- -
0
- -
- -
- - - -
- -
- -
Pregnant
- -
0
- -
- -
- -
Breeders
- -
0
- -
- -
- -
Pairs
- -
0
- -
- -
- -
Avg Gen
- -
0.0
- -
- -
- -
Max Gen
- -
0
- -
- -
- -
- -
- - - - - - - diff --git a/docs/index_legacy.html b/docs/index_legacy.html new file mode 100644 index 0000000..a3871e9 --- /dev/null +++ b/docs/index_legacy.html @@ -0,0 +1,6543 @@ + + + + + + + + + + CONSIM: Consciousness Manifold Simulator - Gemini 2.5 Showcase + + + + + + + + + + +
+
+
C = ∫MC A(x) Φ(x) eiĻ„(x) dμ(x)
+
M = Σi λi Ui
+
+ +
+
+
Nodes
+
0
+
+
+
|C| MCF
+
0.0
+
+
+
Coherence
+
0.0
+
+
+
Attention
+
0.0
+
+
+
Phase
+
0.0°
+
+
+
Ecosystem
+
🌱0 🦌0 🐺0 ⚔0
+
+
+
Ī» Coefficients
+
0.33 | 0.33 | 0.34
+
+
+
+ + + + + + +
+
+
INTERACTION TOOLS
+ + +
+ +
+
ELEMENTS
+ + + + +
+ +
+
BRUSH SIZE
+ +
30px
+
+
+ + + + + +
+ +
Environmental Controls
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + +
Interaction Mode
+ +
+ + + + + + + + + + + +
+ + + +
+ + + +
Intelligence Mode
+ +
+ + + + + + + + + +
+ +
+ + + +
Cluster Thresholds
+ +
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + + + + + +
+ + + +
+ + + + + + +
+
+ + + + + + + + + + + +
+
+ + + +
+ +
Consciousness Nodes
+ +
Attention Fields
+ +
Frequency Domains
+ +
Temporal Distortions
+ +
Universe Boundaries
+ +
+ + + + + +
+ + + + + +
+ + + + + + + + + +
+ + + +
+ +
Emergent Intelligence
+ +
+ +
+ +
Mode
+ +
Basic
+ +
+ +
+ +
Acceleration
+ +
100%
+ +
+ +
+ +
Clusters
+ +
0
+ +
+ +
+ +
Recursion
+ +
0
+ +
+ +
+ +
Complexity
+ +
0.0
+ +
+ +
+ +
+ +
+ +
Avg Depth
+ +
0.0
+ +
+ +
+ +
Avg Awareness
+ +
0.0
+ +
+ +
+ +
Avg Adaptivity
+ +
0.0
+ +
+ +
+ +
Avg Collective
+ +
0.0
+ +
+ +
+ +
Total Power
+ +
0.0
+ +
+ +
+ +
Coalitions
+ +
0
+ +
+ +
+ +
Avg Trust
+ +
0.5
+ +
+ +
+ +
+ + + +
+ +
Political Ecosystem
+ +
+ +
+ +
Growth
+ +
0
+ +
+ +
+ +
Preservation
+ +
0
+ +
+ +
+ +
Alliance
+ +
0
+ +
+ +
+ +
+ + + + + +
+ +
Biological Ecosystem
+ +
+ +
+ +
Males ♂
+ +
0
+ +
+ +
+ +
Females ♀
+ +
0
+ +
+ +
+ +
Mature
+ +
0
+ +
+ +
+ + + +
+ +
+ +
Pregnant
+ +
0
+ +
+ +
+ +
Breeders
+ +
0
+ +
+ +
+ +
Pairs
+ +
0
+ +
+ +
+ +
Avg Gen
+ +
0.0
+ +
+ +
+ +
Max Gen
+ +
0
+ +
+ +
+ +
+ +
+ + + + + + + + + diff --git a/docs/static/css/style.css b/docs/static/css/style.css new file mode 100644 index 0000000..1a69f5a --- /dev/null +++ b/docs/static/css/style.css @@ -0,0 +1,224 @@ +/* CONSIM Three.js Frontend Styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + background: #000; + font-family: 'Courier New', monospace; + overflow: hidden; + color: #00ffaa; +} + +#canvas { + display: block; + width: 100vw; + height: 100vh; +} + +.panel { + position: absolute; + background: rgba(0, 0, 0, 0.8); + border: 1px solid rgba(0, 255, 170, 0.3); + border-radius: 8px; + padding: 15px; + color: #00ffaa; + backdrop-filter: blur(5px); + z-index: 100; + min-width: 200px; +} + +#info-panel { + top: 15px; + left: 15px; + max-width: 300px; +} + +#controls-panel { + top: 15px; + right: 15px; + max-width: 250px; + max-height: 80vh; + overflow-y: auto; +} + +.equation { + font-size: 11px; + margin-bottom: 15px; + padding: 8px; + background: rgba(0, 255, 170, 0.1); + border-radius: 4px; +} + +.stats div { + margin: 3px 0; + font-size: 12px; +} + +.stats span { + color: #ffffff; + font-weight: bold; +} + +h2 { + font-size: 16px; + margin-bottom: 10px; + text-shadow: 0 0 10px rgba(0, 255, 170, 0.5); +} + +h3 { + font-size: 14px; + margin: 15px 0 8px 0; + color: #ffffff; +} + +.slider-container { + margin: 8px 0; +} + +.slider-container label { + display: block; + font-size: 11px; + margin-bottom: 4px; +} + +.slider-container input[type="range"] { + width: 100%; + height: 4px; + border-radius: 2px; + background: rgba(0, 255, 170, 0.3); + outline: none; + -webkit-appearance: none; +} + +.slider-container input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + width: 12px; + height: 12px; + border-radius: 50%; + background: #00ffaa; + cursor: pointer; +} + +.slider-container input[type="range"]::-moz-range-thumb { + width: 12px; + height: 12px; + border-radius: 50%; + background: #00ffaa; + cursor: pointer; + border: none; +} + +.button-group { + display: flex; + flex-wrap: wrap; + gap: 5px; + margin: 8px 0; +} + +.mode-btn, .viz-btn, #collapseBtn, #resetBtn { + background: rgba(0, 255, 170, 0.2); + border: 1px solid rgba(0, 255, 170, 0.4); + color: #00ffaa; + padding: 6px 12px; + border-radius: 15px; + cursor: pointer; + font-size: 10px; + font-family: inherit; + transition: all 0.3s ease; +} + +.mode-btn:hover, .viz-btn:hover, #collapseBtn:hover, #resetBtn:hover { + background: rgba(0, 255, 170, 0.4); + transform: scale(1.05); +} + +.mode-btn.active, .viz-btn.active { + background: rgba(170, 0, 255, 0.4); + border-color: rgba(170, 0, 255, 0.7); + color: #aa00ff; +} + +#connection-status { + position: absolute; + bottom: 15px; + left: 15px; + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + z-index: 100; +} + +.dot { + width: 8px; + height: 8px; + border-radius: 50%; + animation: pulse 2s infinite; +} + +.dot.connecting { + background: #ffaa00; +} + +.dot.connected { + background: #00ff00; + animation: none; +} + +.dot.disconnected { + background: #ff0000; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +/* Scrollbar styling for controls panel */ +#controls-panel::-webkit-scrollbar { + width: 6px; +} + +#controls-panel::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.3); + border-radius: 3px; +} + +#controls-panel::-webkit-scrollbar-thumb { + background: rgba(0, 255, 170, 0.5); + border-radius: 3px; +} + +#controls-panel::-webkit-scrollbar-thumb:hover { + background: rgba(0, 255, 170, 0.8); +} + +/* Mobile responsiveness */ +@media (max-width: 768px) { + .panel { + padding: 10px; + font-size: 10px; + } + + #info-panel { + max-width: 200px; + } + + #controls-panel { + max-width: 180px; + right: 5px; + top: 5px; + } + + .button-group { + flex-direction: column; + } + + .mode-btn, .viz-btn { + width: 100%; + margin: 2px 0; + } +} \ No newline at end of file diff --git a/docs/static/index.html b/docs/static/index.html new file mode 100644 index 0000000..a83b0af --- /dev/null +++ b/docs/static/index.html @@ -0,0 +1,84 @@ + + + + + + CONSIM - Consciousness Lattice Visualization + + + +
+

CONSIM Lattice Engine

+
+
Core EQ:
+
C = ∫MC A(x) Φ(x) eiĻ„(x) dμ(x)
+
M = Σi λi Ui
+
+
+
Nodes: 0
+
Resonance: 0.000
+
Attention: 0.000
+
Phase: 0.0°
+
Clusters: 0
+
FPS: 0
+
+
+ +
+

Physics Controls

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +

Interaction Mode

+
+ + + + +
+ +

Visualization Mode

+
+ + + + + +
+ +

Actions

+
+ + +
+
+ +
+ Connecting... + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/static/js/app.js b/docs/static/js/app.js new file mode 100644 index 0000000..ad2edcf --- /dev/null +++ b/docs/static/js/app.js @@ -0,0 +1,341 @@ +/** + * CONSIM Main Application + * + * This module manages the WebSocket connection to the Python backend + * and coordinates the Three.js consciousness field visualization. + */ + +class ConsciousnessApp { + constructor() { + this.ws = null; + this.renderer = null; + this.isConnected = false; + this.reconnectAttempts = 0; + this.maxReconnectAttempts = 5; + this.reconnectDelay = 1000; + + // Current interaction state + this.interactionMode = 'push'; + this.visualizationMode = 'consciousness'; + this.isMouseDown = false; + + // Physics parameters + this.params = { + gravity: 1.0, + friction: 0.99, + elasticity: 0.8, + time_dilation: 1.0, + field_strength: 1.0 + }; + + this.init(); + } + + init() { + console.log('Initializing CONSIM application...'); + + // Initialize Three.js renderer + this.renderer = new ConsciousnessFieldRenderer({ + latticeSize: 128, + complexField: true, + phaseVisualization: 'spectral', + multiverseBranching: true + }); + + // Set up event handlers + this.setupEventHandlers(); + + // Connect to WebSocket + this.connectWebSocket(); + + console.log('CONSIM application initialized'); + } + + setupEventHandlers() { + // Mouse influence callback + this.renderer.onMouseInfluence = (influence) => { + this.sendMouseInfluence(influence); + }; + + // Physics parameter sliders + this.setupSlider('gravitySlider', 'gravityValue', 'gravity'); + this.setupSlider('frictionSlider', 'frictionValue', 'friction'); + this.setupSlider('timeSlider', 'timeValue', 'time_dilation'); + this.setupSlider('fieldSlider', 'fieldValue', 'field_strength'); + + // Interaction mode buttons + document.querySelectorAll('.mode-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + this.setInteractionMode(e.target.dataset.mode); + }); + }); + + // Visualization mode buttons + document.querySelectorAll('.viz-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + this.setVisualizationMode(e.target.dataset.viz); + }); + }); + + // Action buttons + document.getElementById('collapseBtn').addEventListener('click', () => { + this.triggerQuantumCollapse(); + }); + + document.getElementById('resetBtn').addEventListener('click', () => { + this.resetSimulation(); + }); + + // Mouse events for node creation + document.getElementById('canvas').addEventListener('click', (e) => { + if (!this.isMouseDown) { + this.createNodeAtMouse(e); + } + }); + } + + setupSlider(sliderId, valueId, paramName) { + const slider = document.getElementById(sliderId); + const valueDisplay = document.getElementById(valueId); + + if (slider && valueDisplay) { + slider.addEventListener('input', (e) => { + const value = parseFloat(e.target.value); + this.params[paramName] = value; + valueDisplay.textContent = paramName === 'friction' ? value.toFixed(2) : value.toFixed(1); + + // Send parameter update to server + this.sendParameterUpdate({ [paramName]: value }); + }); + } + } + + connectWebSocket() { + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + const wsUrl = `${protocol}//${window.location.host}/stream`; + + console.log(`Connecting to WebSocket: ${wsUrl}`); + this.updateConnectionStatus('connecting'); + + try { + this.ws = new WebSocket(wsUrl); + + this.ws.onopen = () => { + console.log('WebSocket connected'); + this.isConnected = true; + this.reconnectAttempts = 0; + this.updateConnectionStatus('connected'); + }; + + this.ws.onmessage = (event) => { + try { + const data = JSON.parse(event.data); + this.handleServerMessage(data); + } catch (error) { + console.error('Error parsing WebSocket message:', error); + } + }; + + this.ws.onclose = (event) => { + console.log('WebSocket closed:', event.code, event.reason); + this.isConnected = false; + this.updateConnectionStatus('disconnected'); + + // Attempt to reconnect + if (this.reconnectAttempts < this.maxReconnectAttempts) { + this.reconnectAttempts++; + console.log(`Reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`); + setTimeout(() => this.connectWebSocket(), this.reconnectDelay); + this.reconnectDelay *= 1.5; // Exponential backoff + } else { + console.error('Max reconnection attempts reached'); + } + }; + + this.ws.onerror = (error) => { + console.error('WebSocket error:', error); + this.updateConnectionStatus('disconnected'); + }; + + } catch (error) { + console.error('Error creating WebSocket:', error); + this.updateConnectionStatus('disconnected'); + } + } + + handleServerMessage(data) { + // Update renderer with new lattice state + this.renderer.updateFromLatticeState(data); + + // Update UI if global stats are present + if (data.global_stats) { + this.updateGlobalStats(data.global_stats); + } + + // Update visualization mode if changed + if (data.mode && data.mode !== this.visualizationMode) { + this.visualizationMode = data.mode; + this.renderer.setVisualizationMode(data.mode); + this.updateVisualizationModeUI(data.mode); + } + } + + updateGlobalStats(stats) { + // Stats are already updated by the renderer, but we can add additional processing here + if (stats.consciousness_magnitude > 0.8) { + // High consciousness state - could trigger special effects + } + } + + sendMessage(type, data) { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + const message = { + type: type, + data: data, + timestamp: Date.now() + }; + this.ws.send(JSON.stringify(message)); + } else { + console.warn('WebSocket not connected, message not sent:', type, data); + } + } + + sendMouseInfluence(influence) { + this.sendMessage('mouse_influence', influence); + } + + sendParameterUpdate(params) { + this.sendMessage('parameter_update', params); + } + + createNodeAtMouse(event) { + const rect = event.target.getBoundingClientRect(); + const mouse = { + x: ((event.clientX - rect.left) / rect.width) * 2 - 1, + y: -((event.clientY - rect.top) / rect.height) * 2 + 1 + }; + + // Convert to world coordinates + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(mouse, this.renderer.camera); + const intersectPoint = new THREE.Vector3(); + raycaster.ray.intersectPlane(new THREE.Plane(new THREE.Vector3(0, 0, 1)), intersectPoint); + + this.sendMessage('add_node', { + x: intersectPoint.x, + y: intersectPoint.y + }); + } + + triggerQuantumCollapse() { + // Trigger collapse at center of screen + this.sendMessage('quantum_collapse', { x: 0, y: 0 }); + } + + resetSimulation() { + if (confirm('Reset the entire consciousness lattice?')) { + this.sendMessage('reset', {}); + } + } + + setInteractionMode(mode) { + this.interactionMode = mode; + this.renderer.setInteractionMode(mode); + + // Update UI + document.querySelectorAll('.mode-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.mode === mode); + }); + + console.log('Interaction mode changed to:', mode); + } + + setVisualizationMode(mode) { + this.visualizationMode = mode; + this.renderer.setVisualizationMode(mode); + + // Send mode change to server + this.sendMessage('set_mode', { mode: mode }); + + this.updateVisualizationModeUI(mode); + console.log('Visualization mode changed to:', mode); + } + + updateVisualizationModeUI(mode) { + document.querySelectorAll('.viz-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.viz === mode); + }); + } + + updateConnectionStatus(status) { + const statusText = document.getElementById('statusText'); + const statusDot = document.getElementById('statusDot'); + + if (statusText && statusDot) { + statusDot.className = 'dot ' + status; + + switch(status) { + case 'connecting': + statusText.textContent = 'Connecting...'; + break; + case 'connected': + statusText.textContent = 'Connected'; + break; + case 'disconnected': + statusText.textContent = 'Disconnected'; + break; + } + } + } + + // API methods for external control + async fetchStatus() { + try { + const response = await fetch('/api/status'); + return await response.json(); + } catch (error) { + console.error('Error fetching status:', error); + return null; + } + } + + async updateParametersViaAPI(params) { + try { + const response = await fetch('/api/parameters', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(params) + }); + return await response.json(); + } catch (error) { + console.error('Error updating parameters via API:', error); + return null; + } + } + + dispose() { + if (this.ws) { + this.ws.close(); + } + if (this.renderer) { + this.renderer.dispose(); + } + } +} + +// Initialize application when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + window.consimApp = new ConsciousnessApp(); +}); + +// Handle page unload +window.addEventListener('beforeunload', () => { + if (window.consimApp) { + window.consimApp.dispose(); + } +}); + +// Export for use in other modules +if (typeof module !== 'undefined' && module.exports) { + module.exports = ConsciousnessApp; +} \ No newline at end of file diff --git a/docs/static/js/app_demo.js b/docs/static/js/app_demo.js new file mode 100644 index 0000000..2aed4a8 --- /dev/null +++ b/docs/static/js/app_demo.js @@ -0,0 +1,418 @@ +/** + * CONSIM Demo Application - HTTP Polling Version + * + * This is a simplified version that uses HTTP polling instead of WebSockets + * for environments where full dependencies aren't available. + */ + +class ConsciousnessApp { + constructor() { + this.renderer = null; + this.isRunning = false; + this.pollInterval = null; + this.pollDelay = 100; // 10fps polling for demo + + // Current interaction state + this.interactionMode = 'push'; + this.visualizationMode = 'consciousness'; + this.isMouseDown = false; + + // Physics parameters + this.params = { + gravity: 1.0, + friction: 0.99, + elasticity: 0.8, + time_dilation: 1.0, + field_strength: 1.0 + }; + + this.init(); + } + + init() { + console.log('Initializing CONSIM demo application...'); + + // Check if Three.js is available + if (typeof THREE === 'undefined') { + console.warn('Three.js not loaded, using fallback 2D renderer'); + this.initFallbackRenderer(); + } else { + // Initialize Three.js renderer + this.renderer = new ConsciousnessFieldRenderer({ + latticeSize: 64, + complexField: true, + phaseVisualization: 'spectral', + multiverseBranching: true + }); + + // Set up mouse influence callback + this.renderer.onMouseInfluence = (influence) => { + // In demo mode, we can't send real-time mouse data + // but we can create nodes on click + }; + } + + // Set up event handlers + this.setupEventHandlers(); + + // Start polling for updates + this.startPolling(); + + // Update connection status + this.updateConnectionStatus('connected'); + + console.log('CONSIM demo application initialized'); + } + + initFallbackRenderer() { + // Simple 2D Canvas fallback renderer + const canvas = document.getElementById('canvas'); + const ctx = canvas.getContext('2d'); + + this.fallbackRenderer = { + canvas: canvas, + ctx: ctx, + width: window.innerWidth, + height: window.innerHeight, + + updateFromLatticeState: (state) => { + if (!state || !state.nodes) return; + + // Clear canvas + ctx.fillStyle = 'rgba(10, 10, 26, 0.1)'; + ctx.fillRect(0, 0, this.fallbackRenderer.width, this.fallbackRenderer.height); + + // Draw nodes + const centerX = this.fallbackRenderer.width / 2; + const centerY = this.fallbackRenderer.height / 2; + const scale = 0.5; + + state.nodes.forEach(node => { + const x = centerX + node.x * scale; + const y = centerY + node.y * scale; + const radius = node.radius || 3; + + // Calculate consciousness magnitude for color + const magnitude = Math.sqrt((node.consciousness_re || 0)**2 + (node.consciousness_im || 0)**2); + const phase = Math.atan2(node.consciousness_im || 0, node.consciousness_re || 0); + + // Map phase to hue + const hue = (phase + Math.PI) / (2 * Math.PI) * 360; + const saturation = 70 + (node.consciousness_depth || 0) * 30; + const lightness = 30 + magnitude * 20; + + ctx.fillStyle = `hsl(${hue}, ${saturation}%, ${lightness}%)`; + ctx.shadowColor = ctx.fillStyle; + ctx.shadowBlur = 10; + + ctx.beginPath(); + ctx.arc(x, y, radius, 0, Math.PI * 2); + ctx.fill(); + + ctx.shadowBlur = 0; + }); + + // Draw cluster connections + if (state.clusters) { + state.clusters.forEach(cluster => { + if (!cluster.nodes || cluster.nodes.length < 2) return; + + ctx.strokeStyle = `hsl(${(cluster.id * 60) % 360}, 80%, 50%)`; + ctx.lineWidth = 1; + ctx.globalAlpha = 0.5; + + for (let i = 0; i < cluster.nodes.length; i++) { + for (let j = i + 1; j < cluster.nodes.length; j++) { + const nodeA = cluster.nodes[i]; + const nodeB = cluster.nodes[j]; + + const x1 = centerX + nodeA.x * scale; + const y1 = centerY + nodeA.y * scale; + const x2 = centerX + nodeB.x * scale; + const y2 = centerY + nodeB.y * scale; + + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); + } + } + + ctx.globalAlpha = 1; + }); + } + } + }; + + // Resize handler + const resizeCanvas = () => { + this.fallbackRenderer.width = canvas.width = window.innerWidth; + this.fallbackRenderer.height = canvas.height = window.innerHeight; + }; + + resizeCanvas(); + window.addEventListener('resize', resizeCanvas); + } + + setupEventHandlers() { + // Physics parameter sliders + this.setupSlider('gravitySlider', 'gravityValue', 'gravity'); + this.setupSlider('frictionSlider', 'frictionValue', 'friction'); + this.setupSlider('timeSlider', 'timeValue', 'time_dilation'); + this.setupSlider('fieldSlider', 'fieldValue', 'field_strength'); + + // Interaction mode buttons + document.querySelectorAll('.mode-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + this.setInteractionMode(e.target.dataset.mode); + }); + }); + + // Visualization mode buttons + document.querySelectorAll('.viz-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + this.setVisualizationMode(e.target.dataset.viz); + }); + }); + + // Action buttons + document.getElementById('collapseBtn').addEventListener('click', () => { + this.triggerQuantumCollapse(); + }); + + document.getElementById('resetBtn').addEventListener('click', () => { + this.resetSimulation(); + }); + + // Mouse events for node creation + document.getElementById('canvas').addEventListener('click', (e) => { + this.createNodeAtMouse(e); + }); + } + + setupSlider(sliderId, valueId, paramName) { + const slider = document.getElementById(sliderId); + const valueDisplay = document.getElementById(valueId); + + if (slider && valueDisplay) { + slider.addEventListener('input', (e) => { + const value = parseFloat(e.target.value); + this.params[paramName] = value; + valueDisplay.textContent = paramName === 'friction' ? value.toFixed(2) : value.toFixed(1); + + // Send parameter update to server + this.sendParameterUpdate({ [paramName]: value }); + }); + } + } + + async startPolling() { + this.isRunning = true; + + // First update the lattice + await this.updateLattice(); + + // Start polling loop + this.pollInterval = setInterval(async () => { + if (this.isRunning) { + await this.fetchAndUpdateState(); + await this.updateLattice(); + } + }, this.pollDelay); + } + + stopPolling() { + this.isRunning = false; + if (this.pollInterval) { + clearInterval(this.pollInterval); + this.pollInterval = null; + } + } + + async fetchAndUpdateState() { + try { + const response = await fetch('/api/state'); + if (response.ok) { + const state = await response.json(); + + // Update renderer + if (this.renderer && this.renderer.updateFromLatticeState) { + this.renderer.updateFromLatticeState(state); + } else if (this.fallbackRenderer) { + this.fallbackRenderer.updateFromLatticeState(state); + } + + // Update stats + if (state.global_stats) { + this.updateStats(state.global_stats); + } + } + } catch (error) { + console.error('Error fetching state:', error); + this.updateConnectionStatus('disconnected'); + } + } + + async updateLattice() { + try { + const response = await fetch('/api/update', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({}) + }); + + if (!response.ok) { + throw new Error('Update failed'); + } + } catch (error) { + console.error('Error updating lattice:', error); + } + } + + updateStats(stats) { + // Update UI elements + document.getElementById('nodeCount').textContent = stats.node_count || 0; + document.getElementById('resonance').textContent = (stats.global_resonance || 0).toFixed(3); + document.getElementById('attention').textContent = (stats.average_attention || 0).toFixed(3); + document.getElementById('phase').textContent = (stats.average_phase_degrees || 0).toFixed(1); + document.getElementById('clusterCount').textContent = stats.cluster_count || 0; + document.getElementById('fps').textContent = Math.round(1000 / this.pollDelay); + } + + async sendParameterUpdate(params) { + try { + await fetch('/api/parameters', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(params) + }); + } catch (error) { + console.error('Error updating parameters:', error); + } + } + + async createNodeAtMouse(event) { + const rect = event.target.getBoundingClientRect(); + const centerX = rect.width / 2; + const centerY = rect.height / 2; + const scale = 0.5; + + // Convert to world coordinates + const worldX = (event.clientX - rect.left - centerX) / scale; + const worldY = (event.clientY - rect.top - centerY) / scale; + + try { + await fetch('/api/nodes', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ x: worldX, y: worldY }) + }); + console.log(`Node created at (${worldX.toFixed(1)}, ${worldY.toFixed(1)})`); + } catch (error) { + console.error('Error creating node:', error); + } + } + + async triggerQuantumCollapse() { + try { + await fetch('/api/collapse', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ x: 0, y: 0 }) + }); + console.log('Quantum collapse triggered'); + } catch (error) { + console.error('Error triggering collapse:', error); + } + } + + async resetSimulation() { + if (confirm('Reset the entire consciousness lattice?')) { + try { + await fetch('/api/reset', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({}) + }); + console.log('Simulation reset'); + } catch (error) { + console.error('Error resetting simulation:', error); + } + } + } + + setInteractionMode(mode) { + this.interactionMode = mode; + if (this.renderer && this.renderer.setInteractionMode) { + this.renderer.setInteractionMode(mode); + } + + // Update UI + document.querySelectorAll('.mode-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.mode === mode); + }); + + console.log('Interaction mode changed to:', mode); + } + + setVisualizationMode(mode) { + this.visualizationMode = mode; + if (this.renderer && this.renderer.setVisualizationMode) { + this.renderer.setVisualizationMode(mode); + } + + this.updateVisualizationModeUI(mode); + console.log('Visualization mode changed to:', mode); + } + + updateVisualizationModeUI(mode) { + document.querySelectorAll('.viz-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.viz === mode); + }); + } + + updateConnectionStatus(status) { + const statusText = document.getElementById('statusText'); + const statusDot = document.getElementById('statusDot'); + + if (statusText && statusDot) { + statusDot.className = 'dot ' + status; + + switch(status) { + case 'connecting': + statusText.textContent = 'Connecting...'; + break; + case 'connected': + statusText.textContent = 'Connected (Demo)'; + break; + case 'disconnected': + statusText.textContent = 'Disconnected'; + break; + } + } + } + + dispose() { + this.stopPolling(); + if (this.renderer && this.renderer.dispose) { + this.renderer.dispose(); + } + } +} + +// Initialize application when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + window.consimApp = new ConsciousnessApp(); +}); + +// Handle page unload +window.addEventListener('beforeunload', () => { + if (window.consimApp) { + window.consimApp.dispose(); + } +}); + +// Export for use in other modules +if (typeof module !== 'undefined' && module.exports) { + module.exports = ConsciousnessApp; +} \ No newline at end of file diff --git a/docs/static/js/consciousnessRenderer.js b/docs/static/js/consciousnessRenderer.js new file mode 100644 index 0000000..3e160a0 --- /dev/null +++ b/docs/static/js/consciousnessRenderer.js @@ -0,0 +1,603 @@ +/** + * Consciousness Field Renderer - Three.js WebGL implementation + * + * This module provides GPU-accelerated visualization of consciousness fields + * with shader-based rendering for: + * - Complex-valued lattice fields with phase information + * - Real-time particle systems for consciousness nodes + * - Interactive controls for parameter manipulation + */ + +class ConsciousnessFieldRenderer { + constructor(options = {}) { + this.options = { + latticeSize: options.latticeSize || 128, + complexField: options.complexField !== false, + phaseVisualization: options.phaseVisualization || 'spectral', + multiverseBranching: options.multiverseBranching !== false, + enableParticles: options.enableParticles !== false, + enableClusters: options.enableClusters !== false, + ...options + }; + + this.scene = null; + this.camera = null; + this.renderer = null; + this.canvas = null; + + // Consciousness field materials and geometries + this.nodeMaterial = null; + this.clusterMaterial = null; + this.universeMaterial = null; + this.attentionFieldMaterial = null; + + // Node instances for GPU instancing + this.nodeGeometry = null; + this.nodeInstances = null; + this.maxNodes = 1000; + + // Cluster connections + this.clusterConnections = []; + + // Camera controls + this.cameraTarget = new THREE.Vector3(0, 0, 0); + this.cameraPosition = new THREE.Vector3(0, 0, 500); + this.zoom = 1.0; + + // Mouse interaction + this.mouse = new THREE.Vector2(); + this.raycaster = new THREE.Raycaster(); + this.isMouseDown = false; + this.currentMode = 'consciousness'; + this.interactionMode = 'push'; + + // Performance tracking + this.frameCount = 0; + this.lastFPSUpdate = Date.now(); + this.fps = 0; + + this.init(); + } + + init() { + // Get canvas + this.canvas = document.getElementById('canvas'); + + // Setup Three.js scene + this.setupScene(); + this.setupCamera(); + this.setupRenderer(); + this.setupLighting(); + this.setupMaterials(); + this.setupGeometry(); + this.setupEventListeners(); + + // Start render loop + this.animate(); + + console.log('Consciousness Field Renderer initialized'); + } + + setupScene() { + this.scene = new THREE.Scene(); + this.scene.background = new THREE.Color(0x0a0a1a); + + // Add subtle fog for depth + this.scene.fog = new THREE.Fog(0x0a0a1a, 1000, 3000); + } + + setupCamera() { + const aspect = window.innerWidth / window.innerHeight; + this.camera = new THREE.PerspectiveCamera(60, aspect, 1, 5000); + this.camera.position.copy(this.cameraPosition); + this.camera.lookAt(this.cameraTarget); + } + + setupRenderer() { + this.renderer = new THREE.WebGLRenderer({ + canvas: this.canvas, + antialias: true, + alpha: false, + powerPreference: "high-performance" + }); + + this.renderer.setSize(window.innerWidth, window.innerHeight); + this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); + this.renderer.sortObjects = false; + this.renderer.autoClear = false; + + // Enable additive blending for glow effects + this.renderer.capabilities.logarithmicDepthBuffer = true; + } + + setupLighting() { + // Ambient light for base visibility + const ambientLight = new THREE.AmbientLight(0x404040, 0.3); + this.scene.add(ambientLight); + + // Point light for consciousness field illumination + const pointLight = new THREE.PointLight(0x00ffaa, 1, 1000); + pointLight.position.set(0, 0, 200); + this.scene.add(pointLight); + } + + setupMaterials() { + // Consciousness node material with complex field visualization + this.nodeMaterial = new THREE.ShaderMaterial({ + uniforms: { + time: { value: 0 }, + amplitude: { value: 1.0 }, + phase: { value: 0.0 }, + frequency: { value: 40.0 }, + consciousness_re: { value: 0.0 }, + consciousness_im: { value: 0.0 }, + intelligence_depth: { value: 0.0 }, + cluster_id: { value: -1 } + }, + vertexShader: ` + attribute float amplitude; + attribute float phase; + attribute float frequency; + attribute float consciousness_re; + attribute float consciousness_im; + attribute float intelligence_depth; + attribute float cluster_id; + + varying float vAmplitude; + varying float vPhase; + varying float vFrequency; + varying float vConsciousness_re; + varying float vConsciousness_im; + varying float vIntelligence_depth; + varying float vCluster_id; + varying vec3 vPosition; + + uniform float time; + + void main() { + vAmplitude = amplitude; + vPhase = phase; + vFrequency = frequency; + vConsciousness_re = consciousness_re; + vConsciousness_im = consciousness_im; + vIntelligence_depth = intelligence_depth; + vCluster_id = cluster_id; + vPosition = position; + + // Calculate consciousness magnitude for vertex displacement + float consciousness_magnitude = sqrt(consciousness_re * consciousness_re + consciousness_im * consciousness_im); + vec3 displaced = position + normal * consciousness_magnitude * 2.0; + + gl_Position = projectionMatrix * modelViewMatrix * vec4(displaced, 1.0); + gl_PointSize = 5.0 + consciousness_magnitude * 3.0; + } + `, + fragmentShader: ` + varying float vAmplitude; + varying float vPhase; + varying float vFrequency; + varying float vConsciousness_re; + varying float vConsciousness_im; + varying float vIntelligence_depth; + varying float vCluster_id; + varying vec3 vPosition; + + uniform float time; + + vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + } + + void main() { + // Calculate consciousness magnitude and phase + float consciousness_magnitude = sqrt(vConsciousness_re * vConsciousness_re + vConsciousness_im * vConsciousness_im); + float consciousness_phase = atan(vConsciousness_im, vConsciousness_re); + + // Map phase to hue (0-360 degrees) + float hue = (consciousness_phase + 3.14159) / (2.0 * 3.14159); + + // Map amplitude to brightness + float brightness = min(1.0, consciousness_magnitude * 0.1 + 0.3); + + // Intelligence affects saturation + float saturation = 0.7 + vIntelligence_depth * 0.3; + + // Cluster highlighting + if (vCluster_id >= 0.0) { + brightness += 0.3; + saturation = 1.0; + } + + // Time-based pulsing based on frequency + float pulse = sin(time * vFrequency * 0.1 + vPhase) * 0.2 + 0.8; + brightness *= pulse; + + vec3 color = hsv2rgb(vec3(hue, saturation, brightness)); + + // Glow effect for high consciousness + if (consciousness_magnitude > 0.5) { + color += vec3(0.2, 0.2, 0.8) * (consciousness_magnitude - 0.5); + } + + gl_FragColor = vec4(color, brightness); + } + `, + transparent: true, + blending: THREE.AdditiveBlending + }); + + // Attention field material (for attention visualization mode) + this.attentionFieldMaterial = new THREE.ShaderMaterial({ + uniforms: { + time: { value: 0 }, + attention_intensity: { value: 1.0 } + }, + vertexShader: ` + attribute float attention; + varying float vAttention; + + void main() { + vAttention = attention; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } + `, + fragmentShader: ` + varying float vAttention; + uniform float time; + + void main() { + float intensity = vAttention * (sin(time * 2.0) * 0.3 + 0.7); + vec3 color = vec3(0.0, 0.6, 1.0) * intensity; + gl_FragColor = vec4(color, intensity * 0.5); + } + `, + transparent: true, + blending: THREE.AdditiveBlending + }); + + // Universe boundary material + this.universeMaterial = new THREE.ShaderMaterial({ + uniforms: { + time: { value: 0 }, + resonance_coeff: { value: 1.0 } + }, + vertexShader: ` + uniform float time; + uniform float resonance_coeff; + + void main() { + vec3 displaced = position + normal * sin(time * 2.0 + position.x * 0.01) * resonance_coeff * 5.0; + gl_Position = projectionMatrix * modelViewMatrix * vec4(displaced, 1.0); + } + `, + fragmentShader: ` + uniform float resonance_coeff; + + void main() { + vec3 color = vec3(1.0, 0.2, 0.2) * resonance_coeff; + gl_FragColor = vec4(color, 0.3); + } + `, + transparent: true, + wireframe: true + }); + } + + setupGeometry() { + // Create instanced geometry for consciousness nodes + this.nodeGeometry = new THREE.SphereGeometry(3, 12, 8); + + // Setup instance data arrays + const positions = new Float32Array(this.maxNodes * 3); + const amplitudes = new Float32Array(this.maxNodes); + const phases = new Float32Array(this.maxNodes); + const frequencies = new Float32Array(this.maxNodes); + const consciousness_res = new Float32Array(this.maxNodes); + const consciousness_ims = new Float32Array(this.maxNodes); + const intelligence_depths = new Float32Array(this.maxNodes); + const cluster_ids = new Float32Array(this.maxNodes); + + // Create instanced mesh + this.nodeInstances = new THREE.InstancedMesh( + this.nodeGeometry, + this.nodeMaterial, + this.maxNodes + ); + + // Add instance attributes + this.nodeInstances.geometry.setAttribute('amplitude', new THREE.InstancedBufferAttribute(amplitudes, 1)); + this.nodeInstances.geometry.setAttribute('phase', new THREE.InstancedBufferAttribute(phases, 1)); + this.nodeInstances.geometry.setAttribute('frequency', new THREE.InstancedBufferAttribute(frequencies, 1)); + this.nodeInstances.geometry.setAttribute('consciousness_re', new THREE.InstancedBufferAttribute(consciousness_res, 1)); + this.nodeInstances.geometry.setAttribute('consciousness_im', new THREE.InstancedBufferAttribute(consciousness_ims, 1)); + this.nodeInstances.geometry.setAttribute('intelligence_depth', new THREE.InstancedBufferAttribute(intelligence_depths, 1)); + this.nodeInstances.geometry.setAttribute('cluster_id', new THREE.InstancedBufferAttribute(cluster_ids, 1)); + + this.nodeInstances.count = 0; // Start with no instances + this.scene.add(this.nodeInstances); + } + + setupEventListeners() { + // Mouse events + this.canvas.addEventListener('mousedown', (e) => this.onMouseDown(e)); + this.canvas.addEventListener('mouseup', (e) => this.onMouseUp(e)); + this.canvas.addEventListener('mousemove', (e) => this.onMouseMove(e)); + this.canvas.addEventListener('wheel', (e) => this.onWheel(e)); + + // Touch events for mobile + this.canvas.addEventListener('touchstart', (e) => this.onTouchStart(e)); + this.canvas.addEventListener('touchend', (e) => this.onTouchEnd(e)); + this.canvas.addEventListener('touchmove', (e) => this.onTouchMove(e)); + + // Window resize + window.addEventListener('resize', () => this.onWindowResize()); + } + + updateFromLatticeState(state) { + if (!state || !state.nodes) return; + + const nodes = state.nodes; + const nodeCount = Math.min(nodes.length, this.maxNodes); + + // Update instance count + this.nodeInstances.count = nodeCount; + + // Update instance data + const matrix = new THREE.Matrix4(); + const positions = this.nodeInstances.geometry.attributes.amplitude; + const phases = this.nodeInstances.geometry.attributes.phase; + const frequencies = this.nodeInstances.geometry.attributes.frequency; + const consciousness_res = this.nodeInstances.geometry.attributes.consciousness_re; + const consciousness_ims = this.nodeInstances.geometry.attributes.consciousness_im; + const intelligence_depths = this.nodeInstances.geometry.attributes.intelligence_depth; + const cluster_ids = this.nodeInstances.geometry.attributes.cluster_id; + + for (let i = 0; i < nodeCount; i++) { + const node = nodes[i]; + + // Update instance matrix (position and scale) + const consciousness_magnitude = Math.sqrt(node.consciousness_re * node.consciousness_re + node.consciousness_im * node.consciousness_im); + const scale = 1.0 + consciousness_magnitude * 0.3; + + matrix.makeScale(scale, scale, scale); + matrix.setPosition(node.x, node.y, 0); + this.nodeInstances.setMatrixAt(i, matrix); + + // Update instance attributes + positions.array[i] = node.attention || 0; + phases.array[i] = node.phase || 0; + frequencies.array[i] = node.frequency || 40; + consciousness_res.array[i] = node.consciousness_re || 0; + consciousness_ims.array[i] = node.consciousness_im || 0; + intelligence_depths.array[i] = node.consciousness_depth || 0; + cluster_ids.array[i] = node.cluster_id || -1; + } + + // Mark attributes as needing update + this.nodeInstances.instanceMatrix.needsUpdate = true; + positions.needsUpdate = true; + phases.needsUpdate = true; + frequencies.needsUpdate = true; + consciousness_res.needsUpdate = true; + consciousness_ims.needsUpdate = true; + intelligence_depths.needsUpdate = true; + cluster_ids.needsUpdate = true; + + // Update cluster connections + this.updateClusterConnections(state.clusters || []); + + // Update universe boundaries + this.updateUniverses(state.universes || []); + + // Update global stats + this.updateStats(state.global_stats || {}); + } + + updateClusterConnections(clusters) { + // Remove old connections + this.clusterConnections.forEach(connection => { + this.scene.remove(connection); + }); + this.clusterConnections = []; + + // Add new connections + clusters.forEach(cluster => { + if (!cluster.nodes || cluster.nodes.length < 2) return; + + const geometry = new THREE.BufferGeometry(); + const positions = []; + const colors = []; + + // Create connections between all nodes in cluster + for (let i = 0; i < cluster.nodes.length; i++) { + for (let j = i + 1; j < cluster.nodes.length; j++) { + const nodeA = cluster.nodes[i]; + const nodeB = cluster.nodes[j]; + + positions.push(nodeA.x, nodeA.y, 0); + positions.push(nodeB.x, nodeB.y, 0); + + // Color based on cluster ID + const hue = (cluster.id * 30) % 360 / 360; + const color = new THREE.Color().setHSL(hue, 1.0, 0.6); + colors.push(color.r, color.g, color.b); + colors.push(color.r, color.g, color.b); + } + } + + geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); + geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); + + const material = new THREE.LineBasicMaterial({ + vertexColors: true, + transparent: true, + opacity: 0.6, + blending: THREE.AdditiveBlending + }); + + const connections = new THREE.LineSegments(geometry, material); + this.scene.add(connections); + this.clusterConnections.push(connections); + }); + } + + updateUniverses(universes) { + // Implementation for universe boundary visualization + // This would create wireframe spheres for each universe + } + + updateStats(stats) { + // Update UI elements + document.getElementById('nodeCount').textContent = stats.node_count || 0; + document.getElementById('resonance').textContent = (stats.global_resonance || 0).toFixed(3); + document.getElementById('attention').textContent = (stats.average_attention || 0).toFixed(3); + document.getElementById('phase').textContent = (stats.average_phase_degrees || 0).toFixed(1); + document.getElementById('clusterCount').textContent = stats.cluster_count || 0; + } + + // Mouse and touch event handlers + onMouseDown(event) { + this.isMouseDown = true; + this.updateMousePosition(event); + } + + onMouseUp(event) { + this.isMouseDown = false; + } + + onMouseMove(event) { + this.updateMousePosition(event); + } + + onWheel(event) { + event.preventDefault(); + + const zoomSpeed = 0.1; + const delta = event.deltaY > 0 ? 1 + zoomSpeed : 1 - zoomSpeed; + + this.zoom *= delta; + this.zoom = Math.max(0.1, Math.min(5.0, this.zoom)); + + this.updateCamera(); + } + + onTouchStart(event) { + if (event.touches.length === 1) { + this.onMouseDown(event.touches[0]); + } + } + + onTouchEnd(event) { + this.onMouseUp(); + } + + onTouchMove(event) { + if (event.touches.length === 1) { + event.preventDefault(); + this.onMouseMove(event.touches[0]); + } + } + + updateMousePosition(event) { + const rect = this.canvas.getBoundingClientRect(); + this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; + this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; + + // Convert to world coordinates + this.raycaster.setFromCamera(this.mouse, this.camera); + const intersectPoint = new THREE.Vector3(); + this.raycaster.ray.intersectPlane(new THREE.Plane(new THREE.Vector3(0, 0, 1)), intersectPoint); + + // Send mouse influence to server + if (this.onMouseInfluence) { + this.onMouseInfluence({ + x: intersectPoint.x, + y: intersectPoint.y, + active: this.isMouseDown, + mode: this.interactionMode + }); + } + } + + updateCamera() { + const distance = 500 / this.zoom; + this.camera.position.z = distance; + this.camera.updateProjectionMatrix(); + } + + onWindowResize() { + const width = window.innerWidth; + const height = window.innerHeight; + + this.camera.aspect = width / height; + this.camera.updateProjectionMatrix(); + + this.renderer.setSize(width, height); + } + + setVisualizationMode(mode) { + this.currentMode = mode; + + // Update material uniforms or switch materials based on mode + switch(mode) { + case 'attention': + // Switch to attention field visualization + break; + case 'frequency': + // Emphasize frequency visualization + break; + case 'temporal': + // Show temporal phase patterns + break; + case 'multiverse': + // Show universe boundaries + break; + default: + // Default consciousness visualization + break; + } + } + + setInteractionMode(mode) { + this.interactionMode = mode; + } + + animate() { + requestAnimationFrame(() => this.animate()); + + const time = Date.now() * 0.001; + + // Update shader uniforms + this.nodeMaterial.uniforms.time.value = time; + if (this.attentionFieldMaterial) { + this.attentionFieldMaterial.uniforms.time.value = time; + } + if (this.universeMaterial) { + this.universeMaterial.uniforms.time.value = time; + } + + // Update FPS counter + this.frameCount++; + if (Date.now() - this.lastFPSUpdate > 1000) { + this.fps = this.frameCount; + this.frameCount = 0; + this.lastFPSUpdate = Date.now(); + document.getElementById('fps').textContent = this.fps; + } + + // Render scene + this.renderer.clear(); + this.renderer.render(this.scene, this.camera); + } + + dispose() { + // Clean up resources + this.renderer.dispose(); + this.nodeGeometry.dispose(); + this.nodeMaterial.dispose(); + if (this.attentionFieldMaterial) this.attentionFieldMaterial.dispose(); + if (this.universeMaterial) this.universeMaterial.dispose(); + } +} \ No newline at end of file