youkii-xr commited on
Commit
004bb8f
ยท
verified ยท
1 Parent(s): eb337ce

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +153 -142
app.py CHANGED
@@ -23,24 +23,20 @@ except Exception as e:
23
  print(f"Error: {e}")
24
  model = None
25
 
26
- # --- 2. LOGIC: DETECTION & REPORTING ---
27
  def generate_human_report(detections, counts):
28
- """Generates a natural language summary of the findings."""
29
  if not detections:
30
  return "The Eye of Horus sees no intelligible glyphs in this image."
31
 
32
  total = len(detections)
33
- # Sort counts by frequency
34
  sorted_counts = sorted(counts.items(), key=lambda item: item[1], reverse=True)
35
 
36
  report = f"๐Ÿ”Ž ANALYSIS COMPLETE\n"
37
  report += f"-----------------------------------\n"
38
  report += f"Total Glyphs Detected: {total}\n\n"
39
  report += "๐Ÿ“ SYMBOL INVENTORY:\n"
40
-
41
  for code, count in sorted_counts:
42
  report += f"โ€ข Gardiner Code '{code}': {count} instance(s)\n"
43
-
44
  report += f"\n-----------------------------------\n"
45
  report += f"CONFIDENCE ASSESSMENT: High\n"
46
  report += f"TRANSLATION STATUS: Ready for context analysis."
@@ -55,11 +51,9 @@ def detect_hieroglyphs(image: Image.Image, conf_threshold: float = 0.25):
55
  try:
56
  results = model.predict(source=image, conf=conf_threshold, iou=0.45, imgsz=640, verbose=False, device='cpu', max_det=300)
57
 
58
- # 1. Visual
59
  annotated_array = results[0].plot()
60
  annotated_image = Image.fromarray(annotated_array[..., ::-1])
61
 
62
- # 2. Data
63
  detections = []
64
  gardiner_counts = {}
65
 
@@ -79,101 +73,147 @@ def detect_hieroglyphs(image: Image.Image, conf_threshold: float = 0.25):
79
  "counts": gardiner_counts
80
  }
81
 
82
- # 3. Text Report
83
  text_report = generate_human_report(detections, gardiner_counts)
84
-
85
  return annotated_image, summary_json, text_report
86
 
87
  except Exception as e:
88
  return None, {"error": str(e)}, f"Critical Error: {str(e)}"
89
 
90
- # --- 3. UI STYLING (EGYPTIAN NIGHT) ---
91
- custom_css = """
 
 
 
 
 
92
  @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&display=swap');
93
  @import url('https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap');
94
 
95
- :root {
96
- --body-background-fill: #050510 !important;
97
- --background-fill-primary: #0a0f1e !important;
98
- --border-color-primary: #d4af37 !important;
99
- --text-body: #e0e7ff !important;
100
- --gold-glow: 0 0 15px rgba(212, 175, 55, 0.3);
101
- }
102
-
103
- body, .gradio-container {
104
- background: radial-gradient(circle at 50% 0%, #1a1f35 0%, #050510 100%) !important;
105
- font-family: 'Cinzel', serif !important;
106
- }
107
-
108
- /* CARDS */
109
- .card {
110
- background: rgba(10, 15, 30, 0.7) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  border: 1px solid rgba(212, 175, 55, 0.3) !important;
112
  border-radius: 15px;
113
  padding: 20px;
114
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
115
  backdrop-filter: blur(10px);
116
  margin-bottom: 20px;
117
- }
118
- .card-title {
 
 
 
 
 
 
 
 
 
119
  font-size: 16px;
120
  font-weight: 700;
121
- color: #d4af37;
122
  text-transform: uppercase;
123
  letter-spacing: 2px;
124
  border-bottom: 1px solid rgba(212, 175, 55, 0.2);
125
  padding-bottom: 8px;
126
  margin-bottom: 15px;
127
- }
128
 
129
- /* BUTTONS */
130
- button.primary-btn {
131
  background: linear-gradient(135deg, #b8860b 0%, #d4af37 100%) !important;
132
  border: 1px solid #ffd700 !important;
133
- color: #000 !important;
134
  font-weight: bold !important;
135
  font-family: 'Cinzel', serif !important;
136
  text-transform: uppercase;
137
  letter-spacing: 1px;
138
- box-shadow: var(--gold-glow);
139
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
  /* REPORT TEXTBOX */
142
- .report-box textarea {
143
- background-color: #1a1a25 !important;
144
- border: 1px solid #d4af37 !important;
145
  font-family: 'Courier Prime', monospace !important;
146
- color: #d4af37 !important;
147
- font-size: 14px !important;
148
- }
149
-
150
- /* JSON CONFIG BOX */
151
- .config-box {
152
- background-color: #111 !important;
153
- border: 1px solid #444 !important;
154
- font-family: 'Courier Prime', monospace !important;
155
- padding: 15px;
156
- border-radius: 8px;
157
- color: #0f0;
158
- font-size: 12px;
159
- overflow-x: auto;
160
- }
161
-
162
- /* CLEANUP */
163
- .gradio-image, .gradio-json { background: transparent !important; border: none !important; }
164
  """
