Spaces:
Paused
Paused
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <link rel="stylesheet" href="style.css"> | |
| <title>Mission Console</title> | |
| </head> | |
| <body> | |
| <div id="app"> | |
| <header> | |
| <div class="brand"> | |
| <div class="logo" aria-hidden="true"></div> | |
| <div> | |
| <h1>Mission Console</h1> | |
| <div class="sub">Video → detection → analysis → tracking → mission assessment</div> | |
| </div> | |
| </div> | |
| <div class="status-row"> | |
| <div class="pill"> | |
| <span class="dot" id="sys-dot"></span> | |
| <span id="sys-status">STANDBY · No video loaded</span> | |
| </div> | |
| <div class="pill"> | |
| <span class="kbd">Detect</span> | |
| <span>First-frame analysis</span> | |
| </div> | |
| <div class="pill"> | |
| <span class="kbd">Track</span> | |
| <span>Continuous monitoring</span> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="workspace"> | |
| <aside> | |
| <div class="card"> | |
| <h2>Video Input</h2> | |
| <div class="hint">Upload one video. Tab 1 uses only the first frame. Tab 2 reuses the same video for tracking | |
| and monitoring.</div> | |
| <div class="row mt-md"> | |
| <label for="videoFile">Video file</label> | |
| <span class="badge"><span id="videoMeta">No file</span></span> | |
| </div> | |
| <input id="videoFile" type="file" accept="video/*" /> | |
| <div class="mt-md"> | |
| <label>Mission Objective (optional · enables class filtering)</label> | |
| <textarea id="missionText" rows="3" | |
| placeholder="Optional: e.g., Detect people and vehicles; highlight hazards and key objects."></textarea> | |
| <div class="hint mt-sm"> | |
| Mission objective is <b>optional</b>. If provided, it will be used directly as input to the detector. | |
| If left blank, the detector will detect <b>all</b> objects without filtering. | |
| <div class="mini mt-xs" id="hfBackendStatus">HF Backend: STANDBY</div> | |
| </div> | |
| </div> | |
| <div class="btnrow"> | |
| <button id="btnLoadSample" class="btn secondary" title="Optional: wire up sample videos later" disabled>Load | |
| Sample</button> | |
| <button id="btnEject" class="btn danger" title="Unload video">Eject</button> | |
| </div> | |
| <div class="grid2"> | |
| <div> | |
| <label>Detector</label> | |
| <select id="detectorSelect"> | |
| <optgroup label="Object Detection Models"> | |
| <option value="yolo11" data-kind="object" selected>Lite</option> | |
| <option value="detr_resnet50" data-kind="object">Big</option> | |
| <option value="grounding_dino" data-kind="object">Large</option> | |
| </optgroup> | |
| <optgroup label="Segmentation Models"> | |
| <option value="GSAM2-L" data-kind="segmentation">GSAM2-L</option> | |
| <option value="GSAM2-B" data-kind="segmentation">GSAM2-B</option> | |
| <option value="GSAM2-S" data-kind="segmentation">GSAM2-S</option> | |
| <option value="YSAM2-L" data-kind="segmentation">YSAM2-L (Fast)</option> | |
| <option value="YSAM2-B" data-kind="segmentation">YSAM2-B (Fast)</option> | |
| <option value="YSAM2-S" data-kind="segmentation">YSAM2-S (Fast)</option> | |
| </optgroup> | |
| <optgroup label="Drone Detection Models"> | |
| <option value="drone_yolo" data-kind="drone">Drone</option> | |
| </optgroup> | |
| </select> | |
| </div> | |
| <div> | |
| <label>Tracking</label> | |
| <select id="trackerSelect"> | |
| <option value="iou">IOU + velocity (built-in)</option> | |
| <option value="external">External hook (user API)</option> | |
| </select> | |
| </div> | |
| <label class="checkbox-row" for="enableDepthToggle" style="display:none"> | |
| <input type="checkbox" id="enableDepthToggle"> | |
| <span>Enable Legacy Depth Map (Slow)</span> | |
| </label> | |
| <label class="checkbox-row" for="enableGPTToggle" style="margin-top: 4px;"> | |
| <input type="checkbox" id="enableGPTToggle" checked> | |
| <span style="color: var(--accent-light);">Enable GPT Reasoning</span> | |
| </label> | |
| <label class="checkbox-row" for="enableStreamToggle" style="margin-top: 4px;"> | |
| <input type="checkbox" id="enableStreamToggle" checked> | |
| <span>Enable Stream Processing</span> | |
| </label> | |
| </div> | |
| </div> | |
| <div class="card" style="flex:1; min-height:0"> | |
| <h2>System Log</h2> | |
| <div class="log" id="sysLog"></div> | |
| </div> | |
| </aside> | |
| <main> | |
| <div class="tabs"> | |
| <button class="tabbtn active" data-tab="frame">Tab 1 · Detect & Analyze</button> | |
| <button class="tabbtn" data-tab="engage">Tab 2 · Track & Monitor</button> | |
| </div> | |
| <!-- ===== Tab 1 ===== --> | |
| <section class="tab active" id="tab-frame"> | |
| <div class="frame-grid"> | |
| <div class="panel panel-monitor"> | |
| <h3> | |
| <span>First Frame · Detection + Analysis</span> | |
| <span class="rightnote" id="frameNote">Awaiting video</span> | |
| </h3> | |
| <div class="viewbox" id="frameViewBox"> | |
| <canvas id="frameCanvas" width="1280" height="720"></canvas> | |
| <canvas id="frameOverlay" class="overlay" width="1280" height="720"></canvas> | |
| <div class="watermark">EO/IR · Track-ID · Classification</div> | |
| <div class="empty" id="frameEmpty"> | |
| <div class="big">Upload a video to begin</div> | |
| <div class="small">This demo performs first-frame detection and analysis. Then it replays the video | |
| with continuous object tracking.</div> | |
| <div style="display:flex; gap:10px; margin-top:6px; flex-wrap:wrap; justify-content:center;"> | |
| <span class="badge"><span class="dot"></span> If you are online, COCO-SSD loads automatically</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="btnrow" style="margin-top:10px"> | |
| <button id="btnReason" class="btn">Detect</button> | |
| <button id="btnCancelReason" class="btn danger" style="display: none;">Cancel</button> | |
| <button id="btnRecompute" class="btn secondary">Reanalyze</button> | |
| <button id="btnClear" class="btn secondary">Clear</button> | |
| </div> | |
| <div class="strip mt-md"> | |
| <span class="chip" id="chipFrameDepth" | |
| title="Toggle depth view of first frame (if available)" style="display:none">VIEW:DEFAULT</span> | |
| </div> | |
| </div> | |
| <div class="panel panel-summary" style="display:flex; flex-direction:column; min-height: 0; overflow: hidden;"> | |
| <h3> | |
| <span>Object Track Cards</span> | |
| <span class="rightnote" id="trackCount">0</span> | |
| </h3> | |
| <div class="list" id="frameTrackList" style="flex:1; overflow-y:auto; padding:6px; max-height:none;"> | |
| <!-- Cards injected here --> | |
| <div style="font-style:italic; color:var(--faint); text-align:center; margin-top:20px; font-size:12px;"> | |
| No objects tracked. | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Threat Chat Panel --> | |
| <div class="panel panel-chat" id="chatPanel"> | |
| <h3> | |
| <span>Mission Analyst</span> | |
| <button class="collapse-btn" id="chatToggle" style="font-size: 0.75rem;">▲ Close Chat</button> | |
| </h3> | |
| <div class="chat-container"> | |
| <div class="chat-messages" id="chatMessages"> | |
| <div class="chat-message chat-system"> | |
| <span class="chat-icon">SYS</span> | |
| <span class="chat-content">Run detection first, then ask questions about detected objects.</span> | |
| </div> | |
| </div> | |
| <div class="chat-input-row"> | |
| <input type="text" id="chatInput" placeholder="Ask about detections..." autocomplete="off"> | |
| <button id="chatSend" class="btn">Send</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ===== Tab 2 ===== --> | |
| <section class="tab" id="tab-engage"> | |
| <div class="engage-grid"> | |
| <div class="panel"> | |
| <h3> | |
| <span>Video Tracking · Continuous Monitoring</span> | |
| <div style="display: flex; gap: 8px; align-items: center;"> | |
| <button class="collapse-btn" id="btnToggleSidebar">◀ Hide Sidebar</button> | |
| <span class="rightnote" id="engageNote">Awaiting video</span> | |
| </div> | |
| </h3> | |
| <div class="viewbox" style="min-height: 420px;"> | |
| <video id="videoEngage" playsinline muted></video> | |
| <canvas id="engageOverlay" class="overlay"></canvas> | |
| <div class="watermark">TRACK · ID · DIST · STATUS</div> | |
| <div class="empty" id="engageEmpty"> | |
| <div class="big">No video loaded</div> | |
| <div class="small">Upload a video. Run <b>Detect</b> first to analyze objects. | |
| Then click <b>Track</b>.</div> | |
| </div> | |
| </div> | |
| <div class="btnrow mt-md"> | |
| <button id="btnEngage" class="btn">Track</button> | |
| <button id="btnPause" class="btn secondary">Pause</button> | |
| <button id="btnReset" class="btn secondary">Reset</button> | |
| </div> | |
| <div class="strip mt-md"> | |
| <span class="chip" id="chipPolicy">POLICY:AUTO</span> | |
| <span class="chip" id="chipTracks">TRACKS:0</span> | |
| <span class="chip" id="chipBeam">MODE:AUTO</span> | |
| <span class="chip" id="chipHz">DET:6Hz</span> | |
| <span class="chip" id="chipFeed" title="Toggle raw vs HF-processed feed (if available)">FEED:RAW</span> | |
| <span class="chip" id="chipDepth" title="Toggle depth view (if available)" style="display:none">VIEW:DEFAULT</span> | |
| </div> | |
| <div class="mt-md"> | |
| <div class="row"><label>Active track progress (selected)</label><small class="mini" | |
| id="dwellText">—</small> | |
| </div> | |
| <div class="bar"> | |
| <div id="dwellBar"></div> | |
| </div> | |
| </div> | |
| <div class="hint mt-md">Manual selection: choose "Manual" in Policy, then click a target in the video.</div> | |
| </div> | |
| <div class="engage-right"> | |
| <div class="panel" style="flex:1; min-height:0"> | |
| <h3> | |
| <span>Live Track Cards</span> | |
| <span class="rightnote" id="liveStamp">—</span> | |
| </h3> | |
| <div class="list" id="trackList" style="max-height:none"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| <footer> | |
| <div>Mission Console · Unclassified visuals</div> | |
| <div class="mono" id="telemetry">VIS=16km · DET=6Hz</div> | |
| </footer> | |
| <!-- Hidden video used only for first-frame capture --> | |
| <video id="videoHidden" playsinline muted style="display:none"></video> | |
| </div> | |
| <script> | |
| window.API_CONFIG = { | |
| BACKEND_BASE: "https://biaslab2025-perception.hf.space" | |
| }; | |
| </script> | |
| <script src="./js/init.js"></script> | |
| <script src="./js/core/config.js"></script> | |
| <script src="./js/core/utils.js"></script> | |
| <script src="./js/core/state.js"></script> | |
| <script src="./js/core/physics.js"></script> | |
| <script src="./js/core/video.js"></script> | |
| <script src="./js/core/hel.js"></script> | |
| <script src="./js/ui/logging.js"></script> | |
| <script src="./js/core/gptMapping.js"></script> | |
| <script src="./js/core/tracker.js"></script> | |
| <script src="./js/api/client.js"></script> | |
| <script src="./js/ui/overlays.js"></script> | |
| <script src="./js/ui/cards.js"></script> | |
| <script src="./js/ui/features.js"></script> | |
| <script src="./js/ui/cursor.js"></script> | |
| <script src="./js/ui/chat.js"></script> | |
| <script src="./data/helicopter_demo_data.js"></script> | |
| <script src="./js/core/demo.js"></script> | |
| <script src="./js/main.js"></script> | |
| </body> | |
| </html> | |