document.addEventListener('DOMContentLoaded', () => { // Toggle logic const btnWebcam = document.getElementById('btn-webcam'); const btnUpload = document.getElementById('btn-upload'); const webcamContainer = document.getElementById('webcam-container'); const uploadContainer = document.getElementById('upload-container'); // Stats layout const sysStatus = document.getElementById('system-status'); const countPeople = document.getElementById('count-people'); const countAnimals = document.getElementById('count-animals'); const latencyVal = document.getElementById('latency-val'); // Emotion Display const emotionLabel = document.getElementById('emotion-label'); const confidenceLabel = document.getElementById('confidence-label'); const ageLabel = document.getElementById('age-label'); const emotionBars = document.getElementById('emotion-bars'); // Upload components const dropZone = document.getElementById('drop-zone'); const fileInput = document.getElementById('file-input'); const browseBtn = document.getElementById('browse-btn'); const previewArea = document.getElementById('preview-area'); const imagePreview = document.getElementById('image-preview'); const uploadCanvas = document.getElementById('upload-canvas'); const resetBtn = document.getElementById('reset-btn'); const analyzeBtn = document.getElementById('analyze-btn'); // Webcam components const webcamVideo = document.getElementById('webcam-video'); const webcamCanvas = document.getElementById('webcam-canvas'); const startWebcamBtn = document.getElementById('start-webcam-btn'); const stopWebcamBtn = document.getElementById('stop-webcam-btn'); let stream = null; let webcamInterval = null; const WEBCAM_FPS = 5; let isPredicting = false; let selectedFile = null; // --- VIEW TOGGLER --- btnWebcam.addEventListener('click', () => { btnWebcam.classList.add('active'); btnUpload.classList.remove('active'); webcamContainer.classList.remove('hidden'); uploadContainer.classList.add('hidden'); }); btnUpload.addEventListener('click', () => { btnUpload.classList.add('active'); btnWebcam.classList.remove('active'); uploadContainer.classList.remove('hidden'); webcamContainer.classList.add('hidden'); stopWebcam(); }); // --- UPLOAD LOGIC --- browseBtn.addEventListener('click', (e) => { e.preventDefault(); fileInput.click(); }); dropZone.addEventListener('click', (e) => { if (e.target !== browseBtn) fileInput.click(); }); dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.style.borderColor = "#3b82f6"; }); dropZone.addEventListener('dragleave', () => { dropZone.style.borderColor = "rgba(255,255,255,0.15)"; }); dropZone.addEventListener('drop', (e) => { e.preventDefault(); dropZone.style.borderColor = "rgba(255,255,255,0.15)"; if (e.dataTransfer.files.length) handleFile(e.dataTransfer.files[0]); }); fileInput.addEventListener('change', () => { if (fileInput.files.length) handleFile(fileInput.files[0]); }); function handleFile(file) { if (!file.type.startsWith('image/')) return alert('Target must be an image.'); selectedFile = file; const reader = new FileReader(); reader.onload = (e) => { imagePreview.src = e.target.result; imagePreview.onload = () => { uploadCanvas.width = imagePreview.width; uploadCanvas.height = imagePreview.height; uploadCanvas.getContext('2d').clearRect(0, 0, uploadCanvas.width, uploadCanvas.height); }; dropZone.classList.add('hidden'); previewArea.classList.remove('hidden'); }; reader.readAsDataURL(file); } resetBtn.addEventListener('click', () => { selectedFile = null; fileInput.value = ''; previewArea.classList.add('hidden'); dropZone.classList.remove('hidden'); uploadCanvas.getContext('2d').clearRect(0, 0, uploadCanvas.width, uploadCanvas.height); resetDashboard(); }); analyzeBtn.addEventListener('click', async () => { if (!selectedFile) return; analyzeBtn.disabled = true; sysStatus.textContent = "Processing Static Target..."; const formData = new FormData(); formData.append('file', selectedFile); try { const startTick = performance.now(); const res = await fetch('/api/predict', { method: 'POST', body: formData }); const data = await res.json(); const endTick = performance.now(); latencyVal.innerHTML = `${Math.round(endTick - startTick)}ms`; if (data.success) { renderDashboard(data.data, uploadCanvas, imagePreview, false); sysStatus.textContent = "Analysis Complete"; } else { alert('Inference architecture failed: ' + data.error); sysStatus.textContent = "Inference Failed"; } } catch (error) { sysStatus.textContent = "Network Timeout"; } finally { analyzeBtn.disabled = false; } }); // --- WEBCAM LOGIC --- startWebcamBtn.addEventListener('click', async () => { try { stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "user" } }); webcamVideo.srcObject = stream; webcamVideo.onloadedmetadata = () => { webcamVideo.play(); webcamCanvas.width = webcamVideo.clientWidth; webcamCanvas.height = webcamVideo.clientHeight; startWebcamBtn.classList.add('hidden'); stopWebcamBtn.classList.remove('hidden'); sysStatus.textContent = "Tracking Active Stream..."; sysStatus.style.color = "#34d399"; emotionBars.innerHTML = '