Spaces:
Sleeping
Sleeping
| const dropZone = document.getElementById('dropZone'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const imagePreview = document.getElementById('imagePreview'); | |
| const previewContainer = document.getElementById('previewContainer'); | |
| const scanningOverlay = document.getElementById('scanningOverlay'); | |
| const resultsPanel = document.getElementById('resultsPanel'); | |
| const statusText = document.getElementById('statusText'); | |
| const predictedClass = document.getElementById('predictedClass'); | |
| const confidenceValue = document.getElementById('confidenceValue'); | |
| const confidenceFill = document.getElementById('confidenceFill'); | |
| const probBreakdown = document.getElementById('probBreakdown'); | |
| const resetBtn = document.getElementById('resetBtn'); | |
| const latencyValue = document.getElementById('latencyValue'); | |
| dropZone.addEventListener('click', () => fileInput.click()); | |
| dropZone.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| dropZone.style.borderColor = 'var(--accent)'; | |
| }); | |
| dropZone.addEventListener('dragleave', () => { | |
| dropZone.style.borderColor = 'var(--glass-border)'; | |
| }); | |
| dropZone.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| const file = e.dataTransfer.files[0]; | |
| if (file && file.type.startsWith('image/')) { | |
| handleFile(file); | |
| } | |
| }); | |
| fileInput.addEventListener('change', (e) => { | |
| const file = e.target.files[0]; | |
| if (file) handleFile(file); | |
| }); | |
| function handleFile(file) { | |
| const reader = new FileReader(); | |
| reader.onload = (e) => { | |
| imagePreview.src = e.target.result; | |
| previewContainer.style.display = 'block'; | |
| startAnalysis(file); | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| async function startAnalysis(file) { | |
| statusText.innerText = 'Analyzing Neural Data...'; | |
| scanningOverlay.style.display = 'block'; | |
| const startTime = performance.now(); | |
| const formData = new FormData(); | |
| formData.append('file', file); | |
| try { | |
| const response = await fetch('/predict', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| const data = await response.json(); | |
| const endTime = performance.now(); | |
| latencyValue.innerText = `${Math.round(endTime - startTime)}ms`; | |
| displayResults(data); | |
| } catch (error) { | |
| statusText.innerText = 'Analysis Failed'; | |
| console.error(error); | |
| } finally { | |
| scanningOverlay.style.display = 'none'; | |
| } | |
| } | |
| function displayResults(data) { | |
| statusText.innerText = 'Scan Complete'; | |
| predictedClass.innerText = data.class.toUpperCase(); | |
| const conf = Math.round(data.confidence * 100); | |
| confidenceValue.innerText = `${conf}%`; | |
| confidenceFill.style.width = `${conf}%`; | |
| probBreakdown.innerHTML = ''; | |
| Object.entries(data.probabilities).forEach(([name, prob]) => { | |
| const div = document.createElement('div'); | |
| div.className = 'prob-item'; | |
| div.innerHTML = ` | |
| <span>${name.toUpperCase()}</span> | |
| <span>${(prob * 100).toFixed(2)}%</span> | |
| `; | |
| probBreakdown.appendChild(div); | |
| }); | |
| } | |
| resetBtn.addEventListener('click', () => { | |
| fileInput.value = ''; | |
| previewContainer.style.display = 'none'; | |
| predictedClass.innerText = 'Awaiting Input'; | |
| confidenceValue.innerText = '0%'; | |
| confidenceFill.style.width = '0%'; | |
| probBreakdown.innerHTML = ''; | |
| statusText.innerText = 'System Ready'; | |
| latencyValue.innerText = '0ms'; | |
| }); | |