Spaces:
Paused
Paused
File size: 15,398 Bytes
9b08343 83fade1 9b08343 83fade1 9b08343 6a4d6c4 9b08343 83fade1 9b08343 83fade1 9b08343 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fiber Checker</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600;9..144,650&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root{--bg:#f6f1e7;--card:#fffdf8;--ink:#2a2118;--ink2:#5e5144;--ink3:#857767;--line:#e3d7c3;--accent:#9a5b1f;--accent2:#6b3b16;--shadow:0 1px 2px rgba(60,40,20,.06),0 6px 20px rgba(60,40,20,.06)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--bg:#14120f;--card:#1f1c18;--ink:#f1e9dc;--ink2:#c9bba8;--ink3:#9c8f7e;--line:#332e28;--accent:#d89a52;--accent2:#e8b273;--shadow:0 1px 2px rgba(0,0,0,.3)}}
:root[data-theme="dark"]{--bg:#14120f;--card:#1f1c18;--ink:#f1e9dc;--ink2:#c9bba8;--ink3:#9c8f7e;--line:#332e28;--accent:#d89a52;--accent2:#e8b273;--shadow:0 1px 2px rgba(0,0,0,.3)}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.6 Inter,system-ui,sans-serif}
a{color:var(--accent);text-decoration:none;overflow-wrap:anywhere}a:hover{text-decoration:underline}
h1,h2,h3{font-family:Fraunces,Georgia,serif;font-weight:650;letter-spacing:-.01em;line-height:1.15}
h2{font-size:clamp(28px,3.4vw,38px);margin:0 0 10px}
h3{font-size:20px;margin:0 0 6px}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px}
nav{position:sticky;top:0;z-index:5;background:color-mix(in srgb,var(--bg) 88%,transparent);backdrop-filter:blur(8px);border-bottom:1px solid var(--line)}
nav .wrap{display:flex;align-items:center;gap:18px;height:52px}
.brand{font-family:Fraunces,serif;font-weight:650;font-size:18px;color:var(--ink);white-space:nowrap}
.navlinks{display:flex;gap:18px;overflow-x:auto;scrollbar-width:none;flex:1}
.navlinks a{color:var(--ink2);font-size:14px;white-space:nowrap}
header.hero{position:relative;overflow:hidden;border-bottom:1px solid var(--line);min-height:560px}
.hero .photos{position:absolute;top:0;right:0;bottom:0;width:62%;background:url('assets/hero.webp') center/cover no-repeat;filter:sepia(.35) saturate(1.1)}
.hero:after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,var(--bg) 0,var(--bg) 40%,color-mix(in srgb,var(--bg) 82%,transparent) 54%,color-mix(in srgb,var(--bg) 25%,transparent) 76%,transparent 100%)}
.hero .wrap{position:relative;z-index:2;padding-top:72px;padding-bottom:64px}
.eyebrow{text-transform:uppercase;letter-spacing:.14em;font-size:12px;font-weight:600;color:var(--accent)}
.hero h1{font-size:clamp(36px,5.6vw,64px);max-width:700px;margin:12px 0 18px}
.lede{font-size:19px;max-width:600px;margin:0}
.by{margin-top:18px;color:var(--ink2);font-size:15px}.by b{color:var(--ink)}
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-top:36px;max-width:720px}
.stat{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:14px 16px;box-shadow:var(--shadow)}
.stat b{display:block;font-family:Fraunces,serif;font-size:28px;font-weight:650;line-height:1.1}
.stat span{font-size:13px;color:var(--ink3)}
.cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
.btn{display:inline-flex;align-items:center;gap:8px;border-radius:10px;padding:10px 16px;font-weight:600;font-size:15px;border:1px solid var(--line);background:var(--card);color:var(--ink)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn:hover{text-decoration:none;filter:brightness(1.05)}
section{padding:72px 0;border-bottom:1px solid var(--line)}
.sub{color:var(--ink2);max-width:760px;margin:0 0 28px;font-size:17px}
.pairs{display:grid;gap:22px}
.pair{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;background:var(--card);border:1px solid var(--line);border-radius:16px;padding:14px;box-shadow:var(--shadow)}
.pair figure{margin:0}
.pair img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:10px;display:block}
figcaption{font-size:13px;color:var(--ink3);margin-top:6px;line-height:1.4}
figcaption b{color:var(--ink);font-weight:600}
.tag{display:inline-block;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;padding:2px 8px;border-radius:99px;margin-bottom:4px}
.yes{background:#e3f1e7;color:#1f6b45}.no{background:#f5e3df;color:#9a2e20}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .yes{background:#1d3427;color:#7fd8a6}:root:not([data-theme="light"]) .no{background:#3a221d;color:#ff9e8f}}
.pairsrc{grid-column:1/-1;font-size:12.5px;color:var(--ink3);margin:0}
.mapgrid{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:24px;align-items:start}
.mapbox{background:#18181c;border-radius:16px;padding:14px;text-align:center;box-shadow:var(--shadow)}
.mapbox img{max-width:100%;max-height:560px;image-rendering:pixelated}
.legend{font-size:13px;color:var(--ink3);margin-top:10px}
.legend i{display:inline-block;width:11px;height:11px;border-radius:3px;margin:0 4px -1px 10px}
.tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:14px}
.tiles img{width:100%;border-radius:10px;display:block}
.cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
.card{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:18px;box-shadow:var(--shadow)}
.card p{margin:0;color:var(--ink2);font-size:15px}
.card .k{font-size:26px;margin-bottom:6px}
.shot{width:100%;border-radius:14px;border:1px solid var(--line);box-shadow:var(--shadow);display:block}
.tablewrap{overflow-x:auto;border-radius:14px;box-shadow:var(--shadow)}
table{border-collapse:collapse;width:100%;font-size:15px;background:var(--card)}
th,td{text-align:left;padding:10px 14px;border-bottom:1px solid var(--line)}
th{font-weight:600;color:var(--ink2);font-size:13px;text-transform:uppercase;letter-spacing:.05em}
td.n{font-variant-numeric:tabular-nums;font-weight:600}
.note{font-size:14px;color:var(--ink3);margin-top:14px;max-width:820px}
.limits li{margin-bottom:8px}
footer{padding:36px 0 48px;color:var(--ink3);font-size:14px;text-align:center}
@media (max-width:860px){
.hero .photos{width:100%;opacity:.35}
.hero:after{background:color-mix(in srgb,var(--bg) 70%,transparent)}
.stats{grid-template-columns:repeat(2,minmax(0,1fr))}
.pair{grid-template-columns:repeat(2,minmax(0,1fr))}
.mapgrid{grid-template-columns:1fr}
.cards{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:520px){
.wrap{padding:0 16px}
header.hero{min-height:0}
.hero .wrap{padding-top:40px;padding-bottom:40px}
.lede{font-size:17px}
.cards{grid-template-columns:1fr}
section{padding:48px 0}
th,td{padding:8px 10px;font-size:14px}
}
</style>
<script>
// Follow the theme the Space page was opened with (Gradio follows Hugging Face's ?__theme=), else the system setting.
try{var t=new URLSearchParams(parent.location.search).get('__theme');if(t==='light'||t==='dark')document.documentElement.dataset.theme=t;}catch(e){}
</script>
</head>
<body>
<nav><div class="wrap">
<span class="brand">Fiber Checker</span>
<div class="navlinks">
<a href="#see">What it sees</a><a href="#map">A fiber map</a><a href="#who">Who it is for</a>
<a href="#tested">How it was tested</a><a href="#limits">Limits</a><a href="?tab=check">Check a segment</a>
</div>
</div></nav>
<header class="hero" id="top">
<div class="photos" role="img" aria-label="A mosaic of CT renders along traced surfaces of public scrolls, each showing papyrus fibers"></div>
<div class="wrap">
<div class="eyebrow">Vesuvius Challenge open data 路 free, no key</div>
<h1>Are papyrus fibers visible on your traced surface?</h1>
<p class="lede">Pick any traced segment of the open data, or upload your own mesh. Fiber Checker renders the CT along the surface patch by patch and tells you where long, thin papyrus strands show, with a check of itself on every run.</p>
<p class="by">Made and shared by <b>Chase Hendrick</b>, October 2026. Scans and meshes: Vesuvius Challenge open data.</p>
<div class="stats">
<div class="stat"><b>1.00</b><span>sheet vs the gap beside it, on two scrolls it never saw</span></div>
<div class="stat"><b>92 to 98%</b><span>sheet vs a tile shuffle (pixel measure 53 to 57%)</span></div>
<div class="stat"><b>0 USD</b><span>the free judge runs on this page's CPU</span></div>
<div class="stat"><b>~80 s</b><span>for a 60-patch check of a segment</span></div>
</div>
<div class="cta">
<a class="btn primary" href="?tab=check">Check a segment</a>
<a class="btn primary" href="?tab=game">Play Fiber or not?</a>
<a class="btn" href="#see">What the judge sees</a>
<a class="btn" href="?tab=howto">How-to guides</a>
<a class="btn" href="?tab=agents">For agents and code</a>
</div>
</div>
</header>
<section id="see"><div class="wrap">
<h2>What the judge sees</h2>
<p class="sub">Each patch is the CT rendered on the traced surface. The judge has to prefer it over copies that keep its brightness and texture but lose the strands. On a surface that sits on papyrus, it does, by a wide margin.</p>
<div class="pairs" id="pairs"></div>
</div></section>
<section id="map"><div class="wrap">
<h2>A fiber map</h2>
<p class="sub">The result of a check: every patch colored by its fiber evidence, on the segment's own mesh grid, so it lines up with the trace. Below the map, the clearest patches the judge saw.</p>
<div class="mapgrid">
<div>
<div class="mapbox"><img src="assets/map.png" alt="A fiber map of PHerc0139 segment w030"></div>
<div class="legend"><i style="background:#fde725"></i>clear fibers<i style="background:#21918c"></i>some<i style="background:#440154"></i>weak<i style="background:#6e6e6e"></i>no sign<i style="background:#343640"></i>not scored</div>
</div>
<div>
<h3 id="mapnums">PHerc0139, segment w030</h3>
<p class="sub" style="margin-bottom:8px" id="mapline">A public scroll on no prize list, the 2.4 um scan of 2 January 2026 at level 2. This winding was one the free judge trained on, so it shows the output, not evidence of how well it works.</p>
<div class="tiles">
<img src="assets/tile-0.webp" alt="clearest patch 1"><img src="assets/tile-1.webp" alt="clearest patch 2"><img src="assets/tile-2.webp" alt="clearest patch 3">
<img src="assets/tile-3.webp" alt="clearest patch 4"><img src="assets/tile-4.webp" alt="clearest patch 5"><img src="assets/tile-5.webp" alt="clearest patch 6">
</div>
<p class="note">Model output about texture, never a reading of text.</p>
</div>
</div>
</div></section>
<section id="page"><div class="wrap">
<h2>The page</h2>
<p class="sub">Choose a scroll, a segment and a scan, press Check fibers, and the map, the numbers, the clearest and weakest patches and a download appear beside it. The download holds <code>fiber.json</code>, <code>fiber.tif</code>, the map and a one-page report.</p>
<img class="shot" src="assets/ui.webp" alt="The Check a segment tab with a finished check">
</div></section>
<section id="who"><div class="wrap">
<h2>Who it is for</h2>
<p class="sub">One check, read four ways.</p>
<div class="cards">
<div class="card"><div class="k">馃尡</div><h3>Beginners</h3><p>See what papyrus fibers look like in CT, play Fiber or not? against the model, and check an example in two minutes.</p></div>
<div class="card"><div class="k">馃弳</div><h3>Prize entrants</h3><p>The Progress Prize asks you to show fibers on your output surface. Attach the one-page report, and say which judge you used.</p></div>
<div class="card"><div class="k">馃敩</div><h3>Researchers</h3><p>Preregistered, tested once on held-out scrolls against built controls, with the failed first round on record. Compare two tracers patch by patch.</p></div>
<div class="card"><div class="k">馃Л</div><h3>Tracers and tool builders</h3><p>Upload a tifxyz, read <code>fiber.tif</code> on your own mesh grid, or call the API or MCP server from a script or an agent.</p></div>
</div>
</div></section>
<section id="tested"><div class="wrap">
<h2>How it was tested</h2>
<p class="sub">The free judge is a small network trained on Claude's answers about renders of four public scrolls. Its test was written down before any test image existed, then run once on two scrolls it never saw.</p>
<div class="tablewrap"><table>
<thead><tr><th>Pair the judge had to get right</th><th>PHerc0500P2</th><th>PHerc0343P</th><th>Pixel measure</th></tr></thead>
<tbody>
<tr><td>Sheet vs the gap beside it</td><td class="n">1.00</td><td class="n">1.00</td><td class="n">0.79, 0.76</td></tr>
<tr><td>Sheet vs a 14-pixel tile shuffle, a size never trained on</td><td class="n">0.98</td><td class="n">0.92</td><td class="n">0.53, 0.57</td></tr>
<tr><td>Sheet vs 3 voxels off</td><td class="n">0.87</td><td class="n">0.68</td><td class="n"></td></tr>
</tbody>
</table></div>
<p class="note">120 and 62 patches; the pixel measure is structure-tensor coherence. A first round failed (it preferred tile-shuffled renders, because it rewarded the edges a shuffle adds) and stays on record; the second added shuffles of other sizes to training. All of it is model output.</p>
</div></section>
<section id="limits"><div class="wrap">
<h2>Limits</h2>
<ul class="limits">
<li><b>It does not tell which sheet.</b> Each patch is rendered at the brightest depth within 5 voxels of the trace, and sheets lie close together, so a trace on the neighboring sheet can still show fibers.</li>
<li><b>Tested setting:</b> open-data meshes on 2.2 to 2.4 um scans at level 2. Other scans still run, and the page says so.</li>
<li><b>Untested hints:</b> jump hints, fiber direction and best depth are ideas until a test of their own passes.</li>
<li><b>Built controls, not real faulty traces,</b> were what it was tested against.</li>
</ul>
</div></section>
<footer><div class="wrap">Fiber Checker 路 code and weights Apache 2.0 路 scans and meshes: <a href="https://scrollprize.org/data">Vesuvius Challenge open data</a>, CC BY-NC 4.0, read live and never copied 路 model output, not a reading</div></footer>
<script>
const PAIRS=[0,1,2].map(n=>({n}));
const KIND=[["on","yes","On the traced surface","the CT as it is: strands run across the patch"],
["scramble","no","Scrambled","same brightness and texture, strands gone"],
["shuffle","no","Tile shuffled","cut into 14-pixel tiles, turned and shuffled"],
["off","no","Off the surface","the CT 5 voxels from the trace"]];
const SRC=["PHerc0139","PHerc0500P2","PHerc0343P"];
document.getElementById('pairs').innerHTML=PAIRS.map(p=>'<div class="pair">'+KIND.map(k=>'<figure><img loading="lazy" src="assets/pair-'+p.n+'-'+k[0]+'.webp" alt="'+k[2]+'"><figcaption><span class="tag '+k[1]+'">'+(k[1]==='yes'?'fibers':'control')+'</span><br><b>'+k[2]+'</b>: '+k[3]+'</figcaption></figure>').join('')+'<p class="pairsrc" data-n="'+p.n+'"></p></div>').join('');
fetch('assets/media.json').then(r=>r.json()).then(m=>{document.querySelectorAll('.pairsrc').forEach(el=>{const s=m.pictures['pair-'+el.dataset.n+'-*.webp'];if(s)el.textContent='From '+s+'. Public scroll on no prize list.'})}).catch(()=>{});
</script>
</body>
</html>
|