165
 
166
- # HTML COMPONENTS
167
  header_html = """
168
  <div style="display: flex; align-items: center; gap: 20px; padding: 20px 0;">
169
- <svg width="50" height="50" viewBox="0 0 100 100" fill="none">
170
- <path d="M10,50 Q50,10 90,50 Q50,90 10,50" stroke="#d4af37" stroke-width="3" fill="none"/>
171
- <circle cx="50" cy="50" r="15" fill="#d4af37"/>
172
- <path d="M50,65 L50,90 L30,90" stroke="#d4af37" stroke-width="3" fill="none"/>
173
- </svg>
174
  <div>
175
- <h1 style="margin: 0; font-size: 32px; color: #d4af37;">HORUS VISION</h1>
176
- <p style="margin: 0; color: #a5b4fc; font-size: 12px; letter-spacing: 2px;">HIEROGLYPHIC TRANSLATION & PRESERVATION</p>
177
  </div>
178
  </div>
179
  """
@@ -181,34 +221,45 @@ header_html = """
181
  mission_html = """
182
  <div class="card">
183
  <div class="card-title">๐Ÿ“œ THE MISSION</div>
184
- <p style="color: #ccc; font-size: 14px; line-height: 1.6;">
185
  <b>To preserve the past is to save the future.</b><br>
186
- This tool is part of a larger initiative to digitize and translate Ancient Egyptian inscriptions.
187
- Using YOLOv8, we identify Gardiner codes instantly, bridging the gap between stone artifacts and modern understanding.
188
  </p>
189
  </div>
190
  """
191
 
192
- claude_guide_html = """
193
- <div class="card" style="border-color: #ff6b6b;">
194
- <div class="card-title" style="color: #ff6b6b;">๐Ÿค– CLAUDE DESKTOP INTEGRATION GUIDE</div>
 
195
 
196
- <div style="background: rgba(255, 107, 107, 0.1); border-left: 4px solid #ff6b6b; padding: 10px; margin-bottom: 15px;">
197
- <strong style="color: #ff6b6b;">โš ๏ธ IMPORTANT:</strong>
198
- Do <b>NOT</b> drag and drop images directly into Claude Desktop. The local server cannot see them.
199
- You must place images in the dedicated folder created below.
 
 
 
 
 
 
 
 
 
 
 
200
  </div>
201
 
202
- <div style="color: #ddd; font-size: 14px; line-height: 1.8;">
203
- <b>Step 1:</b> Create a folder on your computer: <code style="background:#333; padding:2px;">C:\\Claude_Work</code><br>
204
- <b>Step 2:</b> Place your hieroglyph images inside that folder.<br>
205
- <b>Step 3:</b> Open your Claude Desktop Config file (usually <code>%APPDATA%\\Claude\\claude_desktop_config.json</code>).<br>
206
- <b>Step 4:</b> Paste the configuration below inside the <code>"mcpServers"</code> block.<br>
207
- <b>Step 5:</b> Restart Claude Desktop.
208
  </div>
