Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -177,7 +177,6 @@ def infer(
|
|
| 177 |
|
| 178 |
# --- FastAPI Endpoints ---
|
| 179 |
def get_example_items():
|
| 180 |
-
# Defined exactly to support single and multi-image examples.
|
| 181 |
return [
|
| 182 |
{
|
| 183 |
"urls": ["/example-file/I1.jpg", "/example-file/I2.jpg"],
|
|
@@ -345,8 +344,8 @@ async def homepage(request: Request):
|
|
| 345 |
display: grid;
|
| 346 |
grid-template-columns: 420px 1fr;
|
| 347 |
gap: 24px;
|
| 348 |
-
align-items: stretch;
|
| 349 |
-
height: 650px;
|
| 350 |
}}
|
| 351 |
|
| 352 |
.panel {{
|
|
@@ -365,10 +364,9 @@ async def homepage(request: Request):
|
|
| 365 |
border-bottom: 1px solid var(--ub-border);
|
| 366 |
font-weight: 500;
|
| 367 |
font-size: 1.1rem;
|
| 368 |
-
flex-shrink: 0;
|
| 369 |
}}
|
| 370 |
|
| 371 |
-
/* Scrollable inner body for Settings */
|
| 372 |
.panel-body-scroll {{
|
| 373 |
flex: 1;
|
| 374 |
padding: 20px;
|
|
@@ -441,30 +439,73 @@ async def homepage(request: Request):
|
|
| 441 |
|
| 442 |
/* The (+) Button */
|
| 443 |
.add-more-btn {{
|
| 444 |
-
display: flex;
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
border-radius: 4px;
|
| 449 |
-
color: var(--ub-muted);
|
| 450 |
-
font-size: 26px;
|
| 451 |
-
cursor: pointer;
|
| 452 |
-
aspect-ratio: 1;
|
| 453 |
-
transition: all 0.2s;
|
| 454 |
-
background: transparent;
|
| 455 |
}}
|
| 456 |
.add-more-btn:hover {{
|
| 457 |
-
border-color: var(--ub-orange);
|
| 458 |
-
color: var(--ub-orange);
|
| 459 |
background: rgba(233,84,32,0.05);
|
| 460 |
}}
|
| 461 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
/* Buttons */
|
| 463 |
.btn {{
|
| 464 |
width: 100%; padding: 14px; border: none; border-radius: 4px;
|
| 465 |
font-size: 16px; font-weight: 700; cursor: pointer;
|
| 466 |
transition: opacity 0.2s, background 0.2s;
|
| 467 |
-
margin-top: auto; /* Pushes button to bottom if space exists */
|
| 468 |
flex-shrink: 0;
|
| 469 |
}}
|
| 470 |
.btn-primary {{
|
|
@@ -474,24 +515,12 @@ async def homepage(request: Request):
|
|
| 474 |
.btn-primary:hover {{ background: var(--ub-orange-hover); }}
|
| 475 |
.btn:disabled {{ opacity: 0.6; cursor: not-allowed; }}
|
| 476 |
|
| 477 |
-
/* Advanced Accordion (+/-) */
|
| 478 |
-
.advanced-toggle {{
|
| 479 |
-
width: 100%; background: none; border: none; color: var(--ub-orange);
|
| 480 |
-
text-align: left; padding: 10px 0; font-weight: 500; cursor: pointer;
|
| 481 |
-
display: flex; justify-content: space-between; align-items: center;
|
| 482 |
-
flex-shrink: 0;
|
| 483 |
-
}}
|
| 484 |
-
.advanced-icon {{ font-weight: bold; font-size: 18px; line-height: 1; }}
|
| 485 |
-
.advanced-body {{ display: none; padding-top: 10px; flex-shrink: 0; }}
|
| 486 |
-
.advanced-body.open {{ display: block; }}
|
| 487 |
-
.grid-2 {{ display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }}
|
| 488 |
-
|
| 489 |
/* SLIDER CONTAINER */
|
| 490 |
.panel-body-slider {{
|
| 491 |
flex: 1;
|
| 492 |
display: flex;
|
| 493 |
flex-direction: column;
|
| 494 |
-
padding: 0;
|
| 495 |
position: relative;
|
| 496 |
}}
|
| 497 |
.slider-stage {{
|
|
@@ -503,80 +532,48 @@ async def homepage(request: Request):
|
|
| 503 |
align-items: center;
|
| 504 |
justify-content: center;
|
| 505 |
}}
|
| 506 |
-
.slider-empty {{
|
| 507 |
-
color: var(--ub-muted);
|
| 508 |
-
text-align: center;
|
| 509 |
-
z-index: 1;
|
| 510 |
-
}}
|
| 511 |
|
| 512 |
.slider-img {{
|
| 513 |
-
position: absolute;
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
object-fit: contain;
|
| 517 |
-
display: none;
|
| 518 |
-
user-select: none;
|
| 519 |
-
-webkit-user-drag: none;
|
| 520 |
}}
|
| 521 |
-
|
| 522 |
-
/* The Small Decoder image sits on top and gets clipped */
|
| 523 |
#imgSmall {{ clip-path: inset(0 50% 0 0); }}
|
| 524 |
|
| 525 |
.slider-handle {{
|
| 526 |
-
position: absolute;
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
width: 4px;
|
| 530 |
-
background: var(--ub-orange);
|
| 531 |
-
cursor: ew-resize;
|
| 532 |
-
display: none;
|
| 533 |
-
z-index: 10;
|
| 534 |
}}
|
| 535 |
.slider-handle::after {{
|
| 536 |
-
content: '◀ ▶';
|
| 537 |
-
position: absolute;
|
| 538 |
-
top: 50%; left: 50%;
|
| 539 |
transform: translate(-50%, -50%);
|
| 540 |
-
width: 40px; height: 30px;
|
| 541 |
-
|
| 542 |
-
color: white;
|
| 543 |
-
border-radius: 15px;
|
| 544 |
display: flex; align-items: center; justify-content: center;
|
| 545 |
-
font-size: 10px; font-weight: bold;
|
| 546 |
-
box-shadow: 0 2px 6px rgba(0,0,0,0.5);
|
| 547 |
}}
|
| 548 |
|
| 549 |
.slider-labels {{
|
| 550 |
-
position: absolute;
|
| 551 |
-
|
| 552 |
-
|
| 553 |
-
justify-content: space-between;
|
| 554 |
-
pointer-events: none;
|
| 555 |
-
z-index: 5;
|
| 556 |
}}
|
| 557 |
.badge {{
|
| 558 |
-
background: rgba(0,0,0,0.6);
|
| 559 |
-
|
| 560 |
-
padding: 6px 12px;
|
| 561 |
-
border-radius: 20px;
|
| 562 |
-
font-size: 13px;
|
| 563 |
-
backdrop-filter: blur(4px);
|
| 564 |
}}
|
| 565 |
|
| 566 |
.loader {{
|
| 567 |
-
position: absolute; inset: 0;
|
| 568 |
-
background: rgba(0,0,0,0.7);
|
| 569 |
display: none; flex-direction: column;
|
| 570 |
-
align-items: center; justify-content: center;
|
| 571 |
-
z-index: 20;
|
| 572 |
}}
|
| 573 |
.spinner {{
|
| 574 |
-
width: 40px; height: 40px;
|
| 575 |
-
border:
|
| 576 |
-
|
| 577 |
-
border-radius: 50%;
|
| 578 |
-
animation: spin 1s linear infinite;
|
| 579 |
-
margin-bottom: 15px;
|
| 580 |
}}
|
| 581 |
|
| 582 |
/* Examples */
|
|
@@ -591,14 +588,8 @@ async def homepage(request: Request):
|
|
| 591 |
}}
|
| 592 |
.ex-card:hover {{ transform: translateY(-3px); box-shadow: 0 6px 16px rgba(0,0,0,0.3); }}
|
| 593 |
|
| 594 |
-
.ex-card-img-wrap {{
|
| 595 |
-
|
| 596 |
-
display: flex; background: #000;
|
| 597 |
-
}}
|
| 598 |
-
.ex-card-img-wrap img {{
|
| 599 |
-
height: 100%; object-fit: cover;
|
| 600 |
-
}}
|
| 601 |
-
|
| 602 |
.ex-card p {{ padding: 12px; margin: 0; font-size: 13px; color: var(--ub-muted); line-height: 1.4; }}
|
| 603 |
|
| 604 |
@keyframes spin {{ to {{ transform: rotate(360deg); }} }}
|
|
@@ -672,8 +663,14 @@ async def homepage(request: Request):
|
|
| 672 |
</div>
|
| 673 |
</div>
|
| 674 |
|
| 675 |
-
<div
|
| 676 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 677 |
</div>
|
| 678 |
</div>
|
| 679 |
|
|
@@ -725,6 +722,17 @@ async def homepage(request: Request):
|
|
| 725 |
const promptInput = document.getElementById('promptInput');
|
| 726 |
const runBtn = document.getElementById('runBtn');
|
| 727 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 728 |
// Slider Elements
|
| 729 |
const sliderStage = document.getElementById('sliderStage');
|
| 730 |
const imgStd = document.getElementById('imgStd');
|
|
@@ -788,6 +796,7 @@ async def homepage(request: Request):
|
|
| 788 |
filesState = [];
|
| 789 |
renderPreviews();
|
| 790 |
promptInput.value = text;
|
|
|
|
| 791 |
|
| 792 |
try {{
|
| 793 |
for(let i=0; i<urls.length; i++) {{
|
|
@@ -797,8 +806,20 @@ async def homepage(request: Request):
|
|
| 797 |
filesState.push(new File([blob], filename, {{type: blob.type}}));
|
| 798 |
}}
|
| 799 |
renderPreviews();
|
|
|
|
|
|
|
| 800 |
window.scrollTo({{top: 0, behavior: 'smooth'}});
|
| 801 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 802 |
}}
|
| 803 |
|
| 804 |
const exGrid = document.getElementById('examplesGrid');
|
|
@@ -853,7 +874,12 @@ async def homepage(request: Request):
|
|
| 853 |
// --- Form Submission ---
|
| 854 |
runBtn.onclick = async () => {{
|
| 855 |
const prompt = promptInput.value.trim();
|
| 856 |
-
if(!prompt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 857 |
|
| 858 |
const fd = new FormData();
|
| 859 |
fd.append('prompt', prompt);
|
|
@@ -869,11 +895,15 @@ async def homepage(request: Request):
|
|
| 869 |
loader.style.display = 'flex';
|
| 870 |
runBtn.disabled = true;
|
| 871 |
|
|
|
|
|
|
|
| 872 |
try {{
|
| 873 |
const res = await fetch('/api/compare', {{ method: 'POST', body: fd }});
|
| 874 |
const data = await res.json();
|
| 875 |
|
| 876 |
if(data.success) {{
|
|
|
|
|
|
|
| 877 |
imgStd.src = data.std_url;
|
| 878 |
imgSmall.src = data.small_url;
|
| 879 |
|
|
@@ -889,13 +919,16 @@ async def homepage(request: Request):
|
|
| 889 |
updateSlider(rect.left + rect.width / 2);
|
| 890 |
}};
|
| 891 |
}} else {{
|
|
|
|
| 892 |
alert('Error: ' + data.error);
|
| 893 |
}}
|
| 894 |
}} catch(e) {{
|
|
|
|
| 895 |
alert('Failed to connect to server.');
|
| 896 |
}} finally {{
|
| 897 |
loader.style.display = 'none';
|
| 898 |
runBtn.disabled = false;
|
|
|
|
| 899 |
}}
|
| 900 |
}};
|
| 901 |
</script>
|
|
|
|
| 177 |
|
| 178 |
# --- FastAPI Endpoints ---
|
| 179 |
def get_example_items():
|
|
|
|
| 180 |
return [
|
| 181 |
{
|
| 182 |
"urls": ["/example-file/I1.jpg", "/example-file/I2.jpg"],
|
|
|
|
| 344 |
display: grid;
|
| 345 |
grid-template-columns: 420px 1fr;
|
| 346 |
gap: 24px;
|
| 347 |
+
align-items: stretch;
|
| 348 |
+
height: 650px;
|
| 349 |
}}
|
| 350 |
|
| 351 |
.panel {{
|
|
|
|
| 364 |
border-bottom: 1px solid var(--ub-border);
|
| 365 |
font-weight: 500;
|
| 366 |
font-size: 1.1rem;
|
| 367 |
+
flex-shrink: 0;
|
| 368 |
}}
|
| 369 |
|
|
|
|
| 370 |
.panel-body-scroll {{
|
| 371 |
flex: 1;
|
| 372 |
padding: 20px;
|
|
|
|
| 439 |
|
| 440 |
/* The (+) Button */
|
| 441 |
.add-more-btn {{
|
| 442 |
+
display: flex; align-items: center; justify-content: center;
|
| 443 |
+
border: 2px dashed var(--ub-muted); border-radius: 4px;
|
| 444 |
+
color: var(--ub-muted); font-size: 26px; cursor: pointer;
|
| 445 |
+
aspect-ratio: 1; transition: all 0.2s; background: transparent;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 446 |
}}
|
| 447 |
.add-more-btn:hover {{
|
| 448 |
+
border-color: var(--ub-orange); color: var(--ub-orange);
|
|
|
|
| 449 |
background: rgba(233,84,32,0.05);
|
| 450 |
}}
|
| 451 |
|
| 452 |
+
/* Advanced Accordion */
|
| 453 |
+
.advanced-toggle {{
|
| 454 |
+
width: 100%; background: none; border: none; color: var(--ub-orange);
|
| 455 |
+
text-align: left; padding: 10px 0; font-weight: 500; cursor: pointer;
|
| 456 |
+
display: flex; justify-content: space-between; align-items: center;
|
| 457 |
+
flex-shrink: 0;
|
| 458 |
+
}}
|
| 459 |
+
.advanced-icon {{ font-weight: bold; font-size: 18px; line-height: 1; }}
|
| 460 |
+
.advanced-body {{ display: none; padding-top: 10px; flex-shrink: 0; }}
|
| 461 |
+
.advanced-body.open {{ display: block; }}
|
| 462 |
+
.grid-2 {{ display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }}
|
| 463 |
+
|
| 464 |
+
/* Status Container (Execution Log) */
|
| 465 |
+
.status-container {{
|
| 466 |
+
margin-top: 20px;
|
| 467 |
+
margin-bottom: 20px;
|
| 468 |
+
border: 1px solid var(--ub-border);
|
| 469 |
+
border-radius: 4px;
|
| 470 |
+
background: #200014; /* deep ubuntu terminal background */
|
| 471 |
+
display: flex;
|
| 472 |
+
flex-direction: column;
|
| 473 |
+
flex: 1;
|
| 474 |
+
min-height: 100px;
|
| 475 |
+
max-height: 200px; /* limits expansion if advanced is closed */
|
| 476 |
+
}}
|
| 477 |
+
.status-header {{
|
| 478 |
+
padding: 8px 12px;
|
| 479 |
+
font-size: 11px;
|
| 480 |
+
font-weight: 700;
|
| 481 |
+
color: var(--ub-muted);
|
| 482 |
+
background: rgba(0,0,0,0.4);
|
| 483 |
+
border-bottom: 1px solid var(--ub-border);
|
| 484 |
+
text-transform: uppercase;
|
| 485 |
+
letter-spacing: 0.5px;
|
| 486 |
+
flex-shrink: 0;
|
| 487 |
+
}}
|
| 488 |
+
.status-log {{
|
| 489 |
+
padding: 10px;
|
| 490 |
+
font-family: 'Courier New', Courier, monospace;
|
| 491 |
+
font-size: 12px;
|
| 492 |
+
color: #eeeeee;
|
| 493 |
+
overflow-y: auto;
|
| 494 |
+
flex: 1;
|
| 495 |
+
display: flex;
|
| 496 |
+
flex-direction: column;
|
| 497 |
+
gap: 4px;
|
| 498 |
+
}}
|
| 499 |
+
.log-time {{ color: #777; margin-right: 8px; }}
|
| 500 |
+
.log-info {{ color: #5bc0eb; }}
|
| 501 |
+
.log-success {{ color: #9bc53d; }}
|
| 502 |
+
.log-error {{ color: #ff5e5b; }}
|
| 503 |
+
|
| 504 |
/* Buttons */
|
| 505 |
.btn {{
|
| 506 |
width: 100%; padding: 14px; border: none; border-radius: 4px;
|
| 507 |
font-size: 16px; font-weight: 700; cursor: pointer;
|
| 508 |
transition: opacity 0.2s, background 0.2s;
|
|
|
|
| 509 |
flex-shrink: 0;
|
| 510 |
}}
|
| 511 |
.btn-primary {{
|
|
|
|
| 515 |
.btn-primary:hover {{ background: var(--ub-orange-hover); }}
|
| 516 |
.btn:disabled {{ opacity: 0.6; cursor: not-allowed; }}
|
| 517 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 518 |
/* SLIDER CONTAINER */
|
| 519 |
.panel-body-slider {{
|
| 520 |
flex: 1;
|
| 521 |
display: flex;
|
| 522 |
flex-direction: column;
|
| 523 |
+
padding: 0;
|
| 524 |
position: relative;
|
| 525 |
}}
|
| 526 |
.slider-stage {{
|
|
|
|
| 532 |
align-items: center;
|
| 533 |
justify-content: center;
|
| 534 |
}}
|
| 535 |
+
.slider-empty {{ color: var(--ub-muted); text-align: center; z-index: 1; }}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 536 |
|
| 537 |
.slider-img {{
|
| 538 |
+
position: absolute; top: 0; left: 0;
|
| 539 |
+
width: 100%; height: 100%; object-fit: contain;
|
| 540 |
+
display: none; user-select: none; -webkit-user-drag: none;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 541 |
}}
|
|
|
|
|
|
|
| 542 |
#imgSmall {{ clip-path: inset(0 50% 0 0); }}
|
| 543 |
|
| 544 |
.slider-handle {{
|
| 545 |
+
position: absolute; left: 50%; top: 0; bottom: 0;
|
| 546 |
+
width: 4px; background: var(--ub-orange);
|
| 547 |
+
cursor: ew-resize; display: none; z-index: 10;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 548 |
}}
|
| 549 |
.slider-handle::after {{
|
| 550 |
+
content: '◀ ▶'; position: absolute; top: 50%; left: 50%;
|
|
|
|
|
|
|
| 551 |
transform: translate(-50%, -50%);
|
| 552 |
+
width: 40px; height: 30px; background: var(--ub-orange);
|
| 553 |
+
color: white; border-radius: 15px;
|
|
|
|
|
|
|
| 554 |
display: flex; align-items: center; justify-content: center;
|
| 555 |
+
font-size: 10px; font-weight: bold; box-shadow: 0 2px 6px rgba(0,0,0,0.5);
|
|
|
|
| 556 |
}}
|
| 557 |
|
| 558 |
.slider-labels {{
|
| 559 |
+
position: absolute; top: 15px; left: 15px; right: 15px;
|
| 560 |
+
display: none; justify-content: space-between;
|
| 561 |
+
pointer-events: none; z-index: 5;
|
|
|
|
|
|
|
|
|
|
| 562 |
}}
|
| 563 |
.badge {{
|
| 564 |
+
background: rgba(0,0,0,0.6); color: white; padding: 6px 12px;
|
| 565 |
+
border-radius: 20px; font-size: 13px; backdrop-filter: blur(4px);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 566 |
}}
|
| 567 |
|
| 568 |
.loader {{
|
| 569 |
+
position: absolute; inset: 0; background: rgba(0,0,0,0.7);
|
|
|
|
| 570 |
display: none; flex-direction: column;
|
| 571 |
+
align-items: center; justify-content: center; z-index: 20;
|
|
|
|
| 572 |
}}
|
| 573 |
.spinner {{
|
| 574 |
+
width: 40px; height: 40px; border: 4px solid rgba(255,255,255,0.2);
|
| 575 |
+
border-top-color: var(--ub-orange); border-radius: 50%;
|
| 576 |
+
animation: spin 1s linear infinite; margin-bottom: 15px;
|
|
|
|
|
|
|
|
|
|
| 577 |
}}
|
| 578 |
|
| 579 |
/* Examples */
|
|
|
|
| 588 |
}}
|
| 589 |
.ex-card:hover {{ transform: translateY(-3px); box-shadow: 0 6px 16px rgba(0,0,0,0.3); }}
|
| 590 |
|
| 591 |
+
.ex-card-img-wrap {{ width: 100%; aspect-ratio: 1; display: flex; background: #000; }}
|
| 592 |
+
.ex-card-img-wrap img {{ height: 100%; object-fit: cover; }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 593 |
.ex-card p {{ padding: 12px; margin: 0; font-size: 13px; color: var(--ub-muted); line-height: 1.4; }}
|
| 594 |
|
| 595 |
@keyframes spin {{ to {{ transform: rotate(360deg); }} }}
|
|
|
|
| 663 |
</div>
|
| 664 |
</div>
|
| 665 |
|
| 666 |
+
<div class="status-container">
|
| 667 |
+
<div class="status-header">Execution Log</div>
|
| 668 |
+
<div class="status-log" id="statusLog">
|
| 669 |
+
<div><span class="log-time">[{DEVICE_LABEL}]</span><span>System Ready...</span></div>
|
| 670 |
+
</div>
|
| 671 |
+
</div>
|
| 672 |
+
|
| 673 |
+
<button class="btn btn-primary" id="runBtn">Run Comparison</button>
|
| 674 |
</div>
|
| 675 |
</div>
|
| 676 |
|
|
|
|
| 722 |
const promptInput = document.getElementById('promptInput');
|
| 723 |
const runBtn = document.getElementById('runBtn');
|
| 724 |
|
| 725 |
+
// Status Log
|
| 726 |
+
const statusLog = document.getElementById('statusLog');
|
| 727 |
+
|
| 728 |
+
function logMsg(msg, styleClass="") {{
|
| 729 |
+
const div = document.createElement('div');
|
| 730 |
+
const timeStr = new Date().toLocaleTimeString('en-US', {{hour12:false}});
|
| 731 |
+
div.innerHTML = `<span class="log-time">[${{timeStr}}]</span><span class="${{styleClass}}">${{msg}}</span>`;
|
| 732 |
+
statusLog.appendChild(div);
|
| 733 |
+
statusLog.scrollTop = statusLog.scrollHeight; // auto-scroll to bottom
|
| 734 |
+
}}
|
| 735 |
+
|
| 736 |
// Slider Elements
|
| 737 |
const sliderStage = document.getElementById('sliderStage');
|
| 738 |
const imgStd = document.getElementById('imgStd');
|
|
|
|
| 796 |
filesState = [];
|
| 797 |
renderPreviews();
|
| 798 |
promptInput.value = text;
|
| 799 |
+
logMsg("Loading example: " + text, "log-info");
|
| 800 |
|
| 801 |
try {{
|
| 802 |
for(let i=0; i<urls.length; i++) {{
|
|
|
|
| 806 |
filesState.push(new File([blob], filename, {{type: blob.type}}));
|
| 807 |
}}
|
| 808 |
renderPreviews();
|
| 809 |
+
|
| 810 |
+
// Scroll to top
|
| 811 |
window.scrollTo({{top: 0, behavior: 'smooth'}});
|
| 812 |
+
|
| 813 |
+
// Wait a tiny bit for UI update, then trigger generation
|
| 814 |
+
setTimeout(() => {{
|
| 815 |
+
logMsg("Example loaded. Starting comparison...", "log-info");
|
| 816 |
+
runBtn.click();
|
| 817 |
+
}}, 500);
|
| 818 |
+
|
| 819 |
+
}} catch (e) {{
|
| 820 |
+
logMsg("Failed to load example images.", "log-error");
|
| 821 |
+
alert('Failed to load example image.');
|
| 822 |
+
}}
|
| 823 |
}}
|
| 824 |
|
| 825 |
const exGrid = document.getElementById('examplesGrid');
|
|
|
|
| 874 |
// --- Form Submission ---
|
| 875 |
runBtn.onclick = async () => {{
|
| 876 |
const prompt = promptInput.value.trim();
|
| 877 |
+
if(!prompt) {{
|
| 878 |
+
logMsg("Validation failed: Prompt is empty.", "log-error");
|
| 879 |
+
return alert("Enter a prompt");
|
| 880 |
+
}}
|
| 881 |
+
|
| 882 |
+
logMsg("Initializing generation sequence...", "log-info");
|
| 883 |
|
| 884 |
const fd = new FormData();
|
| 885 |
fd.append('prompt', prompt);
|
|
|
|
| 895 |
loader.style.display = 'flex';
|
| 896 |
runBtn.disabled = true;
|
| 897 |
|
| 898 |
+
logMsg("Sending request to backend. Running both VAE models...", "log-info");
|
| 899 |
+
|
| 900 |
try {{
|
| 901 |
const res = await fetch('/api/compare', {{ method: 'POST', body: fd }});
|
| 902 |
const data = await res.json();
|
| 903 |
|
| 904 |
if(data.success) {{
|
| 905 |
+
logMsg(`Success! Inference completed. Used seed: ${{data.seed}}`, "log-success");
|
| 906 |
+
|
| 907 |
imgStd.src = data.std_url;
|
| 908 |
imgSmall.src = data.small_url;
|
| 909 |
|
|
|
|
| 919 |
updateSlider(rect.left + rect.width / 2);
|
| 920 |
}};
|
| 921 |
}} else {{
|
| 922 |
+
logMsg("Error processing request: " + data.error, "log-error");
|
| 923 |
alert('Error: ' + data.error);
|
| 924 |
}}
|
| 925 |
}} catch(e) {{
|
| 926 |
+
logMsg("Network or server connection failed.", "log-error");
|
| 927 |
alert('Failed to connect to server.');
|
| 928 |
}} finally {{
|
| 929 |
loader.style.display = 'none';
|
| 930 |
runBtn.disabled = false;
|
| 931 |
+
logMsg("Sequence finished. Ready for next input.", "");
|
| 932 |
}}
|
| 933 |
}};
|
| 934 |
</script>
|