Local web-based control interface for the Jibo social robot via the ROM WebSocket API (port 8160) and on-device ASR (port 8088). Features head navigation via click-to-look and arrow keys, speech/listen/Voice-AI loop, display control, camera/photo capture, and entity tracking — no cloud dependency required. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
593 lines
25 KiB
HTML
593 lines
25 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Re-Commander — Jibo</title>
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<div id="status-dot"></div>
|
|
<h1>Re<span>-Commander</span></h1>
|
|
<span id="status-label">Connecting…</span>
|
|
<span id="hotword-indicator"></span>
|
|
</header>
|
|
|
|
<div class="main">
|
|
|
|
<!-- ── LEFT PANEL ── -->
|
|
<div class="left-panel">
|
|
|
|
<!-- Look / Navigation -->
|
|
<div class="section">
|
|
<div class="section-title">Head Navigation</div>
|
|
<div style="display:flex; gap:16px; align-items:center; margin-bottom:8px;">
|
|
<div class="arrow-pad">
|
|
<div></div>
|
|
<button id="btn-up" title="Look up (↑)">↑</button>
|
|
<div></div>
|
|
<button id="btn-left" title="Look left (←)">←</button>
|
|
<div></div>
|
|
<button id="btn-right" title="Look right (→)">→</button>
|
|
<div></div>
|
|
<button id="btn-down" title="Look down (↓)">↓</button>
|
|
<div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Say -->
|
|
<div class="section">
|
|
<div class="section-title">Say</div>
|
|
<div class="field">
|
|
<textarea id="say-text" rows="2" placeholder="Hello! I am Jibo."></textarea>
|
|
</div>
|
|
<div class="controls-row">
|
|
<button id="btn-say">▶ Say</button>
|
|
<button id="btn-say-cancel" class="danger">✕ Stop</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Listen -->
|
|
<div class="section">
|
|
<div class="section-title">Listen</div>
|
|
<div class="row">
|
|
<label>Max speech</label>
|
|
<input type="number" id="listen-max-speech" value="10000" step="1000">
|
|
<label>ms</label>
|
|
</div>
|
|
<div class="row">
|
|
<label>No-speech TO</label>
|
|
<input type="number" id="listen-max-nosp" value="5000" step="1000">
|
|
<label>ms</label>
|
|
</div>
|
|
<div class="controls-row" style="margin-bottom:8px;">
|
|
<button id="btn-listen">🎙 Listen</button>
|
|
<button id="btn-listen-cancel" class="danger">✕ Cancel</button>
|
|
</div>
|
|
<div id="listen-result">(result appears here)</div>
|
|
<div style="margin-top:8px;display:flex;align-items:center;gap:6px;">
|
|
<input type="checkbox" id="auto-listen-toggle" style="width:auto;">
|
|
<label for="auto-listen-toggle" style="margin:0;cursor:pointer;">Auto-listen on hotword</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Voice AI -->
|
|
<div class="section">
|
|
<div class="section-title">Voice AI</div>
|
|
<div style="display:flex;align-items:center;gap:6px;margin-bottom:8px;">
|
|
<input type="checkbox" id="llm-toggle" style="width:auto;">
|
|
<label for="llm-toggle" style="margin:0;cursor:pointer;">LLM voice loop</label>
|
|
<button id="btn-llm-clear" style="margin-left:auto;font-size:11px;padding:2px 8px;" title="Clear conversation history">↺ Clear</button>
|
|
</div>
|
|
<div class="field">
|
|
<label>Completions endpoint</label>
|
|
<input type="text" id="llm-endpoint" placeholder="http://localhost:11434/v1/chat/completions">
|
|
</div>
|
|
<div class="field">
|
|
<label>Model</label>
|
|
<input type="text" id="llm-model" placeholder="llama3">
|
|
</div>
|
|
<div class="field">
|
|
<label>System prompt</label>
|
|
<textarea id="llm-system-prompt" rows="3" placeholder="You are Jibo, a friendly social robot. Keep responses brief and conversational."></textarea>
|
|
</div>
|
|
<div id="llm-status" style="font-size:11px;color:var(--muted);font-style:italic;min-height:16px;"></div>
|
|
</div>
|
|
|
|
<!-- Attention -->
|
|
<div class="section">
|
|
<div class="section-title">Attention Mode</div>
|
|
<div class="attention-grid">
|
|
<button class="attn-btn" data-mode="OFF">Off</button>
|
|
<button class="attn-btn" data-mode="IDLE">Idle</button>
|
|
<button class="attn-btn" data-mode="DISENGAGE">Disengage</button>
|
|
<button class="attn-btn" data-mode="ENGAGED">Engaged</button>
|
|
<button class="attn-btn" data-mode="SPEAKING">Speaking</button>
|
|
<button class="attn-btn" data-mode="FIXATED">Fixated</button>
|
|
<button class="attn-btn" data-mode="ATTRACTABLE">Attractable</button>
|
|
<button class="attn-btn" data-mode="COMMAND">Command</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Volume -->
|
|
<div class="section">
|
|
<div class="section-title">Volume</div>
|
|
<div class="row">
|
|
<input type="range" id="volume-slider" min="0" max="1" step="0.05" value="0.75">
|
|
<span id="volume-label" style="min-width:32px;text-align:right;font-size:12px;">75%</span>
|
|
</div>
|
|
<button id="btn-set-volume">Set Volume</button>
|
|
</div>
|
|
|
|
</div><!-- /left-panel -->
|
|
|
|
<!-- ── CENTER PANEL ── -->
|
|
<div class="center-panel">
|
|
|
|
<!-- Camera feed -->
|
|
<div id="camera-wrap">
|
|
<img id="camera-feed" alt="Jibo camera" style="display:none;">
|
|
<div id="camera-no-feed">
|
|
<div style="font-size:40px;">📷</div>
|
|
<div>No camera feed</div>
|
|
<div style="font-size:11px;color:var(--muted);">Use the Camera tab to start video or take a photo</div>
|
|
</div>
|
|
<div id="click-dot"></div>
|
|
</div>
|
|
|
|
<!-- Arrow pad (compact, centered under feed) -->
|
|
<div class="controls-row" style="justify-content:center; gap:10px;">
|
|
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;">
|
|
<div style="font-size:11px;color:var(--muted);">Click on feed → look there</div>
|
|
<div style="display:flex;gap:6px;align-items:center;">
|
|
<span style="font-size:12px;color:var(--muted);">Track:</span>
|
|
<input type="checkbox" id="track-flag" style="width:auto;">
|
|
<span id="video-status"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Photos -->
|
|
<div style="width:100%;max-width:640px;">
|
|
<div class="section-title" style="margin-bottom:6px;">Photo Strip</div>
|
|
<div id="photo-strip"></div>
|
|
</div>
|
|
|
|
</div><!-- /center-panel -->
|
|
|
|
<!-- ── RIGHT PANEL ── -->
|
|
<div class="right-panel">
|
|
<div class="tabs">
|
|
<button class="tab-btn active" data-tab="tab-camera">Camera</button>
|
|
<button class="tab-btn" data-tab="tab-display">Display</button>
|
|
<button class="tab-btn" data-tab="tab-entities">Entities</button>
|
|
<button class="tab-btn" data-tab="tab-log">Log</button>
|
|
</div>
|
|
|
|
<!-- Camera tab -->
|
|
<div class="tab-panel active" id="tab-camera">
|
|
<div class="section-title">Video Stream</div>
|
|
<div class="video-controls" style="margin-bottom:8px;">
|
|
<button id="btn-video-start">▶ Start Video</button>
|
|
<button id="btn-video-stop" class="danger">■ Stop</button>
|
|
</div>
|
|
|
|
<div class="section-title" style="margin-top:10px;">Take Photo</div>
|
|
<div class="row">
|
|
<label>Camera</label>
|
|
<select id="photo-camera">
|
|
<option value="right">Right</option>
|
|
<option value="left">Left</option>
|
|
</select>
|
|
</div>
|
|
<div class="row">
|
|
<label>Resolution</label>
|
|
<select id="photo-res">
|
|
<option value="highRes">HighRes</option>
|
|
<option value="medRes">MedRes</option>
|
|
<option value="lowRes">LowRes</option>
|
|
<option value="microRes">MicroRes</option>
|
|
</select>
|
|
</div>
|
|
<button id="btn-photo" style="width:100%;margin-bottom:10px;">📷 Take Photo</button>
|
|
|
|
<div class="section-title" style="margin-top:10px;">Subscriptions</div>
|
|
<div class="controls-row">
|
|
<button id="btn-sub-entity" class="active">👤 Entity</button>
|
|
<button id="btn-sub-motion" class="active">〰 Motion</button>
|
|
<button id="btn-sub-headtouch" class="active">✋ Touch</button>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Display tab -->
|
|
<div class="tab-panel" id="tab-display">
|
|
<div class="section-title">Eye</div>
|
|
<button id="btn-eye" style="width:100%;margin-bottom:10px;">👁 Show Eye</button>
|
|
|
|
<div class="section-title">Play Animation</div>
|
|
<div class="field">
|
|
<select id="eye-anim-select">
|
|
<optgroup label="── Blinks">
|
|
<option>Eye_Blink_01</option>
|
|
<option>Eye_Blink_02</option>
|
|
<option>Eye_Double_Blink_01</option>
|
|
<option>Eye_Double_Blink_02</option>
|
|
<option>Eye_Double_Blink_03</option>
|
|
<option>Eye_Long_Blink_01</option>
|
|
<option>Eye_Medium_Blink_01</option>
|
|
<option>Eye_Quick_Blink_01</option>
|
|
<option>Eye_Quick_Blink_02</option>
|
|
</optgroup>
|
|
<optgroup label="── Expressions">
|
|
<option>Eye_Curious_01</option>
|
|
<option>Eye_Disgusted_01</option>
|
|
<option>Eye_Disgusted_02</option>
|
|
<option>eye_happy_00</option>
|
|
<option>eye_happy_01</option>
|
|
<option>eye_happy_02</option>
|
|
<option>eye_sad_01</option>
|
|
<option>eye_sad_02</option>
|
|
<option>eye_scared_00</option>
|
|
<option>eye_scared_01</option>
|
|
<option>eye_scared_02</option>
|
|
<option>eye_thinking_02</option>
|
|
<option>Confused_00</option>
|
|
<option>surprised_00</option>
|
|
<option>worried_01</option>
|
|
<option>worried_03</option>
|
|
<option>worried_04</option>
|
|
</optgroup>
|
|
<optgroup label="── Eye Moves">
|
|
<option>Checking_00</option>
|
|
<option>Checking_00_02</option>
|
|
<option>Checking_01</option>
|
|
<option>checking-lr-high-01</option>
|
|
<option>checking-lr-low-01</option>
|
|
<option>checking-lr-mid-01</option>
|
|
<option>checking-c-highlow-01</option>
|
|
<option>checking-lr-lowhigh-01</option>
|
|
<option>checking-refresher-01</option>
|
|
<option>checking_08</option>
|
|
<option>Glance_Down_01</option>
|
|
<option>Glance_Left_01</option>
|
|
<option>Glance_Left_02</option>
|
|
<option>Glance_Right_01</option>
|
|
<option>Glance_Right_02</option>
|
|
</optgroup>
|
|
<optgroup label="── Poses">
|
|
<option>Eye_Look_Center_Middle_01</option>
|
|
<option>Eye_Look_Center_Up_01</option>
|
|
<option>Eye_Look_Center_Down_01</option>
|
|
<option>Eye_Look_Left_Middle_01</option>
|
|
<option>Eye_Look_Left_Up_01</option>
|
|
<option>Eye_Look_Left_Down_01</option>
|
|
<option>Eye_Look_Right_Middle_01</option>
|
|
<option>Eye_Look_Right_Up_01</option>
|
|
<option>Eye_Look_Right_Down_01</option>
|
|
</optgroup>
|
|
<optgroup label="── Global Eye">
|
|
<option>Close_To_Open_01</option>
|
|
<option>Open_To_Close_01</option>
|
|
<option>EyeToHappy_00</option>
|
|
<option>EyeToHappy_01</option>
|
|
<option>EyeToHappy_02</option>
|
|
<option>HappyToEye_00</option>
|
|
<option>HappyToEye_01</option>
|
|
<option>eye-bounce-01</option>
|
|
<option>eye-bounce-02</option>
|
|
<option>eye-closed</option>
|
|
<option>eye-laugh-00</option>
|
|
<option>eye-laugh-01</option>
|
|
<option>eye-pop-to-rest-01</option>
|
|
<option>eye-pop-to-rest-02</option>
|
|
<option>ahh-01</option>
|
|
<option>dilation</option>
|
|
<option>dilation-02</option>
|
|
<option>no-match-eye</option>
|
|
<option>quiver-01</option>
|
|
<option>quiver-02</option>
|
|
<option>quiver-03</option>
|
|
</optgroup>
|
|
<optgroup label="── Transitions">
|
|
<option>eye-transition-blink-00</option>
|
|
<option>eye-transition-blink-02</option>
|
|
<option>eye-transition-fade-00</option>
|
|
<option>eye-closed-fade-to-black-01</option>
|
|
<option>eye-fade-from-black-00</option>
|
|
<option>eye-fade-from-black-01</option>
|
|
<option>dim-transition</option>
|
|
</optgroup>
|
|
<optgroup label="── Globals">
|
|
<option>disengaged-to-engaged-01</option>
|
|
<option>disengaged-to-engaged-02</option>
|
|
<option>disengaged-to-listening-01</option>
|
|
<option>disengaged-to-listening-02</option>
|
|
<option>disengaged-to-listening-03</option>
|
|
<option>engaged-01</option>
|
|
<option>engaged-02</option>
|
|
<option>engaged-03</option>
|
|
<option>engaged-04</option>
|
|
<option>eye-center-to-up-01</option>
|
|
<option>eye-center-to-down-01</option>
|
|
<option>eye-up-to-center-01</option>
|
|
<option>eye-down-to-center-01</option>
|
|
</optgroup>
|
|
<optgroup label="── Thinking">
|
|
<option>Thinking_Dots_03</option>
|
|
<option>eye_thinking_02</option>
|
|
</optgroup>
|
|
<optgroup label="── Misc">
|
|
<option>Sleeping_Idle_01</option>
|
|
<option>end-listening-01</option>
|
|
<option>eye-default</option>
|
|
<option>Exclamation_00</option>
|
|
</optgroup>
|
|
<optgroup label="── Emoji (Classic)">
|
|
<option>Emoji_Airplane</option>
|
|
<option>Emoji_Ant</option>
|
|
<option>Emoji_Apple</option>
|
|
<option>Emoji_Art</option>
|
|
<option>Emoji_Baby</option>
|
|
<option>Emoji_Baseball</option>
|
|
<option>Emoji_Basketball</option>
|
|
<option>Emoji_Beer</option>
|
|
<option>Emoji_Bicycle</option>
|
|
<option>Emoji_Bird_Blue</option>
|
|
<option>Emoji_Book</option>
|
|
<option>Emoji_Bowling</option>
|
|
<option>Emoji_Boxing</option>
|
|
<option>Emoji_Brain</option>
|
|
<option>Emoji_Burger</option>
|
|
<option>Emoji_Cake</option>
|
|
<option>Emoji_Camera</option>
|
|
<option>Emoji_Car</option>
|
|
<option>Emoji_Cat</option>
|
|
<option>Emoji_Checkmark</option>
|
|
<option>Emoji_ChristmasTree</option>
|
|
<option>Emoji_Clap</option>
|
|
<option>Emoji_Coffee</option>
|
|
<option>Emoji_Computer</option>
|
|
<option>Emoji_Dog</option>
|
|
<option>Emoji_Drawing</option>
|
|
<option>Emoji_Earth</option>
|
|
<option>Emoji_ExclamationBlue</option>
|
|
<option>Emoji_ExclamationRed</option>
|
|
<option>Emoji_ExclamationYellow</option>
|
|
<option>Emoji_Fire</option>
|
|
<option>Emoji_Fireworks</option>
|
|
<option>Emoji_Fish</option>
|
|
<option>Emoji_Football</option>
|
|
<option>Emoji_Gift</option>
|
|
<option>Emoji_Golf</option>
|
|
<option>Emoji_Halo</option>
|
|
<option>Emoji_HeartArrow</option>
|
|
<option>Emoji_HeartBlue</option>
|
|
<option>Emoji_HeartRed</option>
|
|
<option>Emoji_Hockey</option>
|
|
<option>Emoji_Hotdog</option>
|
|
<option>Emoji_House</option>
|
|
<option>Emoji_IceCream</option>
|
|
<option>Emoji_Lightbulb</option>
|
|
<option>Emoji_LightningBolt</option>
|
|
<option>Emoji_Lock</option>
|
|
<option>Emoji_Lunch</option>
|
|
<option>Emoji_Magic</option>
|
|
<option>Emoji_Money</option>
|
|
<option>Emoji_Moon</option>
|
|
<option>Emoji_Mountain</option>
|
|
<option>Emoji_Music</option>
|
|
<option>Emoji_PartyBlue</option>
|
|
<option>Emoji_PartyPink</option>
|
|
<option>Emoji_Penguin</option>
|
|
<option>Emoji_Pizza</option>
|
|
<option>Emoji_Planet</option>
|
|
<option>Emoji_Question</option>
|
|
<option>Emoji_Rainbow</option>
|
|
<option>Emoji_Robot</option>
|
|
<option>Emoji_Rocket</option>
|
|
<option>Emoji_Running</option>
|
|
<option>Emoji_Santa</option>
|
|
<option>Emoji_Shark</option>
|
|
<option>Emoji_Snowflake</option>
|
|
<option>Emoji_Snowman</option>
|
|
<option>Emoji_Soccer</option>
|
|
<option>Emoji_Star</option>
|
|
<option>Emoji_Sun</option>
|
|
<option>Emoji_Sunglasses</option>
|
|
<option>Emoji_Sushi</option>
|
|
<option>Emoji_Taco</option>
|
|
<option>Emoji_Tennis</option>
|
|
<option>Emoji_ThumbsDown</option>
|
|
<option>Emoji_ThumbsUp</option>
|
|
<option>Emoji_Tools</option>
|
|
<option>Emoji_Tree</option>
|
|
<option>Emoji_Truck</option>
|
|
<option>Emoji_Umbrella</option>
|
|
<option>Emoji_VideoGame</option>
|
|
<option>Emoji_Watermelon</option>
|
|
<option>Emoji_Waving</option>
|
|
<option>Emoji_Whale</option>
|
|
<option>Emoji_Wine</option>
|
|
</optgroup>
|
|
<optgroup label="── Emoji (HF)">
|
|
<option>emoji-airplane-hf-01</option>
|
|
<option>emoji-alligator-hf-01</option>
|
|
<option>emoji-ant-hf-01</option>
|
|
<option>emoji-apple-red-hf-01</option>
|
|
<option>emoji-baby-hf-01</option>
|
|
<option>emoji-balloons-hf-01</option>
|
|
<option>emoji-bandaid-hf-01</option>
|
|
<option>emoji-baseball-hf-01</option>
|
|
<option>emoji-basketball-hf-01</option>
|
|
<option>emoji-beach-hf-01</option>
|
|
<option>emoji-beer-hf-01</option>
|
|
<option>emoji-bike-hf-01</option>
|
|
<option>emoji-bird-blue-hf-01</option>
|
|
<option>emoji-book-hf-01</option>
|
|
<option>emoji-bowling-hf-01</option>
|
|
<option>emoji-boxing-hf-01</option>
|
|
<option>emoji-breakfast-hf-01</option>
|
|
<option>emoji-broken-heart-hf-01</option>
|
|
<option>emoji-bunny-hf-01</option>
|
|
<option>emoji-burger-hf-01</option>
|
|
<option>emoji-cake-hf-01</option>
|
|
<option>emoji-camera-hf-01</option>
|
|
<option>emoji-car-hf-01</option>
|
|
<option>emoji-cat-hf-01</option>
|
|
<option>emoji-checkmark-hf-01</option>
|
|
<option>emoji-christmas-tree-hf-01</option>
|
|
<option>emoji-computer-chip-hf-01</option>
|
|
<option>emoji-cow-hf-01</option>
|
|
<option>emoji-diamond-hf-01</option>
|
|
<option>emoji-dinner-hf-01</option>
|
|
<option>emoji-disco-ball-hf-01</option>
|
|
<option>emoji-dog-hf-01</option>
|
|
<option>emoji-dress-hf-01</option>
|
|
<option>emoji-earth-hf-01</option>
|
|
<option>emoji-easter-egg-hf-01</option>
|
|
<option>emoji-elephant-hf-01</option>
|
|
<option>emoji-exclamation-mark-red-hf-01</option>
|
|
<option>emoji-exclamation-mark-yellow-hf-01</option>
|
|
<option>emoji-fire-hf-01</option>
|
|
<option>emoji-fish-hf-01</option>
|
|
<option>emoji-fishing-hf-01</option>
|
|
<option>emoji-flamingo-hf-01</option>
|
|
<option>emoji-flower-pink-hf-01</option>
|
|
<option>emoji-football-hf-01</option>
|
|
<option>emoji-ghost-hf-01</option>
|
|
<option>emoji-golf-hf-01</option>
|
|
<option>emoji-guitar-hf-01</option>
|
|
<option>emoji-halo-hf-01</option>
|
|
<option>emoji-hat-hf-01</option>
|
|
<option>emoji-heart-hf-01</option>
|
|
<option>emoji-hockey-hf-01</option>
|
|
<option>emoji-hot-dog-hf-01</option>
|
|
<option>emoji-house-hf-01</option>
|
|
<option>emoji-ice-cream-hf-01</option>
|
|
<option>emoji-ice-cube-hf-01</option>
|
|
<option>emoji-jack-o-lantern-hf-01</option>
|
|
<option>emoji-laptop-hf-01</option>
|
|
<option>emoji-light-bulb-hf-01</option>
|
|
<option>emoji-lightning-hf-01</option>
|
|
<option>emoji-lock-hf-01</option>
|
|
<option>emoji-magic-hf-01</option>
|
|
<option>emoji-magnifying-glass-hf-01</option>
|
|
<option>emoji-microphone-hf-01</option>
|
|
<option>emoji-money-hf-01</option>
|
|
<option>emoji-monkey-hf-01</option>
|
|
<option>emoji-moon-hf-01</option>
|
|
<option>emoji-mountains-hf-01</option>
|
|
<option>emoji-mouse-hf-01</option>
|
|
<option>emoji-music-hf-01</option>
|
|
<option>emoji-new-years-hf-01</option>
|
|
<option>emoji-ocean-hf-01</option>
|
|
<option>emoji-outlet-hf-01</option>
|
|
<option>emoji-pants-hf-01</option>
|
|
<option>emoji-party-hf-01</option>
|
|
<option>emoji-penguin-hf-01</option>
|
|
<option>emoji-phone-hf-01</option>
|
|
<option>emoji-pig-hf-01</option>
|
|
<option>emoji-pizza-hf-01</option>
|
|
<option>emoji-popcorn-hf-01</option>
|
|
<option>emoji-pretzel-hf-01</option>
|
|
<option>emoji-pumpkin-hf-01</option>
|
|
<option>emoji-puzzle-piece-hf-01</option>
|
|
<option>emoji-question-mark-hf-01</option>
|
|
<option>emoji-rainbow-hf-01</option>
|
|
<option>emoji-robot-hf-01</option>
|
|
<option>emoji-rocket-hf-01</option>
|
|
<option>emoji-running-hf-01</option>
|
|
<option>emoji-santa-hf-01</option>
|
|
<option>emoji-school-bus-hf-01</option>
|
|
<option>emoji-sheep-hf-01</option>
|
|
<option>emoji-shopping-hf-01</option>
|
|
<option>emoji-snorkel-hf-01</option>
|
|
<option>emoji-snowflake-hf-01</option>
|
|
<option>emoji-soccer-hf-01</option>
|
|
<option>emoji-star-hf-01</option>
|
|
<option>emoji-stork-hf-01</option>
|
|
<option>emoji-sun-hf-01</option>
|
|
<option>emoji-sushi-hf-01</option>
|
|
<option>emoji-taco-hf-01</option>
|
|
<option>emoji-tennis-hf-01</option>
|
|
<option>emoji-thunder-hf-01</option>
|
|
<option>emoji-toaster-hf-01</option>
|
|
<option>emoji-toilet-paper-hf-01</option>
|
|
<option>emoji-tools-hf-01</option>
|
|
<option>emoji-trash-can-hf-01</option>
|
|
<option>emoji-tree-hf-01</option>
|
|
<option>emoji-truck-hf-01</option>
|
|
<option>emoji-turtle-hf-01</option>
|
|
<option>emoji-tv-hf-01</option>
|
|
<option>emoji-umbrella-hf-01</option>
|
|
<option>emoji-watermelon-hf-01</option>
|
|
<option>emoji-whale-hf-01</option>
|
|
<option>emoji-wine-hf-01</option>
|
|
</optgroup>
|
|
</select>
|
|
</div>
|
|
<button id="btn-play-anim" style="width:100%;margin-bottom:10px;">▶ Play Animation</button>
|
|
|
|
<div class="section-title" style="margin-top:4px;">Display Text</div>
|
|
<div class="field">
|
|
<textarea id="display-text" rows="2" placeholder="Text to show on screen…"></textarea>
|
|
</div>
|
|
<button id="btn-display-text" style="width:100%;margin-bottom:10px;">Show Text</button>
|
|
|
|
<div class="section-title">Display Image</div>
|
|
<div class="field">
|
|
<input type="text" id="display-img-src" placeholder="http://… image URL">
|
|
</div>
|
|
<button id="btn-display-image" style="width:100%;">Show Image</button>
|
|
|
|
</div>
|
|
|
|
<!-- Entities tab -->
|
|
<div class="tab-panel" id="tab-entities">
|
|
<div class="section-title">Detected Entities</div>
|
|
<div id="entity-list"><div style="color:var(--muted);font-size:12px;">Waiting for entity events…</div></div>
|
|
<div class="section-title" style="margin-top:12px;">Head Touch</div>
|
|
<div id="head-touch-display" style="display:grid;grid-template-columns:repeat(3,1fr);gap:4px;">
|
|
<div class="pad-indicator" data-pad="frontLeft">FL</div>
|
|
<div class="pad-indicator" data-pad="middleLeft">ML</div>
|
|
<div class="pad-indicator" data-pad="backLeft">BL</div>
|
|
<div class="pad-indicator" data-pad="frontRight">FR</div>
|
|
<div class="pad-indicator" data-pad="middleRight">MR</div>
|
|
<div class="pad-indicator" data-pad="backRight">BR</div>
|
|
</div>
|
|
<style>
|
|
.pad-indicator {
|
|
background: var(--surface2); border: 1px solid var(--border);
|
|
border-radius: 4px; padding: 6px; text-align: center;
|
|
font-size: 11px; color: var(--muted); transition: all 0.2s;
|
|
}
|
|
.pad-indicator.active { background: var(--accent); color: #000; border-color: var(--accent); }
|
|
</style>
|
|
</div>
|
|
|
|
<!-- Log tab -->
|
|
<div class="tab-panel" id="tab-log" style="padding:0;display:flex;flex-direction:column;flex:1;">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;padding:8px 10px;border-bottom:1px solid var(--border);">
|
|
<span class="section-title" style="margin:0;">Event Log</span>
|
|
<button id="btn-clear-log" style="font-size:11px;padding:3px 8px;">Clear</button>
|
|
</div>
|
|
<div id="event-log"></div>
|
|
</div>
|
|
|
|
</div><!-- /right-panel -->
|
|
</div>
|
|
|
|
<!-- Photo modal -->
|
|
<div id="photo-modal">
|
|
<div id="photo-modal-close">✕</div>
|
|
<img id="photo-modal-img" src="" alt="Photo">
|
|
</div>
|
|
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|