209
- <br>
210
- <div class="config-box">
211
- {
212
  "mcpServers": {
213
  "gradio": {
214
  "command": "npx",
@@ -230,89 +281,49 @@ claude_guide_html = """
230
  ]
231
  }
232
  }
233
- }
234
- </div>
235
- <p style="color: #888; font-size: 12px; margin-top: 10px;">
236
- *Note: Check that 'C:\\Python313\\python.exe' matches your actual Python installation path.
237
- </p>
238
- </div>
239
- """
240
 
241
- # --- 4. MAIN APPLICATION ---
242
- with gr.Blocks(title="Horus Vision") as demo:
 
243
  gr.HTML(f"<style>{custom_css}</style>")
 
 
244
  gr.HTML(header_html)
245
  gr.HTML(mission_html)
246
 
247
- # --- WORKSPACE AREA ---
248
  with gr.Row():
249
-
250
- # LEFT COLUMN: INPUTS (Now with Tabs)
251
  with gr.Column(scale=1):
252
  gr.HTML('<div class="card"><div class="card-title">SOURCE ARTIFACT</div>')
253
-
254
  with gr.Tabs():
255
- # TAB 1: UPLOAD
256
  with gr.TabItem("๐Ÿ“œ Upload Scroll"):
257
- img_upload = gr.Image(
258
- type="pil",
259
- sources=["upload", "clipboard"],
260
- label="Upload Image",
261
- height=300
262
- )
263
  slider_upload = gr.Slider(0.1, 1.0, 0.25, label="Confidence")
264
  btn_upload = gr.Button("๐Ÿ”ฎ DECIPHER SCROLL", elem_classes="primary-btn")
265
 
266
- # TAB 2: CAMERA
267
  with gr.TabItem("๐Ÿ‘๏ธ Divine Sight"):
268
- img_cam = gr.Image(
269
- type="pil",
270
- sources=["webcam"],
271
- label="Camera Input",
272
- height=300
273
- )
274
  slider_cam = gr.Slider(0.1, 1.0, 0.25, label="Confidence")
275
  btn_cam = gr.Button("๐Ÿ”ฎ DECIPHER VISION", elem_classes="primary-btn")
276
-
277
  gr.HTML('</div>')
278
 
279
- # RIGHT COLUMN: OUTPUTS
280
  with gr.Column(scale=1):
281
  gr.HTML('<div class="card"><div class="card-title">INTERPRETATION</div>')
282
-
283
- # The Annotated Image
284
  out_image = gr.Image(label="Annotated Artifact", interactive=False)
285
-
286
- # The Human Readable Summary
287
- out_report = gr.Textbox(
288
- label="Scribe's Report",
289
- lines=6,
290
- elem_classes="report-box",
291
- placeholder="Analysis results will appear here..."
292
- )
293
-
294
- # The Raw JSON (Collapsed by default ideally, but standard here)
295
  with gr.Accordion("Raw Glyph Data (JSON)", open=False):
296
  out_json = gr.JSON(label="JSON Data")
297
-
298
  gr.HTML('</div>')
299
 
300
- # --- CLAUDE GUIDE FOOTER ---
301
- gr.HTML(claude_guide_html)
 
 
302
 
303
- # --- WIRING ---
304
- # We bind both buttons to the same function, targeting the same outputs
305
- btn_upload.click(
306
- fn=detect_hieroglyphs,
307
- inputs=[img_upload, slider_upload],
308
- outputs=[out_image, out_json, out_report]
309
- )
310
-
311
- btn_cam.click(
312
- fn=detect_hieroglyphs,
313
- inputs=[img_cam, slider_cam],
314
- outputs=[out_image, out_json, out_report]
315
- )
316
 
317
  if __name__ == "__main__":
318
  demo.launch(mcp_server=True, ssr_mode=False, allowed_paths=["/tmp"])
 
23
  print(f"Error: {e}")
24
  model = None
25
 
26
+ # --- 2. LOGIC ---
27
  def generate_human_report(detections, counts):
 
28
  if not detections:
29
  return "The Eye of Horus sees no intelligible glyphs in this image."
30
 
31
  total = len(detections)
 
32
  sorted_counts = sorted(counts.items(), key=lambda item: item[1], reverse=True)
33
 
34
  report = f"๐Ÿ”Ž ANALYSIS COMPLETE\n"
35
  report += f"-----------------------------------\n"
36
  report += f"Total Glyphs Detected: {total}\n\n"
37
  report += "๐Ÿ“ SYMBOL INVENTORY:\n"
 
38
  for code, count in sorted_counts:
39
  report += f"โ€ข Gardiner Code '{code}': {count} instance(s)\n"
 
40
  report += f"\n-----------------------------------\n"
41
  report += f"CONFIDENCE ASSESSMENT: High\n"
42
  report += f"TRANSLATION STATUS: Ready for context analysis."
 
51
  try:
52
  results = model.predict(source=image, conf=conf_threshold, iou=0.45, imgsz=640, verbose=False, device='cpu', max_det=300)
53
 
 
54
  annotated_array = results[0].plot()
55
  annotated_image = Image.fromarray(annotated_array[..., ::-1])
56
 
 
57
  detections = []
58
  gardiner_counts = {}
59
 
 
73
  "counts": gardiner_counts
74
  }
75
 
 
76
  text_report = generate_human_report(detections, gardiner_counts)
 
77
  return annotated_image, summary_json, text_report
78
 
79
  except Exception as e:
80
  return None, {"error": str(e)}, f"Critical Error: {str(e)}"
81
 
82
+ # --- 3. THE MYSTICAL UI (CSS) ---
83
+ # We use CSS Variables (--name) to handle Light/Dark mode switching automatically.
84
+
85
+ # Base64 SVG Cursor (Eye of Horus)
86
+ cursor_url = "url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8ZyBmaWxsPSJub25lIiBzdHJva2U9IiNkNGFmMzciIHN0cm9rZS13aWR0aD0iMiI+CiAgICA8cGF0aCBkPSZNMTYsOCBDNiwyMCAyNiwyMCAxNiw4IFoiIGZpbGw9InJnYmEoMjEyLCAxNzUsIDU1LqmAuMykiLz4KICAgIDxjaXJjbGUgY3g9IjE2IiBjeT0iMTUiIHI9IjMiIGZpbGw9IiNkNGFmMzciLz4KICAgIDxwYXRoIGQ9Ik0xNiwyMiBMMTYsMjggTDEwLDI4Ii8+CiAgPC9nPgo8L3N2Zz4=')"
87
+
88
+ custom_css = f"""
89
  @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&display=swap');
90
  @import url('https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap');
91
 
92
+ /* --- 1. THEME VARIABLES (DAY vs NIGHT) --- */
93
+ :root {{
94
+ /* LIGHT MODE (PAPYRUS DAY) */
95
+ --bg-gradient: linear-gradient(135deg, #fdf6e3 0%, #f5e6d3 100%);
96
+ --card-bg: rgba(255, 255, 255, 0.6);
97
+ --text-primary: #5c4033; /* Dark Brown */
98
+ --text-accent: #b8860b; /* Dark Gold */
99
+ --border-color: #d4af37;
100
+ --highlight-bg: rgba(212, 175, 55, 0.1);
101
+ --warning-bg: rgba(255, 0, 0, 0.05);
102
+ --warning-border: #cc0000;
103
+ }}
104
+
105
+ .dark {{
106
+ /* DARK MODE (EGYPTIAN NIGHT) */
107
+ --bg-gradient: radial-gradient(circle at 50% 0%, #1a1f35 0%, #050510 100%);
108
+ --card-bg: rgba(10, 15, 30, 0.7);
109
+ --text-primary: #e0e7ff; /* Light Blue */
110
+ --text-accent: #ffd700; /* Bright Gold */
111
+ --border-color: #d4af37;
112
+ --highlight-bg: rgba(212, 175, 55, 0.1);
113
+ --warning-bg: rgba(255, 99, 71, 0.1);
114
+ --warning-border: #ff6b6b;
115
+ }}
116
+
117
+ /* --- 2. GLOBAL STYLES --- */
118
+ body, .gradio-container {{
119
+ background: var(--bg-gradient) !important;
120
+ font-family: 'Cinzel', serif !important;
121
+ color: var(--text-primary) !important;
122
+ /* MYSTICAL CURSOR */
123
+ cursor: {cursor_url} 16 16, auto !important;
124
+ }}
125
+
126
+ /* BUTTONS & LINKS CURSOR OVERRIDE */
127
+ button, a, .cursor-pointer {{
128
+ cursor: {cursor_url} 16 16, pointer !important;
129
+ }}
130
+
131
+ /* --- 3. ANIMATED CARDS --- */
132
+ .card {{
133
+ background: var(--card-bg) !important;
134
  border: 1px solid rgba(212, 175, 55, 0.3) !important;
135
  border-radius: 15px;
136
  padding: 20px;
137
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
138
  backdrop-filter: blur(10px);
139
  margin-bottom: 20px;
140
+ transition: all 0.4s ease; /* Animation Speed */
141
+ }}
142
+
143
+ /* HOVER ANIMATION: Glow and Lift */
144
+ .card:hover {{
145
+ transform: translateY(-5px);
146
+ border-color: var(--border-color) !important;
147
+ box-shadow: 0 0 20px rgba(212, 175, 55, 0.4), inset 0 0 10px rgba(212, 175, 55, 0.1);
148
+ }}
149
+
150
+ .card-title {{
151
  font-size: 16px;
152
  font-weight: 700;
153
+ color: var(--text-accent);
154
  text-transform: uppercase;
155
  letter-spacing: 2px;
156
  border-bottom: 1px solid rgba(212, 175, 55, 0.2);
157
  padding-bottom: 8px;
158
  margin-bottom: 15px;
159
+ }}
160
 
161
+ /* --- 4. BUTTONS --- */
162
+ button.primary-btn {{
163
  background: linear-gradient(135deg, #b8860b 0%, #d4af37 100%) !important;
164
  border: 1px solid #ffd700 !important;
165
+ color: #fff !important;
166
  font-weight: bold !important;
167
  font-family: 'Cinzel', serif !important;
168
  text-transform: uppercase;
169
  letter-spacing: 1px;
170
+ transition: all 0.3s ease;
171
+ }}
172
+
173
+ button.primary-btn:hover {{
174
+ transform: scale(1.02);
175
+ box-shadow: 0 0 25px rgba(212, 175, 55, 0.6);
176
+ }}
177
+
178
+ /* --- 5. IMPORTANT NOTES HIGHLIGHTING --- */
179
+ .warning-box {{
180
+ background-color: var(--warning-bg);
181
+ border-left: 5px solid var(--warning-border);
182
+ padding: 15px;
183
+ margin: 10px 0;
184
+ border-radius: 0 10px 10px 0;
185
+ font-family: 'Courier Prime', monospace; /* Monospace for tech look */
186
+ font-size: 13px;
187
+ }}
188
+
189
+ .highlight-path {{
190
+ background-color: rgba(255, 255, 255, 0.1);
191
+ border: 1px dashed var(--border-color);
192
+ padding: 2px 6px;
193
+ border-radius: 4px;
194
+ color: var(--text-accent);
195
+ font-weight: bold;
196
+ }}
197
 
198
  /* REPORT TEXTBOX */
199
+ .report-box textarea {{
200
+ background-color: rgba(0,0,0,0.2) !important;
201
+ border: 1px solid var(--border-color) !important;
202
  font-family: 'Courier Prime', monospace !important;
203
+ color: var(--text-accent) !important;
204
+ }}
205
+
206
+ /* REMOVE DEFAULT GRADIO BORDERS */
207
+ .gradio-image, .gradio-json {{ background: transparent !important; border: none !important; }}
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  """
209
 
210
+ # HTML HEADER
211
  header_html = """
212
  <div style="display: flex; align-items: center; gap: 20px; padding: 20px 0;">
213
+ <div style="font-size: 50px;">๐Ÿ‘๏ธ</div>
 
 
 
 
214
  <div>
215
+ <h1 style="margin: 0; font-size: 32px; color: var(--text-accent);">HORUS VISION</h1>
216
+ <p style="margin: 0; opacity: 0.8; font-size: 12px; letter-spacing: 2px;">HIEROGLYPHIC TRANSLATION & PRESERVATION</p>
217
  </div>
218
  </div>
219
  """
 
221
  mission_html = """
222
  <div class="card">
223
  <div class="card-title">๐Ÿ“œ THE MISSION</div>
224
+ <p style="opacity: 0.9; font-size: 14px; line-height: 1.6;">
225
  <b>To preserve the past is to save the future.</b><br>
226
+ This tool uses AI to digitize Ancient Egyptian inscriptions.
227
+ <span style="font-size:12px; float:right;">(Hover over cards to see the aura)</span>
228
  </p>
229
  </div>
230
  """
231
 
232
+ # NEW DETAILED INSTRUCTIONS HTML
233
+ guide_instructions_html = """
234
+ <div class="card" style="border-color: var(--warning-border) !important;">
235
+ <div class="card-title" style="color: var(--warning-border);">๐Ÿค– CLAUDE DESKTOP INTEGRATION GUIDE</div>
236
 
237
+ <div class="warning-box">
238
+ <strong style="font-size:14px; display:block; margin-bottom:5px;">โš ๏ธ CRITICAL: IMAGE PLACEMENT</strong>
239
+ Claude Desktop cannot see your entire computer. It is sandboxed.<br><br>
240
+ 1. You <b>MUST</b> create this exact folder: <span class="highlight-path">C:\\Claude_Work</span><br>
241
+ 2. Place your images <b>INSIDE</b> this folder.<br>
242
+ 3. Do <b>NOT</b> drag-and-drop images into Claude. Instead, type:
243
+ <i>"Analyze the image at C:\\Claude_Work\\papyrus.jpg"</i>
244
+ </div>
245
+
246
+ <div class="warning-box" style="border-color: var(--text-accent);">
247
+ <strong style="font-size:14px; display:block; margin-bottom:5px;">๐Ÿ CRITICAL: CHECK PYTHON PATH</strong>
248
+ The config below assumes your Python is at <code>C:\\Python313\\python.exe</code>.<br><br>
249
+ If you installed Python normally, it might be in a hidden User folder.<br>
250
+ <b>How to check:</b> Open CMD or PowerShell and type <code>where python</code>.<br>
251
+ <b>Action:</b> If the path is different, copy the path from CMD and replace it in the JSON below.
252
  </div>
253
 
254
+ <div style="margin-top: 15px; opacity: 0.9;">
255
+ <b>Step-by-Step Setup:</b><br>
256
+ 1. Open your Config file: <code>%APPDATA%\\Claude\\claude_desktop_config.json</code><br>
257
+ 2. Paste the code block below.<br>
258
+ 3. <b>Fully Quit</b> Claude (Right-click Icon in Tray -> Quit) and restart.
 
259
  </div>
260
+ """
261
+
262
+ claude_json_content = """{
263
  "mcpServers": {
264
  "gradio": {
265
  "command": "npx",
 
281
  ]
282
  }
283
  }
284
+ }"""
 
 
 
 
 
 
285
 
286
+ # --- 4. MAIN APP ---
287
+ with gr.Blocks(title="Horus Vision", theme=gr.themes.Default()) as demo:
288
+ # Inject CSS
289
  gr.HTML(f"<style>{custom_css}</style>")
290
+
291
+ # Header
292
  gr.HTML(header_html)
293
  gr.HTML(mission_html)
294
 
295
+ # Workspace
296
  with gr.Row():
 
 
297
  with gr.Column(scale=1):
298
  gr.HTML('<div class="card"><div class="card-title">SOURCE ARTIFACT</div>')
 
299
  with gr.Tabs():
 
300
  with gr.TabItem("๐Ÿ“œ Upload Scroll"):
301
+ img_upload = gr.Image(type="pil", sources=["upload", "clipboard"], label="Upload", height=300)
 
 
 
 
 
302
  slider_upload = gr.Slider(0.1, 1.0, 0.25, label="Confidence")
303
  btn_upload = gr.Button("๐Ÿ”ฎ DECIPHER SCROLL", elem_classes="primary-btn")
304
 
 
305
  with gr.TabItem("๐Ÿ‘๏ธ Divine Sight"):
306
+ img_cam = gr.Image(type="pil", sources=["webcam"], label="Camera", height=300)
 
 
 
 
 
307
  slider_cam = gr.Slider(0.1, 1.0, 0.25, label="Confidence")
308
  btn_cam = gr.Button("๐Ÿ”ฎ DECIPHER VISION", elem_classes="primary-btn")
 
309
  gr.HTML('</div>')
310
 
 
311
  with gr.Column(scale=1):
312
  gr.HTML('<div class="card"><div class="card-title">INTERPRETATION</div>')
 
 
313
  out_image = gr.Image(label="Annotated Artifact", interactive=False)
314
+ out_report = gr.Textbox(label="Scribe's Report", lines=6, elem_classes="report-box", placeholder="Awaiting input...")
 
 
 
 
 
 
 
 
 
315
  with gr.Accordion("Raw Glyph Data (JSON)", open=False):
316
  out_json = gr.JSON(label="JSON Data")
 
317
  gr.HTML('</div>')
318
 
319
+ # Config Section
320
+ gr.HTML(guide_instructions_html)
321
+ gr.Code(value=claude_json_content, language="json", label="claude_desktop_config.json", interactive=False, lines=15)
322
+ gr.HTML("</div>")
323
 
324
+ # Wiring
325
+ btn_upload.click(fn=detect_hieroglyphs, inputs=[img_upload, slider_upload], outputs=[out_image, out_json, out_report])
326
+ btn_cam.click(fn=detect_hieroglyphs, inputs=[img_cam, slider_cam], outputs=[out_image, out_json, out_report])
 
 
 
 
 
 
 
 
 
 
327
 
328
  if __name__ == "__main__":
329
  demo.launch(mcp_server=True, ssr_mode=False, allowed_paths=["/tmp"])