Spaces:
Sleeping
Sleeping
Move record details into click modal
Browse files
app.py
CHANGED
|
@@ -376,6 +376,19 @@ gradio-app,
|
|
| 376 |
color: var(--ink);
|
| 377 |
}
|
| 378 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
.record-card.needs-recovery {
|
| 380 |
background: var(--orange-soft);
|
| 381 |
border-color: #a65b0b;
|
|
@@ -515,43 +528,159 @@ gradio-app,
|
|
| 515 |
color: var(--ink);
|
| 516 |
}
|
| 517 |
|
| 518 |
-
.
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
border-
|
| 522 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 523 |
font-size: 12px;
|
| 524 |
-
|
|
|
|
| 525 |
}
|
| 526 |
|
| 527 |
-
.
|
| 528 |
-
|
| 529 |
color: var(--ink);
|
| 530 |
-
font-
|
| 531 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 532 |
}
|
| 533 |
|
| 534 |
-
.
|
| 535 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 536 |
}
|
| 537 |
|
| 538 |
-
.
|
| 539 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 540 |
color: var(--ink);
|
| 541 |
-
font-
|
|
|
|
| 542 |
}
|
| 543 |
|
| 544 |
-
.
|
| 545 |
-
|
|
|
|
| 546 |
color: var(--muted);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 547 |
overflow-wrap: anywhere;
|
| 548 |
}
|
| 549 |
|
| 550 |
-
.
|
| 551 |
-
|
| 552 |
-
border: 1px solid var(--line);
|
| 553 |
-
border-radius: var(--radius);
|
| 554 |
-
padding: 16px;
|
| 555 |
}
|
| 556 |
|
| 557 |
.leaderboard-table {
|
|
@@ -723,6 +852,41 @@ gradio-app,
|
|
| 723 |
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
| 724 |
}
|
| 725 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 726 |
.render-stage {
|
| 727 |
height: 154px;
|
| 728 |
}
|
|
@@ -1091,7 +1255,7 @@ def needs_recovery(record: dict[str, Any], visual_record: dict[str, Any]) -> boo
|
|
| 1091 |
return visual > reference + RECOVERY_TOLERANCE_ABS
|
| 1092 |
|
| 1093 |
|
| 1094 |
-
def
|
| 1095 |
rows: list[str] = []
|
| 1096 |
rows.append(detail_row("Rendering", esc(visual_provenance(record, visual_record))))
|
| 1097 |
if record.get("record_type") == "reference" and visual_record.get("verified"):
|
|
@@ -1125,11 +1289,45 @@ def record_details(record: dict[str, Any], visual_record: dict[str, Any], source
|
|
| 1125 |
rows.append(detail_row("Status", "analytical/proved"))
|
| 1126 |
reference_text = str(friedman_reference(record).get("reference_text") or "").strip()
|
| 1127 |
rows.append(detail_row("Reference text", esc(reference_text)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1128 |
return f"""
|
| 1129 |
-
|
| 1130 |
-
|
| 1131 |
-
|
| 1132 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1133 |
"""
|
| 1134 |
|
| 1135 |
|
|
@@ -1146,19 +1344,22 @@ def record_card(record: dict[str, Any], coordinates: dict[str, dict[str, Any]])
|
|
| 1146 |
if needs_recovery(record, visual_record):
|
| 1147 |
card_class += " needs-recovery"
|
| 1148 |
anchor = f"{record.get('setup')}-{record.get('n')}"
|
|
|
|
| 1149 |
return f"""
|
| 1150 |
<article class="record-card {card_class}" id="{esc(anchor)}">
|
| 1151 |
-
<
|
| 1152 |
-
<div class="record-
|
| 1153 |
-
|
| 1154 |
-
|
| 1155 |
-
|
| 1156 |
-
<div class="
|
| 1157 |
-
|
| 1158 |
-
|
| 1159 |
-
|
| 1160 |
-
|
|
|
|
| 1161 |
</article>
|
|
|
|
| 1162 |
"""
|
| 1163 |
|
| 1164 |
|
|
@@ -1232,7 +1433,7 @@ def family_description(summary: dict[str, Any]) -> str:
|
|
| 1232 |
return (
|
| 1233 |
f"This page tracks the smallest known container metric for packing n equal {esc(item)} "
|
| 1234 |
f"inside a {esc(container)}. The number shown on each card is the verified coordinate metric "
|
| 1235 |
-
f"for the rendering; the Friedman reference value and source information
|
| 1236 |
f"Orange cards need more recovery work because the verified coordinate JSON does not yet match "
|
| 1237 |
f"the listed reference within {RECOVERY_TOLERANCE_ABS:.2f}.{updated}"
|
| 1238 |
)
|
|
|
|
| 376 |
color: var(--ink);
|
| 377 |
}
|
| 378 |
|
| 379 |
+
.record-card:hover,
|
| 380 |
+
.record-card:focus-within {
|
| 381 |
+
background: #fffaf0;
|
| 382 |
+
outline: 2px solid var(--line);
|
| 383 |
+
outline-offset: 2px;
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
.record-open {
|
| 387 |
+
display: block;
|
| 388 |
+
color: inherit !important;
|
| 389 |
+
text-decoration: none !important;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
.record-card.needs-recovery {
|
| 393 |
background: var(--orange-soft);
|
| 394 |
border-color: #a65b0b;
|
|
|
|
| 528 |
color: var(--ink);
|
| 529 |
}
|
| 530 |
|
| 531 |
+
.page-card {
|
| 532 |
+
background: var(--paper);
|
| 533 |
+
border: 1px solid var(--line);
|
| 534 |
+
border-radius: var(--radius);
|
| 535 |
+
padding: 16px;
|
| 536 |
+
}
|
| 537 |
+
|
| 538 |
+
.record-modal {
|
| 539 |
+
display: none;
|
| 540 |
+
position: fixed;
|
| 541 |
+
inset: 0;
|
| 542 |
+
z-index: 1000;
|
| 543 |
+
align-items: center;
|
| 544 |
+
justify-content: center;
|
| 545 |
+
padding: 24px;
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
.record-modal:target {
|
| 549 |
+
display: flex;
|
| 550 |
+
}
|
| 551 |
+
|
| 552 |
+
.modal-backdrop {
|
| 553 |
+
position: absolute;
|
| 554 |
+
inset: 0;
|
| 555 |
+
background: rgba(21, 21, 21, 0.42);
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
.modal-panel {
|
| 559 |
+
position: relative;
|
| 560 |
+
z-index: 1;
|
| 561 |
+
width: min(920px, calc(100vw - 32px));
|
| 562 |
+
max-height: calc(100vh - 32px);
|
| 563 |
+
overflow: auto;
|
| 564 |
+
background: var(--paper);
|
| 565 |
+
border: 2px solid var(--line);
|
| 566 |
+
border-radius: var(--radius);
|
| 567 |
+
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.24);
|
| 568 |
+
}
|
| 569 |
+
|
| 570 |
+
.modal-close {
|
| 571 |
+
position: absolute;
|
| 572 |
+
top: 12px;
|
| 573 |
+
right: 12px;
|
| 574 |
+
display: grid;
|
| 575 |
+
place-items: center;
|
| 576 |
+
width: 32px;
|
| 577 |
+
height: 32px;
|
| 578 |
+
background: var(--paper);
|
| 579 |
+
border: 1px solid var(--line);
|
| 580 |
+
border-radius: 4px;
|
| 581 |
+
color: var(--ink) !important;
|
| 582 |
+
font-size: 18px;
|
| 583 |
+
font-weight: 700;
|
| 584 |
+
line-height: 1;
|
| 585 |
+
text-decoration: none !important;
|
| 586 |
+
}
|
| 587 |
+
|
| 588 |
+
.modal-close:hover,
|
| 589 |
+
.modal-close:focus-visible {
|
| 590 |
+
background: #fffaf0;
|
| 591 |
+
outline: 2px solid var(--line);
|
| 592 |
+
outline-offset: 2px;
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
.modal-head {
|
| 596 |
+
padding: 18px 58px 12px 18px;
|
| 597 |
+
border-bottom: 1px solid var(--line);
|
| 598 |
+
}
|
| 599 |
+
|
| 600 |
+
.modal-case {
|
| 601 |
+
margin: 0 0 4px;
|
| 602 |
+
color: var(--quiet);
|
| 603 |
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace !important;
|
| 604 |
font-size: 12px;
|
| 605 |
+
font-weight: 700;
|
| 606 |
+
text-transform: uppercase;
|
| 607 |
}
|
| 608 |
|
| 609 |
+
.modal-head h3 {
|
| 610 |
+
margin: 0;
|
| 611 |
color: var(--ink);
|
| 612 |
+
font-size: 22px;
|
| 613 |
+
line-height: 1.2;
|
| 614 |
+
}
|
| 615 |
+
|
| 616 |
+
.modal-subtitle {
|
| 617 |
+
margin-top: 7px;
|
| 618 |
+
color: var(--muted);
|
| 619 |
+
font-size: 13px;
|
| 620 |
+
line-height: 1.45;
|
| 621 |
}
|
| 622 |
|
| 623 |
+
.modal-layout {
|
| 624 |
+
display: grid;
|
| 625 |
+
grid-template-columns: minmax(240px, 340px) 1fr;
|
| 626 |
+
gap: 18px;
|
| 627 |
+
padding: 18px;
|
| 628 |
+
}
|
| 629 |
+
|
| 630 |
+
.modal-visual .render-stage {
|
| 631 |
+
height: 320px;
|
| 632 |
+
margin: 0;
|
| 633 |
}
|
| 634 |
|
| 635 |
+
.modal-visual .packing-svg {
|
| 636 |
+
max-width: 300px;
|
| 637 |
+
max-height: 300px;
|
| 638 |
+
}
|
| 639 |
+
|
| 640 |
+
.modal-metric {
|
| 641 |
+
margin-bottom: 14px;
|
| 642 |
+
padding: 10px 12px;
|
| 643 |
+
background: var(--paper-soft);
|
| 644 |
+
border: 1px solid var(--line-soft);
|
| 645 |
+
border-radius: var(--radius);
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
+
.modal-metric strong {
|
| 649 |
+
display: block;
|
| 650 |
color: var(--ink);
|
| 651 |
+
font-size: 20px;
|
| 652 |
+
line-height: 1.2;
|
| 653 |
}
|
| 654 |
|
| 655 |
+
.modal-metric span {
|
| 656 |
+
display: block;
|
| 657 |
+
margin-top: 3px;
|
| 658 |
color: var(--muted);
|
| 659 |
+
font-size: 13px;
|
| 660 |
+
}
|
| 661 |
+
|
| 662 |
+
.modal-details {
|
| 663 |
+
margin: 0;
|
| 664 |
+
display: grid;
|
| 665 |
+
grid-template-columns: 142px minmax(0, 1fr);
|
| 666 |
+
gap: 8px 14px;
|
| 667 |
+
color: var(--muted);
|
| 668 |
+
font-size: 13px;
|
| 669 |
+
line-height: 1.42;
|
| 670 |
+
}
|
| 671 |
+
|
| 672 |
+
.modal-details dt {
|
| 673 |
+
color: var(--ink);
|
| 674 |
+
font-weight: 700;
|
| 675 |
+
}
|
| 676 |
+
|
| 677 |
+
.modal-details dd {
|
| 678 |
+
margin: 0;
|
| 679 |
overflow-wrap: anywhere;
|
| 680 |
}
|
| 681 |
|
| 682 |
+
.modal-details a {
|
| 683 |
+
color: var(--link) !important;
|
|
|
|
|
|
|
|
|
|
| 684 |
}
|
| 685 |
|
| 686 |
.leaderboard-table {
|
|
|
|
| 852 |
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
| 853 |
}
|
| 854 |
|
| 855 |
+
.record-modal {
|
| 856 |
+
padding: 12px;
|
| 857 |
+
}
|
| 858 |
+
|
| 859 |
+
.modal-head {
|
| 860 |
+
padding: 16px 54px 12px 14px;
|
| 861 |
+
}
|
| 862 |
+
|
| 863 |
+
.modal-layout {
|
| 864 |
+
display: block;
|
| 865 |
+
padding: 14px;
|
| 866 |
+
}
|
| 867 |
+
|
| 868 |
+
.modal-visual {
|
| 869 |
+
margin-bottom: 14px;
|
| 870 |
+
}
|
| 871 |
+
|
| 872 |
+
.modal-visual .render-stage {
|
| 873 |
+
height: 240px;
|
| 874 |
+
}
|
| 875 |
+
|
| 876 |
+
.modal-visual .packing-svg {
|
| 877 |
+
max-width: 220px;
|
| 878 |
+
max-height: 220px;
|
| 879 |
+
}
|
| 880 |
+
|
| 881 |
+
.modal-details {
|
| 882 |
+
grid-template-columns: 1fr;
|
| 883 |
+
gap: 3px;
|
| 884 |
+
}
|
| 885 |
+
|
| 886 |
+
.modal-details dd {
|
| 887 |
+
margin-bottom: 8px;
|
| 888 |
+
}
|
| 889 |
+
|
| 890 |
.render-stage {
|
| 891 |
height: 154px;
|
| 892 |
}
|
|
|
|
| 1255 |
return visual > reference + RECOVERY_TOLERANCE_ABS
|
| 1256 |
|
| 1257 |
|
| 1258 |
+
def record_detail_rows(record: dict[str, Any], visual_record: dict[str, Any], source: str, image_name: str, expression: str, analytical: Any) -> list[str]:
|
| 1259 |
rows: list[str] = []
|
| 1260 |
rows.append(detail_row("Rendering", esc(visual_provenance(record, visual_record))))
|
| 1261 |
if record.get("record_type") == "reference" and visual_record.get("verified"):
|
|
|
|
| 1289 |
rows.append(detail_row("Status", "analytical/proved"))
|
| 1290 |
reference_text = str(friedman_reference(record).get("reference_text") or "").strip()
|
| 1291 |
rows.append(detail_row("Reference text", esc(reference_text)))
|
| 1292 |
+
return rows
|
| 1293 |
+
|
| 1294 |
+
|
| 1295 |
+
def record_modal(
|
| 1296 |
+
record: dict[str, Any],
|
| 1297 |
+
visual_record: dict[str, Any],
|
| 1298 |
+
display_record: dict[str, Any],
|
| 1299 |
+
coordinates: dict[str, dict[str, Any]],
|
| 1300 |
+
source: str,
|
| 1301 |
+
image_name: str,
|
| 1302 |
+
expression: str,
|
| 1303 |
+
analytical: Any,
|
| 1304 |
+
anchor: str,
|
| 1305 |
+
modal_id: str,
|
| 1306 |
+
visible_author: str,
|
| 1307 |
+
) -> str:
|
| 1308 |
+
rows = record_detail_rows(record, visual_record, source, image_name, expression, analytical)
|
| 1309 |
return f"""
|
| 1310 |
+
<section class="record-modal" id="{esc(modal_id)}" aria-label="{esc(record.get("case"))} record information">
|
| 1311 |
+
<a class="modal-backdrop" href="#{esc(anchor)}" aria-label="Close record information"></a>
|
| 1312 |
+
<div class="modal-panel" role="dialog" aria-modal="true" aria-labelledby="{esc(modal_id)}-title">
|
| 1313 |
+
<a class="modal-close" href="#{esc(anchor)}" aria-label="Close record information">x</a>
|
| 1314 |
+
<div class="modal-head">
|
| 1315 |
+
<div class="modal-case">{esc(record.get("case"))}</div>
|
| 1316 |
+
<h3 id="{esc(modal_id)}-title">{esc(setup_title(str(record.get("setup") or "")))}</h3>
|
| 1317 |
+
<div class="modal-subtitle">n={esc(record.get("n"))} by <strong>{esc(visible_author)}</strong></div>
|
| 1318 |
+
</div>
|
| 1319 |
+
<div class="modal-layout">
|
| 1320 |
+
<div class="modal-visual">{record_visual(record, coordinates)}</div>
|
| 1321 |
+
<div>
|
| 1322 |
+
<div class="modal-metric">
|
| 1323 |
+
<strong>{esc(metric_symbol(display_record))} = {esc(metric_value(display_record))}</strong>
|
| 1324 |
+
<span>{esc(expression)}</span>
|
| 1325 |
+
</div>
|
| 1326 |
+
<dl class="modal-details">{''.join(rows)}</dl>
|
| 1327 |
+
</div>
|
| 1328 |
+
</div>
|
| 1329 |
+
</div>
|
| 1330 |
+
</section>
|
| 1331 |
"""
|
| 1332 |
|
| 1333 |
|
|
|
|
| 1344 |
if needs_recovery(record, visual_record):
|
| 1345 |
card_class += " needs-recovery"
|
| 1346 |
anchor = f"{record.get('setup')}-{record.get('n')}"
|
| 1347 |
+
modal_id = f"modal-{anchor}"
|
| 1348 |
return f"""
|
| 1349 |
<article class="record-card {card_class}" id="{esc(anchor)}">
|
| 1350 |
+
<a class="record-open" href="#{esc(modal_id)}" aria-label="Open {esc(record.get("case"))} record information">
|
| 1351 |
+
<div class="record-top">
|
| 1352 |
+
<div class="record-case">{esc(record.get("case"))}</div>
|
| 1353 |
+
</div>
|
| 1354 |
+
{record_visual(record, coordinates)}
|
| 1355 |
+
<div class="record-body">
|
| 1356 |
+
<div class="metric"><strong>{esc(metric_symbol(display_record))} = {esc(metric_value(display_record))}</strong><span>n={esc(record.get("n"))}</span></div>
|
| 1357 |
+
<div class="expression">{esc(expression)}</div>
|
| 1358 |
+
<div class="record-author">by <strong>{esc(visible_author)}</strong></div>
|
| 1359 |
+
</div>
|
| 1360 |
+
</a>
|
| 1361 |
</article>
|
| 1362 |
+
{record_modal(record, visual_record, display_record, coordinates, source, image_name, expression, analytical, anchor, modal_id, visible_author)}
|
| 1363 |
"""
|
| 1364 |
|
| 1365 |
|
|
|
|
| 1433 |
return (
|
| 1434 |
f"This page tracks the smallest known container metric for packing n equal {esc(item)} "
|
| 1435 |
f"inside a {esc(container)}. The number shown on each card is the verified coordinate metric "
|
| 1436 |
+
f"for the rendering; click a card to view the Friedman reference value and source information. "
|
| 1437 |
f"Orange cards need more recovery work because the verified coordinate JSON does not yet match "
|
| 1438 |
f"the listed reference within {RECOVERY_TOLERANCE_ABS:.2f}.{updated}"
|
| 1439 |
)
|