Unroll 1.6.0: Connect your tool panel in the Embed sheet
Browse files- CHANGELOG.md +4 -0
- CONNECT.md +110 -0
- connect.html +86 -0
- connect.json +34 -0
- index.html +91 -3
- llms.txt +1 -0
- version.json +3 -3
CHANGELOG.md
CHANGED
|
@@ -5,6 +5,10 @@ Unroll is released as v1.0.0. After it, bump the minor version for a feature pus
|
|
| 5 |
with `node tools/stamp_version.mjs minor|patch` before you commit, then add an entry here.
|
| 6 |
The 0.9.x entries below are the pre-release series that led up to 1.0.0. Version 0.9.0 was reconstructed from the git log.
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
## 1.5.0 (2026-10-16)
|
| 9 |
|
| 10 |
- **Labeled segments** in the CT volume: every traced segment that passes through the cube is drawn into a label volume and coloured over the MIP; a list of the segments in the cube, click one to highlight it. `unrollView.ct.volume.labels`, `?ctlabels=1`.
|
|
|
|
| 5 |
with `node tools/stamp_version.mjs minor|patch` before you commit, then add an entry here.
|
| 6 |
The 0.9.x entries below are the pre-release series that led up to 1.0.0. Version 0.9.0 was reconstructed from the git log.
|
| 7 |
|
| 8 |
+
## 1.6.0 (2026-10-24)
|
| 9 |
+
|
| 10 |
+
- **Connect your tool**, in the Embed sheet (the </> button, also linked from About; and `/CONNECT.md`, `/connect.json`): the open-data URLs behind every layer, a traced winding (tifxyz), a scroll's segment folder and the CT the CT view streams, with ready snippets for Python (zarr, numpy and tifffile), villa's `vesuvius` package, VC3D (File > Attach Remote Zarr), neuroglancer and curl, and links to this page's own API and embed. Each snippet that says "tested" ran against the live public data on 2026-10-24. Made by `python -m kit spaceconnect` in ChaseHendrick/Scrolls, shared by every Space of Chase's.
|
| 11 |
+
|
| 12 |
## 1.5.0 (2026-10-16)
|
| 13 |
|
| 14 |
- **Labeled segments** in the CT volume: every traced segment that passes through the cube is drawn into a label volume and coloured over the MIP; a list of the segments in the cube, click one to highlight it. `unrollView.ct.volume.labels`, `?ctlabels=1`.
|
CONNECT.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Connect your tool: Unroll
|
| 2 |
+
|
| 3 |
+
The traced windings, X-ray CT and ink layers in Unroll come from the Vesuvius Challenge open data, and every one of them reads straight from these URLs in your own tool, with no account and no download step.
|
| 4 |
+
|
| 5 |
+
Checked 2026-10-24. Generated from `connect.json` by `kit spaceconnect` in [ChaseHendrick/Scrolls](https://github.com/ChaseHendrick/Scrolls).
|
| 6 |
+
|
| 7 |
+
## A traced winding (tifxyz), example PHerc0841 w00
|
| 8 |
+
|
| 9 |
+
`https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0841/segments/20260220213127-w00/mesh/20260220213127-on-20250821151531-9.366um.tifxyz`
|
| 10 |
+
|
| 11 |
+
License: CC BY-NC 4.0 (Vesuvius Challenge open data). Every winding Unroll shows has a folder like this under SCROLL/segments/ in the open data; Unroll keeps only a decimated copy for the browser.
|
| 12 |
+
|
| 13 |
+
### Python (numpy, tifffile) (tested 2026-10-24)
|
| 14 |
+
|
| 15 |
+
```python
|
| 16 |
+
# pip install numpy tifffile
|
| 17 |
+
import io, json, urllib.request
|
| 18 |
+
import numpy as np, tifffile
|
| 19 |
+
|
| 20 |
+
T = "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0841/segments/20260220213127-w00/mesh/20260220213127-on-20250821151531-9.366um.tifxyz"
|
| 21 |
+
meta = json.load(urllib.request.urlopen(T + "/meta.json")) # scale, bbox, format
|
| 22 |
+
get = lambda c: tifffile.imread(io.BytesIO(urllib.request.urlopen(f"{T}/{c}.tif").read()))
|
| 23 |
+
xyz = np.stack([get(c) for c in "xyz"], -1) # xyz[i, j] = (x, y, z) in scan voxels; -1 = no surface
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
## Every segment of a scroll, example PHerc0841
|
| 27 |
+
|
| 28 |
+
`s3://vesuvius-challenge-open-data/PHerc0841/segments/`
|
| 29 |
+
|
| 30 |
+
License: CC BY-NC 4.0 (Vesuvius Challenge open data). Each segment folder has mesh/ (tifxyz), surface-volumes/ (OME-Zarr layers) and, where published, ink-detection/.
|
| 31 |
+
|
| 32 |
+
### Python (list the folder) (tested 2026-10-24)
|
| 33 |
+
|
| 34 |
+
```python
|
| 35 |
+
import re, urllib.request
|
| 36 |
+
|
| 37 |
+
B = "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com"
|
| 38 |
+
xml = urllib.request.urlopen(B + "/?list-type=2&delimiter=/&prefix=PHerc0841/segments/").read().decode()
|
| 39 |
+
print(re.findall(r"<Prefix>([^<]+)</Prefix>", xml)) # subfolders; <Key> gives files
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
## X-ray CT behind the CT view, PHerc0139 9.362 um
|
| 43 |
+
|
| 44 |
+
`https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr`
|
| 45 |
+
|
| 46 |
+
License: CC BY-NC 4.0 (Vesuvius Challenge open data). Streamed from the open-data bucket, never copied here. Unroll opens any other scan with ?ctzarr=URL&ctum=VOXEL_UM.
|
| 47 |
+
|
| 48 |
+
### Python (zarr) (tested 2026-10-24)
|
| 49 |
+
|
| 50 |
+
```python
|
| 51 |
+
# pip install "zarr>=3" fsspec aiohttp
|
| 52 |
+
import zarr
|
| 53 |
+
|
| 54 |
+
root = zarr.open_group("https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr", mode="r") # OME-Zarr, zarr v2
|
| 55 |
+
a = root["2"] # level 0 is full resolution; level L is 2**L times coarser
|
| 56 |
+
print(a.shape, a.dtype, a.chunks)
|
| 57 |
+
block = a[2622:2686, 828:892, 828:892] # (z, y, x); reads only the chunks it touches
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
### villa's vesuvius package (tested 2026-10-24)
|
| 61 |
+
|
| 62 |
+
```python
|
| 63 |
+
# pip install "vesuvius[volume-only]"
|
| 64 |
+
from vesuvius import Volume
|
| 65 |
+
|
| 66 |
+
v = Volume(type="zarr", path="https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/2") # one pyramid level
|
| 67 |
+
block = v[2622:2686, 828:892, 828:892]
|
| 68 |
+
```
|
| 69 |
+
|
| 70 |
+
### VC3D (from villa's source)
|
| 71 |
+
|
| 72 |
+
```text
|
| 73 |
+
In VC3D (villa's volume-cartographer), open or create a project, then
|
| 74 |
+
File > Attach Remote Zarr... and paste:
|
| 75 |
+
|
| 76 |
+
https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr
|
| 77 |
+
|
| 78 |
+
It accepts http, https and s3 OME-Zarr roots.
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
### neuroglancer (tested 2026-10-24)
|
| 82 |
+
|
| 83 |
+
```text
|
| 84 |
+
https://neuroglancer-demo.appspot.com/#!%7B%22layers%22%3A%5B%7B%22type%22%3A%22image%22%2C%22source%22%3A%22zarr%3A%2F%2Fhttps%3A%2F%2Fvesuvius-challenge-open-data.s3.us-east-1.amazonaws.com%2FPHerc0139%2Fvolumes%2F20250728140407-9.362um-1.2m-113keV-masked.zarr%2F%22%2C%22name%22%3A%22X-ray%20CT%20behind%20the%20CT%20view%2C%20PHerc0139%209.362%20um%22%7D%5D%2C%22layout%22%3A%224panel%22%7D
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
### curl (tested 2026-10-24)
|
| 88 |
+
|
| 89 |
+
```bash
|
| 90 |
+
curl -s https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/.zattrs # OME multiscales metadata
|
| 91 |
+
curl -s https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/2/.zarray # one level: shape, chunks, dtype, codec
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
## Unroll's own API, files and embed
|
| 95 |
+
|
| 96 |
+
`https://sharpmeow-unroll.static.hf.space/`
|
| 97 |
+
|
| 98 |
+
License: Page code Apache 2.0; derived data CC BY-NC 4.0. Every button has a data-api name and the same call on window.unroll, so a script or an agent can drive the page.
|
| 99 |
+
|
| 100 |
+
### Links and embed (tested 2026-10-24)
|
| 101 |
+
|
| 102 |
+
```text
|
| 103 |
+
API description (window.unroll, postMessage, deep links): https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/api.json
|
| 104 |
+
Guide for agents: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/llms.txt
|
| 105 |
+
Scroll list and per-scroll manifests: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/scrolls/index.json
|
| 106 |
+
Ink Bench on the command line: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/tools/inkbench.py
|
| 107 |
+
Deep link to one winding: https://sharpmeow-unroll.static.hf.space/?scroll=PHerc0139&t=0.6&layer=overlay&focus=w047&compare=0.3
|
| 108 |
+
|
| 109 |
+
<iframe src="https://sharpmeow-unroll.static.hf.space/index.html?embed=1" width="100%" height="600" allow="fullscreen; clipboard-write"></iframe>
|
| 110 |
+
```
|
connect.html
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<section class="scc" id="connect" aria-label="Connect your tool"><style>.scc{--a:var(--scc-accent,#4ea8de);color:inherit;font:inherit;line-height:1.5;max-width:60rem}
|
| 2 |
+
.scc h2{font-size:1.15em;margin:.2em 0 .3em}.scc h3{font-size:1em;margin:0 0 .2em}
|
| 3 |
+
.scc p{margin:.3em 0}.scc a{color:var(--a)}
|
| 4 |
+
.scc .scc-src{border:1px solid color-mix(in srgb,currentColor 18%,transparent);border-radius:10px;padding:.7em .9em;margin:.7em 0;background:color-mix(in srgb,currentColor 4%,transparent)}
|
| 5 |
+
.scc .scc-meta{font-size:.85em;opacity:.8}
|
| 6 |
+
.scc details{border-top:1px solid color-mix(in srgb,currentColor 12%,transparent);padding:.35em 0}
|
| 7 |
+
.scc summary{cursor:pointer;font-weight:600;list-style-position:inside}
|
| 8 |
+
.scc .scc-b{font-weight:400;font-size:.75em;padding:.05em .5em;border-radius:99px;margin-left:.5em;border:1px solid currentColor;opacity:.75;white-space:nowrap}
|
| 9 |
+
.scc .scc-b.ok{color:#3fb37f}.scc .scc-b.src{color:var(--a)}.scc .scc-b.warn{color:#e0a030}
|
| 10 |
+
.scc .scc-code{position:relative;margin:.4em 0 .2em}
|
| 11 |
+
.scc pre{margin:0;padding:.7em .8em;border-radius:8px;overflow:auto;font-size:.82em;background:color-mix(in srgb,currentColor 9%,transparent);white-space:pre}
|
| 12 |
+
.scc code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
|
| 13 |
+
.scc button.scc-copy{all:unset;box-sizing:border-box;position:absolute;top:.35em;right:.35em;font-size:.75em;line-height:1.4;padding:.1em .6em;border-radius:6px;border:1px solid color-mix(in srgb,currentColor 30%,transparent);background:color-mix(in srgb,currentColor 8%,transparent);color:inherit;cursor:pointer}
|
| 14 |
+
.scc button.scc-copy:hover{border-color:var(--a)}
|
| 15 |
+
.scc .scc-url{position:relative}.scc .scc-url pre{padding-right:4.5em;white-space:pre-wrap;word-break:break-all}
|
| 16 |
+
.scc .scc-go{display:inline-block;margin:.3em 0;padding:.25em .8em;border-radius:6px;border:1px solid var(--a);text-decoration:none}
|
| 17 |
+
.scc footer{font-size:.8em;opacity:.75;margin-top:.6em}</style>
|
| 18 |
+
<h2>Connect your tool</h2>
|
| 19 |
+
<p>The traced windings, X-ray CT and ink layers in Unroll come from the Vesuvius Challenge open data, and every one of them reads straight from these URLs in your own tool, with no account and no download step.</p>
|
| 20 |
+
<div class="scc-src" id="connect-segment"><h3>A traced winding (tifxyz), example PHerc0841 w00</h3>
|
| 21 |
+
<p class="scc-meta">CC BY-NC 4.0 (Vesuvius Challenge open data) · Every winding Unroll shows has a folder like this under SCROLL/segments/ in the open data; Unroll keeps only a decimated copy for the browser.</p>
|
| 22 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0841/segments/20260220213127-w00/mesh/20260220213127-on-20250821151531-9.366um.tifxyz</code></pre></div>
|
| 23 |
+
<details><summary>Python (numpy, tifffile)<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 24 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install numpy tifffile
|
| 25 |
+
import io, json, urllib.request
|
| 26 |
+
import numpy as np, tifffile
|
| 27 |
+
|
| 28 |
+
T = "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0841/segments/20260220213127-w00/mesh/20260220213127-on-20250821151531-9.366um.tifxyz"
|
| 29 |
+
meta = json.load(urllib.request.urlopen(T + "/meta.json")) # scale, bbox, format
|
| 30 |
+
get = lambda c: tifffile.imread(io.BytesIO(urllib.request.urlopen(f"{T}/{c}.tif").read()))
|
| 31 |
+
xyz = np.stack([get(c) for c in "xyz"], -1) # xyz[i, j] = (x, y, z) in scan voxels; -1 = no surface</code></pre></div></details>
|
| 32 |
+
</div>
|
| 33 |
+
<div class="scc-src" id="connect-segments"><h3>Every segment of a scroll, example PHerc0841</h3>
|
| 34 |
+
<p class="scc-meta">CC BY-NC 4.0 (Vesuvius Challenge open data) · Each segment folder has mesh/ (tifxyz), surface-volumes/ (OME-Zarr layers) and, where published, ink-detection/. · <a href="https://scrollprize.org/data_browser/PHerc0841" target="_blank" rel="noopener">browse</a></p>
|
| 35 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>s3://vesuvius-challenge-open-data/PHerc0841/segments/</code></pre></div>
|
| 36 |
+
<details><summary>Python (list the folder)<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 37 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>import re, urllib.request
|
| 38 |
+
|
| 39 |
+
B = "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com"
|
| 40 |
+
xml = urllib.request.urlopen(B + "/?list-type=2&delimiter=/&prefix=PHerc0841/segments/").read().decode()
|
| 41 |
+
print(re.findall(r"<Prefix>([^<]+)</Prefix>", xml)) # subfolders; <Key> gives files</code></pre></div></details>
|
| 42 |
+
</div>
|
| 43 |
+
<div class="scc-src" id="connect-ct"><h3>X-ray CT behind the CT view, PHerc0139 9.362 um</h3>
|
| 44 |
+
<p class="scc-meta">CC BY-NC 4.0 (Vesuvius Challenge open data) · Streamed from the open-data bucket, never copied here. Unroll opens any other scan with ?ctzarr=URL&ctum=VOXEL_UM. · <a href="https://scrollprize.org/data_browser/PHerc0139" target="_blank" rel="noopener">browse</a></p>
|
| 45 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr</code></pre></div>
|
| 46 |
+
<details><summary>Python (zarr)<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 47 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install "zarr>=3" fsspec aiohttp
|
| 48 |
+
import zarr
|
| 49 |
+
|
| 50 |
+
root = zarr.open_group("https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr", mode="r") # OME-Zarr, zarr v2
|
| 51 |
+
a = root["2"] # level 0 is full resolution; level L is 2**L times coarser
|
| 52 |
+
print(a.shape, a.dtype, a.chunks)
|
| 53 |
+
block = a[2622:2686, 828:892, 828:892] # (z, y, x); reads only the chunks it touches</code></pre></div></details>
|
| 54 |
+
<details><summary>villa's vesuvius package<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 55 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install "vesuvius[volume-only]"
|
| 56 |
+
from vesuvius import Volume
|
| 57 |
+
|
| 58 |
+
v = Volume(type="zarr", path="https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/2") # one pyramid level
|
| 59 |
+
block = v[2622:2686, 828:892, 828:892]</code></pre></div></details>
|
| 60 |
+
<details><summary>VC3D<span class="scc-b src">from villa's source</span></summary>
|
| 61 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>In VC3D (villa's volume-cartographer), open or create a project, then
|
| 62 |
+
File > Attach Remote Zarr... and paste:
|
| 63 |
+
|
| 64 |
+
https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr
|
| 65 |
+
|
| 66 |
+
It accepts http, https and s3 OME-Zarr roots.</code></pre></div></details>
|
| 67 |
+
<details><summary>neuroglancer<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 68 |
+
<a class="scc-go" href="https://neuroglancer-demo.appspot.com/#!%7B%22layers%22%3A%5B%7B%22type%22%3A%22image%22%2C%22source%22%3A%22zarr%3A%2F%2Fhttps%3A%2F%2Fvesuvius-challenge-open-data.s3.us-east-1.amazonaws.com%2FPHerc0139%2Fvolumes%2F20250728140407-9.362um-1.2m-113keV-masked.zarr%2F%22%2C%22name%22%3A%22X-ray%20CT%20behind%20the%20CT%20view%2C%20PHerc0139%209.362%20um%22%7D%5D%2C%22layout%22%3A%224panel%22%7D" target="_blank" rel="noopener">Open in neuroglancer</a>
|
| 69 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://neuroglancer-demo.appspot.com/#!%7B%22layers%22%3A%5B%7B%22type%22%3A%22image%22%2C%22source%22%3A%22zarr%3A%2F%2Fhttps%3A%2F%2Fvesuvius-challenge-open-data.s3.us-east-1.amazonaws.com%2FPHerc0139%2Fvolumes%2F20250728140407-9.362um-1.2m-113keV-masked.zarr%2F%22%2C%22name%22%3A%22X-ray%20CT%20behind%20the%20CT%20view%2C%20PHerc0139%209.362%20um%22%7D%5D%2C%22layout%22%3A%224panel%22%7D</code></pre></div></details>
|
| 70 |
+
<details><summary>curl<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 71 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>curl -s https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/.zattrs # OME multiscales metadata
|
| 72 |
+
curl -s https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/2/.zarray # one level: shape, chunks, dtype, codec</code></pre></div></details>
|
| 73 |
+
</div>
|
| 74 |
+
<div class="scc-src" id="connect-page"><h3>Unroll's own API, files and embed</h3>
|
| 75 |
+
<p class="scc-meta">Page code Apache 2.0; derived data CC BY-NC 4.0 · Every button has a data-api name and the same call on window.unroll, so a script or an agent can drive the page.</p>
|
| 76 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://sharpmeow-unroll.static.hf.space/</code></pre></div>
|
| 77 |
+
<details><summary>Links and embed<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 78 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>API description (window.unroll, postMessage, deep links): https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/api.json
|
| 79 |
+
Guide for agents: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/llms.txt
|
| 80 |
+
Scroll list and per-scroll manifests: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/scrolls/index.json
|
| 81 |
+
Ink Bench on the command line: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/tools/inkbench.py
|
| 82 |
+
Deep link to one winding: https://sharpmeow-unroll.static.hf.space/?scroll=PHerc0139&t=0.6&layer=overlay&focus=w047&compare=0.3
|
| 83 |
+
|
| 84 |
+
<iframe src="https://sharpmeow-unroll.static.hf.space/index.html?embed=1" width="100%" height="600" allow="fullscreen; clipboard-write"></iframe></code></pre></div></details>
|
| 85 |
+
</div>
|
| 86 |
+
<footer>Machine-readable: <a href="https://huggingface.co/spaces/SharpMeow/unroll/blob/main/connect.json" target="_blank" rel="noopener">connect.json</a> and <a href="https://huggingface.co/spaces/SharpMeow/unroll/blob/main/CONNECT.md" target="_blank" rel="noopener">CONNECT.md</a>. Checked 2026-10-24. "Tested" means the snippet ran against this public data on that date. Scan data keeps its own license (the Vesuvius Challenge open data is CC BY-NC 4.0).</footer></section>
|
connect.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema": "space-connect/1",
|
| 3 |
+
"space": "SharpMeow/unroll",
|
| 4 |
+
"title": "Unroll",
|
| 5 |
+
"checked": "2026-10-24",
|
| 6 |
+
"intro": "The traced windings, X-ray CT and ink layers in Unroll come from the Vesuvius Challenge open data, and every one of them reads straight from these URLs in your own tool, with no account and no download step.",
|
| 7 |
+
"sources": [
|
| 8 |
+
{"id": "segment", "title": "A traced winding (tifxyz), example PHerc0841 w00", "kind": "tifxyz",
|
| 9 |
+
"url": "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0841/segments/20260220213127-w00/mesh/20260220213127-on-20250821151531-9.366um.tifxyz",
|
| 10 |
+
"license": "CC BY-NC 4.0 (Vesuvius Challenge open data)",
|
| 11 |
+
"note": "Every winding Unroll shows has a folder like this under SCROLL/segments/ in the open data; Unroll keeps only a decimated copy for the browser."},
|
| 12 |
+
{"id": "segments", "title": "Every segment of a scroll, example PHerc0841", "kind": "s3-prefix",
|
| 13 |
+
"url": "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com", "prefix": "PHerc0841/segments/",
|
| 14 |
+
"license": "CC BY-NC 4.0 (Vesuvius Challenge open data)",
|
| 15 |
+
"note": "Each segment folder has mesh/ (tifxyz), surface-volumes/ (OME-Zarr layers) and, where published, ink-detection/.",
|
| 16 |
+
"browse": "https://scrollprize.org/data_browser/PHerc0841"},
|
| 17 |
+
{"id": "ct", "title": "X-ray CT behind the CT view, PHerc0139 9.362 um", "kind": "ome-zarr",
|
| 18 |
+
"url": "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr",
|
| 19 |
+
"zarr_format": 2, "example": {"level": "2", "start": [2622, 828, 828]},
|
| 20 |
+
"license": "CC BY-NC 4.0 (Vesuvius Challenge open data)",
|
| 21 |
+
"note": "Streamed from the open-data bucket, never copied here. Unroll opens any other scan with ?ctzarr=URL&ctum=VOXEL_UM.",
|
| 22 |
+
"browse": "https://scrollprize.org/data_browser/PHerc0139"},
|
| 23 |
+
{"id": "page", "title": "Unroll's own API, files and embed", "kind": "page-api",
|
| 24 |
+
"url": "https://sharpmeow-unroll.static.hf.space/",
|
| 25 |
+
"links": [{"label": "API description (window.unroll, postMessage, deep links)", "url": "https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/api.json"},
|
| 26 |
+
{"label": "Guide for agents", "url": "https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/llms.txt"},
|
| 27 |
+
{"label": "Scroll list and per-scroll manifests", "url": "https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/scrolls/index.json"},
|
| 28 |
+
{"label": "Ink Bench on the command line", "url": "https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/tools/inkbench.py"},
|
| 29 |
+
{"label": "Deep link to one winding", "url": "https://sharpmeow-unroll.static.hf.space/?scroll=PHerc0139&t=0.6&layer=overlay&focus=w047&compare=0.3"}],
|
| 30 |
+
"embed": "https://sharpmeow-unroll.static.hf.space/index.html?embed=1",
|
| 31 |
+
"license": "Page code Apache 2.0; derived data CC BY-NC 4.0",
|
| 32 |
+
"note": "Every button has a data-api name and the same call on window.unroll, so a script or an agent can drive the page."}
|
| 33 |
+
]
|
| 34 |
+
}
|
index.html
CHANGED
|
@@ -139,7 +139,7 @@ if (!/(^|[#&])s=/.test(location.hash)) ['scrolls/index.json', 'scrolls/PHerc0139
|
|
| 139 |
<button class="icon" id="btnOpen" data-testid="open-own" data-api="panel('open')" title="Open your own scroll: files stay in your browser, nothing is uploaded" aria-label="Open your own scroll">+</button>
|
| 140 |
<button class="icon" id="btnBench" data-testid="bench" data-api="bench.open()" title="Ink Bench: score your own ink prediction against the published ink. Runs in your browser, nothing is uploaded" aria-label="Ink Bench"><svg viewBox="0 0 24 24" width="15" height="15"><path d="M4 19V9M10 19V5M16 19v-7M21 19H3" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button>
|
| 141 |
<button class="icon" id="btnInfo" data-testid="about" data-api="panel('about')" title="About this page" aria-label="About">i</button>
|
| 142 |
-
<button class="icon" id="btnEmbed" data-testid="embed" data-api="panel('embed')" title="Embed this viewer on your site" aria-label="Embed this viewer"></></button>
|
| 143 |
<button class="icon" id="btnFull" data-testid="fullscreen" data-api="fullscreen()" title="Fullscreen" aria-label="Fullscreen" aria-pressed="false">
|
| 144 |
<svg viewBox="0 0 24 24" width="15" height="15"><path d="M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5" fill="none" stroke="currentColor" stroke-width="1.5"/></svg>
|
| 145 |
</button>
|
|
@@ -232,12 +232,12 @@ if (!/(^|[#&])s=/.test(location.hash)) ['scrolls/index.json', 'scrolls/PHerc0139
|
|
| 232 |
<p class="mono dim small">Sources: open data bucket <code>PHerc0139/segments/*/mesh/*9.362um.tifxyz</code>, <code>surface-volumes/9.362um…zarr</code> and <code>ink-detection/downsampled</code>. Data: Giorgio Angelotti, Stephen Parsons, Sean Johnson, Elian Rafael Dal Prà, Johannes Rudolph, Paul Tafforeau, Alessandro Mirone, Paul Henderson, Hendrik Schilling, Forrest McDonald, David Josey, Youssef Nader, C. Seth Parker, W. Brent Seales. <i>Vesuvius Challenge - CT Scans of Herculaneum Papyri.</i> Vesuvius Challenge. Licensed <a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY‑NC 4.0</a>. The page's code (HTML, CSS, JS and <code>tools/</code>) is Apache 2.0; see the Space's README.</p>
|
| 233 |
<p class="mono dim small made-by">Made by Chase Hendrick.</p>
|
| 234 |
</div>
|
| 235 |
-
<div class="sheet-foot mono dim small about-foot"><span>For agents: <a href="llms.txt" target="_blank" rel="noopener">llms.txt</a> · <a href="AGENTS.md" target="_blank" rel="noopener">AGENTS.md</a> · <a href="api.json" target="_blank" rel="noopener">api.json</a></span> <span id="aVersion" class="version" data-testid="version" title="Version and build (CHANGELOG.md)"></span></div>
|
| 236 |
</section>
|
| 237 |
|
| 238 |
<section id="embedSheet" class="sheet about" role="dialog" aria-modal="false" aria-labelledby="eTitle" hidden data-testid="embed-panel">
|
| 239 |
<div class="sheet-head">
|
| 240 |
-
<div><div class="mono dim">EMBED</div><h2 id="eTitle">Put this viewer on your site</h2></div>
|
| 241 |
<button class="icon" id="eClose" data-testid="embed-close" data-api="panel('embed', false)" aria-label="Close">✕</button>
|
| 242 |
</div>
|
| 243 |
<div class="about-body">
|
|
@@ -248,6 +248,94 @@ if (!/(^|[#&])s=/.test(location.hash)) ['scrolls/index.json', 'scrolls/PHerc0139
|
|
| 248 |
<textarea id="embedCode" class="embed-code mono" rows="5" readonly aria-label="Embed code" data-testid="embed-code" data-api="embed.snippet()"></textarea>
|
| 249 |
<p><button class="chip" id="embedCopy" data-testid="embed-copy" data-api="embed.snippet()">Copy</button> <a id="embedPreviewURL" href="./" target="_blank" rel="noopener" data-testid="embed-preview" data-api="embed.snippet()">Preview the embed</a></p>
|
| 250 |
<p class="mono dim small">oEmbed: <a href="oembed.json" target="_blank" rel="noopener">/oembed.json</a>. Host pages can drive the viewer with postMessage; see <a href="docs/EMBED.md" target="_blank" rel="noopener">EMBED.md</a>.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
</div>
|
| 252 |
</section>
|
| 253 |
|
|
|
|
| 139 |
<button class="icon" id="btnOpen" data-testid="open-own" data-api="panel('open')" title="Open your own scroll: files stay in your browser, nothing is uploaded" aria-label="Open your own scroll">+</button>
|
| 140 |
<button class="icon" id="btnBench" data-testid="bench" data-api="bench.open()" title="Ink Bench: score your own ink prediction against the published ink. Runs in your browser, nothing is uploaded" aria-label="Ink Bench"><svg viewBox="0 0 24 24" width="15" height="15"><path d="M4 19V9M10 19V5M16 19v-7M21 19H3" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button>
|
| 141 |
<button class="icon" id="btnInfo" data-testid="about" data-api="panel('about')" title="About this page" aria-label="About">i</button>
|
| 142 |
+
<button class="icon" id="btnEmbed" data-testid="embed" data-api="panel('embed')" title="Embed this viewer on your site, or connect your tool to its data" aria-label="Embed this viewer or connect your tool"></></button>
|
| 143 |
<button class="icon" id="btnFull" data-testid="fullscreen" data-api="fullscreen()" title="Fullscreen" aria-label="Fullscreen" aria-pressed="false">
|
| 144 |
<svg viewBox="0 0 24 24" width="15" height="15"><path d="M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5" fill="none" stroke="currentColor" stroke-width="1.5"/></svg>
|
| 145 |
</button>
|
|
|
|
| 232 |
<p class="mono dim small">Sources: open data bucket <code>PHerc0139/segments/*/mesh/*9.362um.tifxyz</code>, <code>surface-volumes/9.362um…zarr</code> and <code>ink-detection/downsampled</code>. Data: Giorgio Angelotti, Stephen Parsons, Sean Johnson, Elian Rafael Dal Prà, Johannes Rudolph, Paul Tafforeau, Alessandro Mirone, Paul Henderson, Hendrik Schilling, Forrest McDonald, David Josey, Youssef Nader, C. Seth Parker, W. Brent Seales. <i>Vesuvius Challenge - CT Scans of Herculaneum Papyri.</i> Vesuvius Challenge. Licensed <a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY‑NC 4.0</a>. The page's code (HTML, CSS, JS and <code>tools/</code>) is Apache 2.0; see the Space's README.</p>
|
| 233 |
<p class="mono dim small made-by">Made by Chase Hendrick.</p>
|
| 234 |
</div>
|
| 235 |
+
<div class="sheet-foot mono dim small about-foot"><span><a href="#connect" onclick="document.getElementById('btnEmbed').click();setTimeout(()=>document.getElementById('connect').scrollIntoView({behavior:'smooth'}),50);return false">Connect your tool</a> · For agents: <a href="llms.txt" target="_blank" rel="noopener">llms.txt</a> · <a href="AGENTS.md" target="_blank" rel="noopener">AGENTS.md</a> · <a href="api.json" target="_blank" rel="noopener">api.json</a></span> <span id="aVersion" class="version" data-testid="version" title="Version and build (CHANGELOG.md)"></span></div>
|
| 236 |
</section>
|
| 237 |
|
| 238 |
<section id="embedSheet" class="sheet about" role="dialog" aria-modal="false" aria-labelledby="eTitle" hidden data-testid="embed-panel">
|
| 239 |
<div class="sheet-head">
|
| 240 |
+
<div><div class="mono dim">EMBED</div><h2 id="eTitle">Put this viewer on your site, or its data in your tool</h2></div>
|
| 241 |
<button class="icon" id="eClose" data-testid="embed-close" data-api="panel('embed', false)" aria-label="Close">✕</button>
|
| 242 |
</div>
|
| 243 |
<div class="about-body">
|
|
|
|
| 248 |
<textarea id="embedCode" class="embed-code mono" rows="5" readonly aria-label="Embed code" data-testid="embed-code" data-api="embed.snippet()"></textarea>
|
| 249 |
<p><button class="chip" id="embedCopy" data-testid="embed-copy" data-api="embed.snippet()">Copy</button> <a id="embedPreviewURL" href="./" target="_blank" rel="noopener" data-testid="embed-preview" data-api="embed.snippet()">Preview the embed</a></p>
|
| 250 |
<p class="mono dim small">oEmbed: <a href="oembed.json" target="_blank" rel="noopener">/oembed.json</a>. Host pages can drive the viewer with postMessage; see <a href="docs/EMBED.md" target="_blank" rel="noopener">EMBED.md</a>.</p>
|
| 251 |
+
<!-- space-connect:start -->
|
| 252 |
+
<section class="scc" id="connect" aria-label="Connect your tool"><style>.scc{--a:var(--scc-accent,#4ea8de);color:inherit;font:inherit;line-height:1.5;max-width:60rem}
|
| 253 |
+
.scc h2{font-size:1.15em;margin:.2em 0 .3em}.scc h3{font-size:1em;margin:0 0 .2em}
|
| 254 |
+
.scc p{margin:.3em 0}.scc a{color:var(--a)}
|
| 255 |
+
.scc .scc-src{border:1px solid color-mix(in srgb,currentColor 18%,transparent);border-radius:10px;padding:.7em .9em;margin:.7em 0;background:color-mix(in srgb,currentColor 4%,transparent)}
|
| 256 |
+
.scc .scc-meta{font-size:.85em;opacity:.8}
|
| 257 |
+
.scc details{border-top:1px solid color-mix(in srgb,currentColor 12%,transparent);padding:.35em 0}
|
| 258 |
+
.scc summary{cursor:pointer;font-weight:600;list-style-position:inside}
|
| 259 |
+
.scc .scc-b{font-weight:400;font-size:.75em;padding:.05em .5em;border-radius:99px;margin-left:.5em;border:1px solid currentColor;opacity:.75;white-space:nowrap}
|
| 260 |
+
.scc .scc-b.ok{color:#3fb37f}.scc .scc-b.src{color:var(--a)}.scc .scc-b.warn{color:#e0a030}
|
| 261 |
+
.scc .scc-code{position:relative;margin:.4em 0 .2em}
|
| 262 |
+
.scc pre{margin:0;padding:.7em .8em;border-radius:8px;overflow:auto;font-size:.82em;background:color-mix(in srgb,currentColor 9%,transparent);white-space:pre}
|
| 263 |
+
.scc code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
|
| 264 |
+
.scc button.scc-copy{all:unset;box-sizing:border-box;position:absolute;top:.35em;right:.35em;font-size:.75em;line-height:1.4;padding:.1em .6em;border-radius:6px;border:1px solid color-mix(in srgb,currentColor 30%,transparent);background:color-mix(in srgb,currentColor 8%,transparent);color:inherit;cursor:pointer}
|
| 265 |
+
.scc button.scc-copy:hover{border-color:var(--a)}
|
| 266 |
+
.scc .scc-url{position:relative}.scc .scc-url pre{padding-right:4.5em;white-space:pre-wrap;word-break:break-all}
|
| 267 |
+
.scc .scc-go{display:inline-block;margin:.3em 0;padding:.25em .8em;border-radius:6px;border:1px solid var(--a);text-decoration:none}
|
| 268 |
+
.scc footer{font-size:.8em;opacity:.75;margin-top:.6em}</style>
|
| 269 |
+
<h2>Connect your tool</h2>
|
| 270 |
+
<p>The traced windings, X-ray CT and ink layers in Unroll come from the Vesuvius Challenge open data, and every one of them reads straight from these URLs in your own tool, with no account and no download step.</p>
|
| 271 |
+
<div class="scc-src" id="connect-segment"><h3>A traced winding (tifxyz), example PHerc0841 w00</h3>
|
| 272 |
+
<p class="scc-meta">CC BY-NC 4.0 (Vesuvius Challenge open data) · Every winding Unroll shows has a folder like this under SCROLL/segments/ in the open data; Unroll keeps only a decimated copy for the browser.</p>
|
| 273 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0841/segments/20260220213127-w00/mesh/20260220213127-on-20250821151531-9.366um.tifxyz</code></pre></div>
|
| 274 |
+
<details><summary>Python (numpy, tifffile)<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 275 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install numpy tifffile
|
| 276 |
+
import io, json, urllib.request
|
| 277 |
+
import numpy as np, tifffile
|
| 278 |
+
|
| 279 |
+
T = "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0841/segments/20260220213127-w00/mesh/20260220213127-on-20250821151531-9.366um.tifxyz"
|
| 280 |
+
meta = json.load(urllib.request.urlopen(T + "/meta.json")) # scale, bbox, format
|
| 281 |
+
get = lambda c: tifffile.imread(io.BytesIO(urllib.request.urlopen(f"{T}/{c}.tif").read()))
|
| 282 |
+
xyz = np.stack([get(c) for c in "xyz"], -1) # xyz[i, j] = (x, y, z) in scan voxels; -1 = no surface</code></pre></div></details>
|
| 283 |
+
</div>
|
| 284 |
+
<div class="scc-src" id="connect-segments"><h3>Every segment of a scroll, example PHerc0841</h3>
|
| 285 |
+
<p class="scc-meta">CC BY-NC 4.0 (Vesuvius Challenge open data) · Each segment folder has mesh/ (tifxyz), surface-volumes/ (OME-Zarr layers) and, where published, ink-detection/. · <a href="https://scrollprize.org/data_browser/PHerc0841" target="_blank" rel="noopener">browse</a></p>
|
| 286 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>s3://vesuvius-challenge-open-data/PHerc0841/segments/</code></pre></div>
|
| 287 |
+
<details><summary>Python (list the folder)<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 288 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>import re, urllib.request
|
| 289 |
+
|
| 290 |
+
B = "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com"
|
| 291 |
+
xml = urllib.request.urlopen(B + "/?list-type=2&delimiter=/&prefix=PHerc0841/segments/").read().decode()
|
| 292 |
+
print(re.findall(r"<Prefix>([^<]+)</Prefix>", xml)) # subfolders; <Key> gives files</code></pre></div></details>
|
| 293 |
+
</div>
|
| 294 |
+
<div class="scc-src" id="connect-ct"><h3>X-ray CT behind the CT view, PHerc0139 9.362 um</h3>
|
| 295 |
+
<p class="scc-meta">CC BY-NC 4.0 (Vesuvius Challenge open data) · Streamed from the open-data bucket, never copied here. Unroll opens any other scan with ?ctzarr=URL&ctum=VOXEL_UM. · <a href="https://scrollprize.org/data_browser/PHerc0139" target="_blank" rel="noopener">browse</a></p>
|
| 296 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr</code></pre></div>
|
| 297 |
+
<details><summary>Python (zarr)<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 298 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install "zarr>=3" fsspec aiohttp
|
| 299 |
+
import zarr
|
| 300 |
+
|
| 301 |
+
root = zarr.open_group("https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr", mode="r") # OME-Zarr, zarr v2
|
| 302 |
+
a = root["2"] # level 0 is full resolution; level L is 2**L times coarser
|
| 303 |
+
print(a.shape, a.dtype, a.chunks)
|
| 304 |
+
block = a[2622:2686, 828:892, 828:892] # (z, y, x); reads only the chunks it touches</code></pre></div></details>
|
| 305 |
+
<details><summary>villa's vesuvius package<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 306 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install "vesuvius[volume-only]"
|
| 307 |
+
from vesuvius import Volume
|
| 308 |
+
|
| 309 |
+
v = Volume(type="zarr", path="https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/2") # one pyramid level
|
| 310 |
+
block = v[2622:2686, 828:892, 828:892]</code></pre></div></details>
|
| 311 |
+
<details><summary>VC3D<span class="scc-b src">from villa's source</span></summary>
|
| 312 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>In VC3D (villa's volume-cartographer), open or create a project, then
|
| 313 |
+
File > Attach Remote Zarr... and paste:
|
| 314 |
+
|
| 315 |
+
https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr
|
| 316 |
+
|
| 317 |
+
It accepts http, https and s3 OME-Zarr roots.</code></pre></div></details>
|
| 318 |
+
<details><summary>neuroglancer<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 319 |
+
<a class="scc-go" href="https://neuroglancer-demo.appspot.com/#!%7B%22layers%22%3A%5B%7B%22type%22%3A%22image%22%2C%22source%22%3A%22zarr%3A%2F%2Fhttps%3A%2F%2Fvesuvius-challenge-open-data.s3.us-east-1.amazonaws.com%2FPHerc0139%2Fvolumes%2F20250728140407-9.362um-1.2m-113keV-masked.zarr%2F%22%2C%22name%22%3A%22X-ray%20CT%20behind%20the%20CT%20view%2C%20PHerc0139%209.362%20um%22%7D%5D%2C%22layout%22%3A%224panel%22%7D" target="_blank" rel="noopener">Open in neuroglancer</a>
|
| 320 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://neuroglancer-demo.appspot.com/#!%7B%22layers%22%3A%5B%7B%22type%22%3A%22image%22%2C%22source%22%3A%22zarr%3A%2F%2Fhttps%3A%2F%2Fvesuvius-challenge-open-data.s3.us-east-1.amazonaws.com%2FPHerc0139%2Fvolumes%2F20250728140407-9.362um-1.2m-113keV-masked.zarr%2F%22%2C%22name%22%3A%22X-ray%20CT%20behind%20the%20CT%20view%2C%20PHerc0139%209.362%20um%22%7D%5D%2C%22layout%22%3A%224panel%22%7D</code></pre></div></details>
|
| 321 |
+
<details><summary>curl<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 322 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>curl -s https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/.zattrs # OME multiscales metadata
|
| 323 |
+
curl -s https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr/2/.zarray # one level: shape, chunks, dtype, codec</code></pre></div></details>
|
| 324 |
+
</div>
|
| 325 |
+
<div class="scc-src" id="connect-page"><h3>Unroll's own API, files and embed</h3>
|
| 326 |
+
<p class="scc-meta">Page code Apache 2.0; derived data CC BY-NC 4.0 · Every button has a data-api name and the same call on window.unroll, so a script or an agent can drive the page.</p>
|
| 327 |
+
<div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://sharpmeow-unroll.static.hf.space/</code></pre></div>
|
| 328 |
+
<details><summary>Links and embed<span class="scc-b ok">tested 2026-10-24</span></summary>
|
| 329 |
+
<div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>API description (window.unroll, postMessage, deep links): https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/api.json
|
| 330 |
+
Guide for agents: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/llms.txt
|
| 331 |
+
Scroll list and per-scroll manifests: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/scrolls/index.json
|
| 332 |
+
Ink Bench on the command line: https://huggingface.co/spaces/SharpMeow/unroll/resolve/main/tools/inkbench.py
|
| 333 |
+
Deep link to one winding: https://sharpmeow-unroll.static.hf.space/?scroll=PHerc0139&t=0.6&layer=overlay&focus=w047&compare=0.3
|
| 334 |
+
|
| 335 |
+
<iframe src="https://sharpmeow-unroll.static.hf.space/index.html?embed=1" width="100%" height="600" allow="fullscreen; clipboard-write"></iframe></code></pre></div></details>
|
| 336 |
+
</div>
|
| 337 |
+
<footer>Machine-readable: <a href="https://huggingface.co/spaces/SharpMeow/unroll/blob/main/connect.json" target="_blank" rel="noopener">connect.json</a> and <a href="https://huggingface.co/spaces/SharpMeow/unroll/blob/main/CONNECT.md" target="_blank" rel="noopener">CONNECT.md</a>. Checked 2026-10-24. "Tested" means the snippet ran against this public data on that date. Scan data keeps its own license (the Vesuvius Challenge open data is CC BY-NC 4.0).</footer></section>
|
| 338 |
+
<!-- space-connect:end -->
|
| 339 |
</div>
|
| 340 |
</section>
|
| 341 |
|
llms.txt
CHANGED
|
@@ -11,6 +11,7 @@
|
|
| 11 |
- [Adding a scroll](/docs/ADDING_A_SCROLL.md): the manifest format and the precompute pipeline
|
| 12 |
- [EMBED.md](/docs/EMBED.md): embedding in an iframe and the postMessage API
|
| 13 |
- [oembed.json](/oembed.json): oEmbed
|
|
|
|
| 14 |
- [CHANGELOG.md](/CHANGELOG.md): versions; the current one is in /version.json
|
| 15 |
|
| 16 |
## Quick start
|
|
|
|
| 11 |
- [Adding a scroll](/docs/ADDING_A_SCROLL.md): the manifest format and the precompute pipeline
|
| 12 |
- [EMBED.md](/docs/EMBED.md): embedding in an iframe and the postMessage API
|
| 13 |
- [oembed.json](/oembed.json): oEmbed
|
| 14 |
+
- [CONNECT.md](/CONNECT.md): read the data behind the page from your own tool (Python, villa, VC3D, neuroglancer, curl); machine-readable in [connect.json](/connect.json)
|
| 15 |
- [CHANGELOG.md](/CHANGELOG.md): versions; the current one is in /version.json
|
| 16 |
|
| 17 |
## Quick start
|
version.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
{
|
| 2 |
"name": "unroll",
|
| 3 |
-
"version": "1.
|
| 4 |
-
"date": "2026-10-
|
| 5 |
-
"sha": "
|
| 6 |
"license": "Apache-2.0",
|
| 7 |
"data_license": "CC-BY-NC-4.0",
|
| 8 |
"shaNote": "Short SHA of the commit this build was stamped on (its parent, since a commit cannot contain its own hash). Run node tools/stamp_version.mjs patch before each push.",
|
|
|
|
| 1 |
{
|
| 2 |
"name": "unroll",
|
| 3 |
+
"version": "1.6.0",
|
| 4 |
+
"date": "2026-10-24",
|
| 5 |
+
"sha": "e31bb23",
|
| 6 |
"license": "Apache-2.0",
|
| 7 |
"data_license": "CC-BY-NC-4.0",
|
| 8 |
"shaNote": "Short SHA of the commit this build was stamped on (its parent, since a commit cannot contain its own hash). Run node tools/stamp_version.mjs patch before each push.",
|