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: 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 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()