diff --git a/.agents/skills/nebula-lab/SKILL.md b/.agents/skills/nebula-lab/SKILL.md index 9f9c908821..c2f2de58c3 100644 --- a/.agents/skills/nebula-lab/SKILL.md +++ b/.agents/skills/nebula-lab/SKILL.md @@ -31,6 +31,17 @@ angle — leaves on every side. Slabs pack into per-axis atlases for delivery. I handoff explicitly: brightness and colour agreement between banks is an acceptance criterion, not a detail. +New compiler and sampled-volume deliveries target **500 total retained scene elements**, +including stars, every optical slab copy, impostors and wrappers. Reserve their actual costs +before planning XYZ intervals; 500 slabs is not a 500-element scene. Prefer source-backed +slab emission for unresolved or dense light, and use fewer separate catalogue stars where +the evidence supports that representation. Never count the same light in both, invent stellar +depths, or silently discard retained stars to fit the quota. Preserve the saved plan and +cost receipt for replay and all component mixtures. A planning estimate is not visual +acceptance; keep the actual brightness/detail/handoff gates. Historical pinned deliveries +remain unchanged and report when over budget. See +`labs/nebula/docs/emission-compiler.md#automatic-layer-budget` before changing this step. + ## Packages and boundaries `labs/nebula/packages/{lab,volume-core,volume-bake,reconstruction,volume-viewer}`. @@ -71,7 +82,28 @@ Pick by what the evidence supports, not by habit. Two-scale in one line: broad light is `gain(x,y) × prior(x,y,z)` with `gain = fraction × blur(image) / blur(column)`; finite components fit the residual at prior-supported depths, so image brightness scales the envelope and never moves it in depth. Example recipe: `labs/nebula/models/smc/constrained/emission-envelope-ellipsoid.json`, with its method note beside it. -**Lenses:** every image recolours one shared geometry, so switching lens changes colour, never shape. **The prior is a hypothesis, never a measurement** — prefer one that scores better against observations; for the SMC a VMC-constrained ellipsoid beat the tidal simulation (withheld deviance 0.457 vs 0.601). +**RGB-only lenses:** every image recolours one shared geometry, so switching lens changes colour, never shape. **The prior is a hypothesis, never a measurement** — prefer one that scores better against observations; for the SMC a VMC-constrained ellipsoid beat the tidal simulation (withheld deviance 0.457 vs 0.601). + +## Numerical alignment before image inspection + +Diagnose alignment numerically before judging screenshots or rebaking. Use the configured +lenses as independent checks of the shared coordinate transport; different spectral structures +and brightness are expected, so do not force their pixels to match. + +- Check registered landmarks or matched stars in the common sky frame: translation, scale, + rotation, handedness, footprints and held-out residuals in pixels/arcseconds. Verify the same + points through source, prepared geometry and camera projection. +- Compare shared geometry/alpha across RGB-only lenses. For declared component mixtures, + compare the shared frame, slab intervals and layout while preserving legitimate support + differences. Use spatial residuals, not histogram agreement, to establish alignment. +- Separate registration error from material, sampling and browser compositing error. Compare + analytic projections, decoded baked values and rendered pixel measurements at the same + camera. Fix the owner identified by those measurements; do not compensate with a display + offset or assume that every failed image metric proves misregistration. +- Run capture analysis locally and return compact numerical reports. Keep captures on disk; + do not routinely load them into model context. Inspect an image only for a named question + that the numbers cannot settle, a required final visual check, or an explicit user request; + use the smallest useful crop and fewest images. ## Matching a lens to its image @@ -143,6 +175,17 @@ server route you can call directly, so an agent sees exactly what a person sees. | --- | --- | --- | | Levels | `GET /__nebula/reconstruction-levels?resultId=` | per-channel histograms, signed delta, transfer curve, percentile ratios | | Difference map | `GET /__nebula/reconstruction-difference?resultId=` (`&format=png` for the image) | render − image on luminance, over the Earth view: blue too dark, red too bright, clear within tolerance | +| Radial profile | `GET /__nebula/reconstruction-radial?resultId=` | azimuthally averaged source/render brightness in radial bins from the footprint centroid, per-bin ratio and delta, half-light radius ratio | + +**Radial profile answers what the other two cannot: does brightness fall off with radius like the source?** +Levels is a histogram and spatially blind — it can match p50/p90/p99 exactly while the structure sits in the +wrong place (a brightness swap between the centre and an annulus conserves the histogram outright). The +difference map shows *where* the error is but not its radial shape. The radial profile's own control is that +swap: a permutation of the same pixel values that moves brightness from the core to the rim reads as p50/p90 +ratio 1.00 in Levels while the radial profile's per-bin ratio runs from ~0 at the centre to tens at the rim +and its half-light radius is pushed outward. A pure scale error (render radially compressed or expanded) is +caught by the half-light radius ratio instead. Highest value for a centrally concentrated, near-spherical +subject. **Read the difference map for *where*, the levels for *how much*.** On the LMC it showed the bar blue (core too dark, the opacity shoulder) and the body a red ring (mid-tones too bright), which diff --git a/.github/workflows/universe.yml b/.github/workflows/universe.yml index 94881af093..1472396b40 100644 --- a/.github/workflows/universe.yml +++ b/.github/workflows/universe.yml @@ -409,6 +409,7 @@ jobs: run: >- node --test tools/prepare-context-availability.test.mts site/test/prepared-context-navigation.test.mts + site/test/galactic-focus.test.mts site/test/prepared-focus-card.test.mts site/test/volume-presentation.test.mts - name: Restore environment images and prepare minimap run: | @@ -591,7 +592,8 @@ jobs: node labs/nebula/run.mts test overlay-placement overlay-registration overlay-alignment field-tilt emission-window component-material material - point-projection cloud-inspection compact + point-projection cloud-inspection compact shape-cloud-camera + nebula-frame bake compiler-sampling render-element-budget retained-material-bank optical-composite-preparation detect-shapes structure-wavelets structure-map ridge-graph material-solver shape-prior solver acquisition footprint image-links image-ranking @@ -601,6 +603,8 @@ jobs: workspace-sections workspace-portals workspace-objects camera-model-panel image-appearance-panel catalogue object-browser papers survey-images geometry-model observation-alignment structures-model + build lens-levels lens-difference lens-radial lens-radial-panel + registration photometric-mge photometric-prior compiler-defaults simulation-guided compiler-published ci-guard: name: Report the first CI failure diff --git a/.gitignore b/.gitignore index 78f1784a17..1627840826 100644 --- a/.gitignore +++ b/.gitignore @@ -215,6 +215,9 @@ src/objects/*/source/**/*.bpc # the accepted bytes instead of replaying them (`--verify-replay` still can). /labs/nebula/models/*/candidates/prepared/*.webp /labs/nebula/models/*/clouds-observation/source/target.png +# Reference derivatives rebuilt by `acquire-images` from the hash-pinned publisher TIFF in the ignored cache. +# Their `.webp.json` sidecars stay tracked: the pins and the interpretation are the record, the pixels are not. +/labs/nebula/sources/*.webp # Reacquirable distant-world paper originals; acquisition recipes pin exact bytes. /src/objects/oumuamua/source/reference/*.html /src/objects/sedna/source/reference/*.html @@ -293,6 +296,7 @@ src/objects/*/source/**/*.bpc /src/objects/m8/prepared/ /src/objects/smc/prepared/ /src/objects/lmc/prepared/ +/src/objects/omega-centauri/prepared/ /src/objects/betelgeuse-shell/.prepared-*/ /src/objects/hd-181327-disc/.prepared-*/ /src/objects/m42/.prepared-*/ @@ -303,6 +307,7 @@ src/objects/*/source/**/*.bpc /src/objects/lmc/.prepared-*/ /src/objects/m45/.prepared-*/ /src/objects/m8/.prepared-*/ +/src/objects/omega-centauri/.prepared-*/ # Binary kernels in shared SPICE kernel banks are restored by tools/spice/kernel-bank.mts; text kernels are committed. src/spice/**/*.bsp src/spice/**/*.bc diff --git a/docs/README.md b/docs/README.md index c2c9025a61..b18052882a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,6 +21,7 @@ For a body's sources, processing, evidence and known problems, read its | Querying VO archives, selecting bounded science products and retaining acquisition evidence | [VO observation access](vo-observation-access.md) | | Which upstream packages own a mechanical boundary here, and which contracts stay ours | [Astronomy package ownership](astronomy-package-ownership.md) | | One example picture per telescope, each made from a product that telescope's toolkit produced here | [Telescope examples](telescope-examples.md) | +| Pinned sources, public commands and retained outputs for the 18 telescope data families | [Telescope family examples](telescope-family-examples/README.md) | | Exoplanet light curves to maps: eigencurve fitting and its checks | [Eclipse mapping](eclipse-mapping.md) | | JWST images to sky band composites: MAST programs, the re-run level-3 stage, its oracle and depth from a model | [JWST imaging](jwst-imaging.md) | | What JWST's public archive holds by observing mode, what this project can already reduce, and which shipped objects JWST has observed | [JWST ledger](jwst-ledger.md) | diff --git a/docs/provenance/investigation-index.md b/docs/provenance/investigation-index.md index 21f6e47d76..37759fb516 100644 --- a/docs/provenance/investigation-index.md +++ b/docs/provenance/investigation-index.md @@ -4,7 +4,7 @@ Generated by `pnpm investigations:index`. Every unresolved or deferred decision decisions, not scientific readiness. **Ledgers:** 496 of 496 catalogued objects. -**Open decisions:** 1023 (900 unresolved, 123 deferred). +**Open decisions:** 1027 (901 unresolved, 126 deferred). ## Where the reopening evidence would appear @@ -13,7 +13,7 @@ The source each decision examined. Watching these is how a decision reopens. | Source | Open | Bodies | | --- | ---: | --- | | damit.cuni.cz | 257 | abundantia, adelheid, aegina, aethra, aglaja, alexandra, +168 more | -| arxiv.org | 72 | adelheid, aegina, aemilia, agenor, aglaja, alkmene, +55 more | +| arxiv.org | 73 | adelheid, aegina, aemilia, agenor, aglaja, alkmene, +56 more | | doi.org | 42 | bienor, braille, ce-tauri, chariklo, comet-1p, comet-209p, +28 more | | sbnarchive.psi.edu | 29 | atlas, comet-109p, comet-153p, comet-167p, comet-17p, comet-21p, +23 more | | tilmanndenk.de | 23 | albiorix, bebhionn, bergelmir, bestla, erriapus, fornjot, +16 more | @@ -26,11 +26,12 @@ The source each decision examined. Watching these is how a decision reopens. | www.hou.usra.edu | 5 | ariel, hydra, nix, varuna, annefrank | | astro.troja.mff.cuni.cz | 4 | eurybates, orus, patroclus, polymele | | echo.jpl.nasa.gov | 4 | comet-209p, comet-2p, comet-8p, nereus | +| zenodo.org | 4 | hd-189733b, wasp-43b, ganymede, omega-centauri | | space.jpl.nasa.gov | 3 | juliet, nereid, ophelia | | www.lpi.usra.edu | 3 | asteroid-1998-ml14, comet-1p, methone | -| zenodo.org | 3 | hd-189733b, wasp-43b, ganymede | | almascience.eso.org | 2 | r-doradus, haumea | | archive.eso.org | 2 | betelgeuse, r-doradus | +| cdsarc.cds.unistra.fr | 2 | smc, omega-centauri | | github.com | 2 | dinkinesh, wasp-43b | | naif.jpl.nasa.gov | 2 | annefrank, dinkinesh | | opus.pds-rings.seti.org | 2 | phoebe, metis | @@ -43,7 +44,6 @@ The source each decision examined. Watching these is how a decision reopens. | archives.esac.esa.int | 1 | comet-67p | | asc-planetarynames-data.s3.us-west-2.amazonaws.com | 1 | dactyl | | astrogeology.usgs.gov | 1 | ida | -| cdsarc.cds.unistra.fr | 1 | smc | | comet-toolbox.com | 1 | lutetia | | data.caltech.edu | 1 | titan | | data.darts.isas.jaxa.jp | 1 | itokawa | @@ -166,6 +166,7 @@ The source each decision examined. Watching these is how a decision reopens. | `dark-red-spot-colour-variation` | 1 | haumea | A published surface map or rotationally resolved colour model fixes the region's extent and contrast in a body-fixed frame. | | `dated-report` | 1 | pluto | A dated run for this Pluto version is recorded in the package. | | `deep-impact-li-2013-photometric-normalization` | 1 | comet-9p | A verified formulation and matching filter calibration improve both retained terrain coverage and independent overlaps. | +| `delivery-blocker` | 1 | omega-centauri | The unchanged actual-renderer handoff gate and main-app visual acceptance pass, including acceptable close-zoom presentation. Navigation, context visibility, cold replay and R2 restoration do not waive these requirements. | | `deposit-temperature-conversion` | 1 | wasp-43b | The conversion code or stellar spectrum behind the deposited maps is published. | | `detailed-shape-dem-and-geology` | 1 | belinda | A Belinda source release provides the missing downloadable mapped data, projection, measured quantity and coverage for direct comparison with the selected inputs. | | `diffuse-material` | 1 | helix | Audit source separation and finite emission with positive source evidence, retaining real knots and verified compact anchors, then inspect the same spectral front/side views. | @@ -206,6 +207,7 @@ The source each decision examined. Watching these is how a decision reopens. | `hst-photometry-and-keck-near-infrared-photometry` | 1 | juliet | A spatially resolved Juliet measurement supplies original spectral or image samples with body-fixed coordinates and enough coverage to qualify a mapped lens. | | `hst-photometry-ground-based-near-infrared-studies-an` | 1 | cordelia | A spatially resolved Cordelia measurement supplies original spectral or image samples with body-fixed coordinates and enough coverage to qualify a mapped lens. | | `hst-photometry-recovery-and-observer-account` | 1 | ophelia | A spatially resolved Ophelia measurement supplies original spectral or image samples with body-fixed coordinates and enough coverage to qualify a mapped lens. | +| `hst-registration-companion` | 1 | omega-centauri | Independent absolute astrometry is required beyond the existing relative native-image registration. | | `hubble-companion-follow-up` | 1 | deedee | A published companion detection or resolved shape product changes the system interpretation. | | `image-to-shape-feature-registration` | 1 | comet-1p | Independent surface features with a verified model frame validate the photographic placement within stated source uncertainty. | | `interacting-orbit-2024` | 1 | hiiaka | The interacting solution is acquired with its frame, epoch and uncertainty and independently checked for the application epoch. | @@ -259,6 +261,7 @@ The source each decision examined. Watching these is how a decision reopens. | `middle-axis-uncertainty-discrepancy` | 1 | haumea | An erratum or a later publication settles the middle-axis uncertainty. | | `missing-sample-continuation` | 1 | sun | A synoptic release supplies observed polar coverage for these instruments. | | `mission-shape-publications` | 1 | dinkinesh | A released numeric shape, backplane, control-point or camera bundle associated with one of these papers. | +| `modern-inclination` | 1 | omega-centauri | A coherent photometric/kinematic refit supports combining the newer inclination with a compatible projected profile. | | `mosaic-coverage-mask` | 1 | steins | A source validity mask or independent per-pixel coverage/registration reference can replace or qualify the documented heuristic. | | `mp3c-thermal-size-comparison` | 1 | abundantia | The individual source methods and observation geometry can be compared against model 4625, or an occultation, resolved outline or shape-aware thermophysical fit supplies a volume calibration. | | `mps-other-presentations` | 1 | comet-1p | A distinct photographed region and independent registration demonstrate useful new coverage. | @@ -339,7 +342,7 @@ The source each decision examined. Watching these is how a decision reopens. | `shape-pole-rotation` | 1 | comet-3i | A lightcurve inversion, pole solution or rotation period is published. | | `shape-uniqueness` | 1 | asteroid-2002-tx300 | A multi-chord occultation or resolved imaging determines the third axis. | | `shell-depth-approximation` | 1 | milky-way | A source supplies measured cloud depths that can replace the authored shell. | -| `shell-focus-link` | 1 | smc | The initial-focus payload resolves its host chain, or host validation moves off the single-object fragment. | +| `shell-focus-link` | 1 | smc | The direct SMC browser inspection runs against a complete installed runtime closure. | | `side-view-limit` | 1 | m2-9 | Improve the owning symmetry/material assumptions against fixed views without masking the defect through exposure or a fabricated depth field. | | `sio-band` | 1 | betelgeuse | A reduction that keeps the SiO channels unflagged, or a stated closure-phase error model, fits them at reduced chi-squared near 1. | | `sio-far-emission` | 1 | betelgeuse-shell | A self-calibrated SiO cube of this member, or another epoch of the line, which would show whether the northern emission and its continuum peak persist. | @@ -396,13 +399,14 @@ The source each decision examined. Watching these is how a decision reopens. | `vmc-intake` | 1 | smc | The VMC intake is re-acquired with the wrap-corrected match set and the shape fit is re-run against it. | | `voyager-clear-candidates` | 1 | nereid | A controlled reconstruction demonstrates independent body-fixed registration and useful surface information at the native sampling, or a finer observation becomes available. | | `voyager-pds-iss` | 1 | belinda | A Belinda observation or controlled reconstruction demonstrates useful native surface detail, body-fixed geometry and independent registration beyond the cited sampling or coverage limits. | +| `wilson-fit` | 1 | omega-centauri | A specified model comparison justifies implementing the correct Wilson distribution-function solution. | | `wisp-and-physical-arrays` | 1 | m45 | Acquire the original numerical observations with masks, uncertainty and usable rights before implementing a physical scattering or layered-depth operator. | | `zubarev-2025-mosaic` | 1 | hyperion | Its pixel or model release becomes publicly downloadable. | ## Backlog: no external source recorded -478 of these open decisions name no source outside this repository, so nothing says where to look -(641 with the excluded decisions, which the ledger test tracks). Give each one the archive, +479 of these open decisions name no source outside this repository, so nothing says where to look +(642 with the excluded decisions, which the ledger test tracks). Give each one the archive, deposit or paper it was checked against, or record that its next move is work here. | Waiting on | Open | Bodies | @@ -457,6 +461,7 @@ deposit or paper it was checked against, or record that its next move is work he | `d-g-e-ring-profiles` | 1 | saturn | | `daily-viirs-imagery` | 1 | earth | | `dated-report` | 1 | pluto | +| `delivery-blocker` | 1 | omega-centauri | | `detailed-shape-dem-and-geology` | 1 | belinda | | `diffuse-material` | 1 | helix | | `disconnected-color-encounters` | 1 | prometheus | diff --git a/docs/telescope-family-examples/README.md b/docs/telescope-family-examples/README.md index 70cb4b893d..23fcb66123 100644 --- a/docs/telescope-family-examples/README.md +++ b/docs/telescope-family-examples/README.md @@ -1,28 +1,28 @@ # Telescope family examples -This directory pins one compact, reviewable public-path example for every F01–F18 family. `manifest.json` is the source of truth: every row records the real source URL and byte pin, exact CLI command, committed output pin, product-record/readback proof, owner, independent check, and scientific limit. +The [test fixtures](../../tests/fixtures/telescope-family-examples/) pin one compact, reviewable public-path example for every F01–F18 family. The [manifest](../../tests/fixtures/telescope-family-examples/manifest.json) is the source of truth: every row records the real source URL and byte pin, exact CLI command, committed output pin, product-record/readback proof, owner, independent check, and scientific limit. Each row carries `exampleProven: true` and `proposalBaseline.status: "complete"` because its family baseline is now executable through a public owner. The examples remain deliberately bounded: completeness applies to the recorded format profile and operations, not every format that could belong to the family. | Family | Review artifact | Public path | What it proves | | --- | --- | --- | --- | -| F01 | `artifacts/F01.csv` | `telescope export` | Native 2D image values | -| F02 | `artifacts/F02.json` | `telescope family-run` | Mixed time, Stokes and spectral slicing with FITS/WCS context | -| F03 | `artifacts/F03.csv` | `telescope family-run` | Standalone spectrum export | -| F04 | `artifacts/F04.json` | `telescope family-run` | Pinned slit-scan inspection | -| F05 | `artifacts/F05.csv` | `telescope family-run` | Discrete photometry export | -| F06 | `artifacts/F06.csv` | `telescope family-run` | Explicit time selection | -| F07 | `artifacts/F07.csv` | `telescope family-run` | Native dynamic-spectrum window | -| F08 | `artifacts/F08.json` | `telescope family-run` | Typed table inspection | -| F09 | `artifacts/F09.csv` | `telescope family-run` | Astrometry export | -| F10 | `artifacts/F10.csv` | `telescope family-run` | Selected event rows with lineage | -| F11 | `artifacts/F11.json` | `telescope family-run` | Selected UVFITS visibilities with package-owned UV preview | -| F12 | `artifacts/F12.json` | `telescope family-run` | OIFITS V2 diagnostics | -| F13 | `artifacts/F13.json` | `telescope family-run` | Declared Stokes spectrum and explicit polarization policy | -| F14 | `artifacts/F14.json` | `telescope family-run` | Native HEALPix NESTED pixel selection | -| F15 | `artifacts/F15.json` | `telescope family-run` | Native delay-Doppler profile | -| F16 | `artifacts/F16.json` | `telescope family-run` | Existing physical point-field inspection | -| F17 | `artifacts/F17.json` | `telescope family-run` | Pinned NEAR MSI raw/calibrated/label closure | -| F18 | `artifacts/F18.json` | `telescope family-run` | Exact compound-member enumeration | +| F01 | [F01.csv](../../tests/fixtures/telescope-family-examples/artifacts/F01.csv) | `telescope export` | Native 2D image values | +| F02 | [F02.json](../../tests/fixtures/telescope-family-examples/artifacts/F02.json) | `telescope family-run` | Mixed time, Stokes and spectral slicing with FITS/WCS context | +| F03 | [F03.csv](../../tests/fixtures/telescope-family-examples/artifacts/F03.csv) | `telescope family-run` | Standalone spectrum export | +| F04 | [F04.json](../../tests/fixtures/telescope-family-examples/artifacts/F04.json) | `telescope family-run` | Pinned slit-scan inspection | +| F05 | [F05.csv](../../tests/fixtures/telescope-family-examples/artifacts/F05.csv) | `telescope family-run` | Discrete photometry export | +| F06 | [F06.csv](../../tests/fixtures/telescope-family-examples/artifacts/F06.csv) | `telescope family-run` | Explicit time selection | +| F07 | [F07.csv](../../tests/fixtures/telescope-family-examples/artifacts/F07.csv) | `telescope family-run` | Native dynamic-spectrum window | +| F08 | [F08.json](../../tests/fixtures/telescope-family-examples/artifacts/F08.json) | `telescope family-run` | Typed table inspection | +| F09 | [F09.csv](../../tests/fixtures/telescope-family-examples/artifacts/F09.csv) | `telescope family-run` | Astrometry export | +| F10 | [F10.csv](../../tests/fixtures/telescope-family-examples/artifacts/F10.csv) | `telescope family-run` | Selected event rows with lineage | +| F11 | [F11.json](../../tests/fixtures/telescope-family-examples/artifacts/F11.json) | `telescope family-run` | Selected UVFITS visibilities with package-owned UV preview | +| F12 | [F12.json](../../tests/fixtures/telescope-family-examples/artifacts/F12.json) | `telescope family-run` | OIFITS V2 diagnostics | +| F13 | [F13.json](../../tests/fixtures/telescope-family-examples/artifacts/F13.json) | `telescope family-run` | Declared Stokes spectrum and explicit polarization policy | +| F14 | [F14.json](../../tests/fixtures/telescope-family-examples/artifacts/F14.json) | `telescope family-run` | Native HEALPix NESTED pixel selection | +| F15 | [F15.json](../../tests/fixtures/telescope-family-examples/artifacts/F15.json) | `telescope family-run` | Native delay-Doppler profile | +| F16 | [F16.json](../../tests/fixtures/telescope-family-examples/artifacts/F16.json) | `telescope family-run` | Existing physical point-field inspection | +| F17 | [F17.json](../../tests/fixtures/telescope-family-examples/artifacts/F17.json) | `telescope family-run` | Pinned NEAR MSI raw/calibrated/label closure | +| F18 | [F18.json](../../tests/fixtures/telescope-family-examples/artifacts/F18.json) | `telescope family-run` | Exact compound-member enumeration | Descriptor member paths are relative to each descriptor, so the examples contain no checkout-specific absolute paths. Runtime `output.product.json` receipts are deliberately not copied here; the manifest points at focused tests that reopen and verify those records. diff --git a/docs/telescope-family-examples/descriptors/F16.json b/docs/telescope-family-examples/descriptors/F16.json deleted file mode 100644 index 821fb7509a..0000000000 --- a/docs/telescope-family-examples/descriptors/F16.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "schema": "cssearth-telescope-product-descriptor@1", - "dataset": { - "id": "stellar-neighbourhood", - "target": "stellar-neighbourhood", - "acquisition": { - "kind": "repository", - "identity": "src/objects/stellar-neighbourhood/object.json" - }, - "producingRecord": "src/objects/stellar-neighbourhood/object.json", - "sourceClassifications": [ - { - "term": "physical point field", - "vocabulary": "cssearth-object@1", - "version": "1", - "status": "source" - } - ], - "families": [ - "F16" - ], - "profiles": [ - { - "handlerId": "f16-spatial-physical", - "profileId": "existing-physical-object@1" - } - ] - }, - "members": [ - { - "id": "object", - "path": "../../../src/objects/stellar-neighbourhood/object.json", - "role": "science", - "bytes": 906, - "sha256": "fa4dbdb551af2ecfa85dc4964218f8708bbab60401f8d452a7a5230776c376e1", - "mediaType": "application/json" - } - ], - "components": [ - { - "id": "points", - "name": "stellar-neighbourhood points", - "families": [ - "F16" - ], - "locations": [ - { - "memberId": "object", - "path": "object.json" - } - ], - "representation": { - "kind": "physical-field", - "topology": "points", - "samples": null - }, - "axes": [], - "columns": [], - "quantity": { - "name": "physical point samples", - "semantics": "Existing prepared physical object; no depth is inferred from an angular or spectral observation." - }, - "calibration": { - "state": "model-derived", - "basis": [ - "Validated by the existing points loader across 7 pinned inputs.", - "{\"source\":{\"schema\":\"cssearth-source-provenance@1\",\"sources\":[{\"id\":\"catalogue\",\"path\":\"stars-hyg.gxct\",\"sha256\":\"d1574537361ac78d67f32ddf30ac0122e9d52115851f1519cb91bed26dcf8e74\",\"bytes\":4818664,\"key\":\"catalogs/stars-hyg\",\"source\":\"HYG v4.4 (Hipparcos-Yale-Gliese Database, D. Nash / astronexus)\",\"license\":\"CC-BY-SA-4.0\",\"url\":\"https://codeberg.org/astronexus/hyg/raw/branch/main/data/hyg/CURRENT/LICENSE\",\"epoch\":\"ICRS/J2000 equinox; source astrometry primarily Hipparcos-2007 reduction, epoch J1991.25\",\"built\":\"2026-09-02\",\"extra\":{\"count\":109389,\"columns\":[\"posPc\",\"absMag\",\"teffK\",\"radiusSolar\",\"colorIndexBv\",\"hip\",\"name\",\"pmRaMasPerYr\",\"pmDecMasPerYr\"],\"droppedSun\":1,\"droppedNonPositiveDist\":0,\"droppedSentinelDist\":10224,\"totalSourceRows\":119614},\"credit\":\"HYG Stellar Database by David Nash / Astronexus. Prepared derivatives licensed CC-BY-SA-4.0.\",\"modifications\":\"Complete row set reordered into a spatial hierarchy; luminosity-weighted proxies and 32-color display quantization. No astrometry propagation.\"}],\"qualification\":\"Local generated assets; no network publication. HYG astrometry is a local stellar neighbourhood, not a full Milky Way stellar census.\",\"sourceBinding\":{\"kind\":\"catalogued\",\"references\":[{\"catalogueId\":\"hyg-v44\",\"role\":\"material\",\"evidence\":\"src/objects/stellar-neighbourhood/source/provenance.json@8d2f45b58b5ea9a0b69a81242c51aa6e6d6ebcdf#/sources/0\"}]},\"catalogueDisplay\":{\"feature\":\"stars\",\"label\":\"HYG\",\"credit\":\"Star catalogue · David Nash / Astronexus · CC BY-SA 4.0.\",\"description\":\"HYG Stellar Database by David Nash / Astronexus. Prepared derivatives licensed CC-BY-SA-4.0.\",\"footerAliases\":[\"https://codeberg.org/astronexus/hyg/raw/branch/main/data/hyg/CURRENT/LICENSE\"]}},\"catalogueMetadata\":{\"source\":\"HYG v4.4 (Hipparcos-Yale-Gliese Database, D. Nash / astronexus)\",\"epoch\":\"ICRS/J2000 equinox; source astrometry primarily Hipparcos-2007 reduction, epoch J1991.25\",\"built\":\"2026-09-02\",\"sentinelDistPc\":100000,\"sentinelDistDoc\":\"dist == 100000.0 marks an unmeasurable/negative Hipparcos parallax; rows with it are dropped, not shipped.\",\"hipSentinel\":0,\"hipSentinelDoc\":\"hip == 0 means the row has no Hipparcos catalogue number.\",\"teffCalibration\":\"Ballesteros (2012) eq. 14, B-V -> Teff\",\"totalSourceRows\":119614,\"droppedSun\":1,\"droppedNonPositiveDist\":0,\"droppedSentinelDist\":10224,\"survivingRows\":109389},\"qualification\":\"All catalogue rows retained at their recorded astrometry; no proper-motion propagation to the navigation epoch. Internal nodes approximate unresolved luminosity and position; no fixed pixel-error guarantee when the point pool is saturated.\"}" - ] - }, - "flags": [], - "frame": { - "kind": "physical", - "name": "sun-icrf", - "epoch": "JD_TT 2461286.5" - }, - "dependencyIds": [] - } - ], - "dependencies": [], - "issues": [ - { - "scope": "component", - "identity": "points", - "state": "unknown", - "reason": "Portable export retains prepared resources and source recipe; raw source datasets are referenced rather than bundled. Bounds: {\"min\":[-1024,-1024,-1024],\"max\":[1024,1024,1024]}." - } - ] -} diff --git a/labs/nebula/docs/emission-compiler.md b/labs/nebula/docs/emission-compiler.md index 71cd7c7037..0c876fbaea 100644 --- a/labs/nebula/docs/emission-compiler.md +++ b/labs/nebula/docs/emission-compiler.md @@ -30,6 +30,18 @@ After the first successful compile, fit controls apply automatically; only the n Image-fit error, missing/excess signal and velocity residuals answer different questions. The fit's baseline RMSE is the zero-emission model on the same covered target pixels. Missing/excess fractions refer to normalized display signal; they are not mass fractions. A better projection cannot validate depth, and the display is not a hydrodynamic simulation. Inspect neutral front, oblique and side views as well as textured source comparisons before accepting any visual result. +## Automatic layer budget + +New compiler and sampled-volume deliveries reserve **at most 500 total retained scene elements**, including hidden elements, stars, optical copies, impostors and wrappers. The current single-topology CSS profile reserves 47 elements for delivery overhead and three elements per XYZ slab, plus one per separate star. With no stars, the optimizer receives a maximum of 151 total XYZ slabs. Every retained star reduces that allowance; an impossible allocation fails before baking rather than silently dropping stars. Final app admission also verifies topology and actual delivery overhead. + +Prefer source-backed slab emission for unresolved or dense light and fewer separate catalogue stars when the evidence supports it. Do not count the same light twice or infer measured stellar depths from an image. The field and its supported feature scale still determine the fine reference grid. An offline probe groups adjacent reference cells into wider intervals where less depth detail is needed. Each interval integrates every original reference midpoint, including faint emission, before encoding one RGBA8 texture. Material painting uses those same physical intervals and depth samples. This reduces retained planes and texture files; it does not promise proportionally less sampling work. + +The planner probes at 64 pixels wide with four image subpixel phases. Spatial variation and displacement from the reference planes estimate the extra error caused by grouping. Dynamic programming chooses complete partitions instead of making greedy splits, which can strand a concentrated feature inside a wide interval. It selects the fewest layers meeting a 1% planning estimate on each axis; if the budget prevents that, it minimizes the worst axis and records `budget-limited`. Sampled component mixtures plan once from an envelope covering every prepared lens, then share that partition. + +The saved sampling receipt contains the exact reference grid, intervals, planning report and versioned renderer-cost reservation. All image-only lenses share one topology; component mixtures must not multiply resident topologies beyond the final element allowance. `target-met` describes only this coarse estimate: subpixel features, material differences, RGBA8 rounding and browser compositing still require actual output checks. Inspect front, oblique and side views and compare both banks at each axis handoff. Keep the 5% relative-luminance and 4% normalized-L1 handoff gates unchanged. A failed result remains unaccepted; a completed bake or a small element count cannot qualify it. + +Verified compact replay uses its saved partition exactly and never replans. Historical receipts without a renderer-cost reservation retain their original sampling and bytes, including over-budget deliveries; replay reports that limitation. A new cost receipt must still pass validation during replay. New authoring cannot opt out by supplying an old sampling record. Existing repaint-only workflows keep their explicit sampling until separately requalified. The shared planner and grouped baker are available to those preparation owners without runtime sampling or geometry generation. + ## Reproduce from a clean checkout Requires the checkout containing the compiler, **Node 22.18+ or a supported newer release, pnpm 10.33.0, Python 3.9–3.12 with venv/pip**, internet access and disk space for native images and results. `python3` below must select that supported Python. The pinned TensorFlow release needs a wheel for the machine's OS/CPU. Run this complete sequence from the repository root; keep an existing lab server alive and omit only the final server command when it already runs. diff --git a/labs/nebula/models/omega-centauri/README.md b/labs/nebula/models/omega-centauri/README.md new file mode 100644 index 0000000000..ae21dfbaf1 --- /dev/null +++ b/labs/nebula/models/omega-centauri/README.md @@ -0,0 +1,172 @@ +# Omega Centauri (NGC 5139) + +**Blocked at visual qualification; not delivered.** Omega Centauri is registered in +the Lab and uses a published oblate MGE light profile. Bake 1 completed but was +visually rejected. Bake 2 produced neutral geometry, then failed during lens +painting. Bake 3 completed for local inspection after the material roundoff fix; +its unchanged neutral geometry still fails the axis-handoff image gate. A separately +authorized adaptive-layer bake reduces retained slabs from 779 to 459 but also +fails that gate; see the layer-optimization experiment below. No app +promotion, merge, or Omega R2 publication/restoration has been completed. + +## Current method + +[photometric-mge.json](photometric-mge.json) transcribes the eight projected +Gaussians in D’Souza & Rix (2013), Table 1, with a pinned source PDF and +[physical evidence](physical-evidence.json). The selected conditional model uses +PA 100° east of north, inclination 50°, and distance 5426 ± 47 pc. Its near/far +tilt sign and six-sigma numerical cutoff are authored; they are not measurements. +[The method note](mge-method.md) gives units, deprojection and competing constraints. + +The generic photometric compiler separates a smooth MGE envelope from finite +positive image residuals. The current candidate uses an authored envelope fraction +of 0.95, an 8-fit-pixel smoothing scale, and a maximum of 4096 residual features. +Each residual receives one conditional depth and finite XYZ material; each optical +lens supplies coarse envelope chromaticity and component colors on common geometry. +The selected analytic fit retained 4085 features, with total RMSE 0.03825, 5.90% +missing light and 17.79% excess light. These display-fit metrics are not a visual +acceptance or a calibrated photometric validation. + +The field represents **integrated starlight**, not resolved member stars. Source +stellar light is preserved, with zero extracted stellar residual and no separate +star catalogue layer. The 512-pixel fit grid and minimum projected sigma of 0.9 +fit pixels (5.80 arcsec here) cannot recover native stellar widths or all crowded +core texture. This is neither measured stellar depth nor a dynamical mass model. + +## Source images + +| Lens | Native publisher image | +| --- | --- | +| [VST/OmegaCAM, eso1119b](https://www.eso.org/public/images/eso1119b/) | Optical G/R/I, 14540 × 14540 pixels, 50.88′ square; light/geometry reference. | +| [WFI, eso0844a](https://www.eso.org/public/images/eso0844a/) | Optical B/V/I, 8040 × 7560 pixels, 31.88′ × 29.99′; second material lens. Some publisher mosaic gaps contain DSS data. | + +Native TIFFs, complete AVM metadata and identities are pinned. Angular registration +uses native dimensions. Earlier 8192-pixel WebP preparation is historical; it is not +the current scientific source. ESO credits and reuse terms are retained in the +[observation recipe](observations.json): VST credit is ESO/INAF-VST/OmegaCAM, +with acknowledgement to A. Grado and L. Limatola/INAF-Capodimonte Observatory; +WFI credit is ESO. Both follow the [ESO image-use terms](https://www.eso.org/public/outreach/copyright/). + +## Native registration + +The [current native receipt](native-registration.json) passes the unchanged field-star +gate with **1,899 automatic VST/WFI correspondences, 633 held-out stars and 0.0972 arcsec +held-out RMS**. All four spatial quadrants are covered; the held-out stars span over 99.7% +of the common image footprint in each direction. This validates relative registration, +not absolute sky coordinates, stellar membership, depth or photometry. The publisher says +some WFI mosaic gaps use DSS data; those regions are not independently attributed detections. + +The earlier recipe incorrectly put each AVM reference coordinate at the raster centre. +Both native TIFFs actually carry noncentral reference pixels in a smaller AVM reference +grid. Keeping those complete embedded WCS records fixes the roughly 100-arcsec relative +offset without a fitted calibration or relaxed gate. The source pins, exact AVM values, +gate metrics and failing recentred/corrupted-identity controls are in the receipt. +`verify-registration.mts` checks the embedded metadata against the processing recipe and +replays the fit from the prepared native source cache. A small spatially distributed +native-star fixture tests the same defect without requiring the large images in CI. + +[The original pointing check](registration.json) and [DSS trial](dss2-fits-registration-report.json) +are preserved historical results from the incorrect metadata transcription. The former's +0.24-arcsec centre comparison is roughly one native pixel, despite its original sub-pixel +wording. Neither historical receipt qualifies the corrected native inputs. + +## Actual results and current blocker + +The current inspection uses **459 retained slabs**, with one neutral bank and two +optical lenses. [Front, oblique and both side views](evidence/2026-09-20/README.md) +show the actual retained-DOM compiler renderer. The inspection wrapper is not the +main application or a promoted Lab delivery. The object remains a research subject; +no unfinished application package or new runtime bank is shipped here. + +- **Bake 1:** `41d62d…c3e962` completed but was visually rejected for large bright + clumps from the finite supports. +- **Bake 2:** `412d07…1fa7bdca` stopped at 66% during VST painting; the + [original receipt](evidence/2026-09-20/bake2-compile.json) records the failure. + A valid convex color mixture produced `255.00000000000003`. The correction + rejects nonfinite values before bounding finite roundoff; its regression and + 32,173,980 retained samples per lens pass. This does not qualify the renderer. +- **Bake 3:** `5d934218dcc59475e632d503bea59dfeb3bb156431d8d88d3616830808b23df9` + completed both lenses in 271.59 seconds for local inspection. The + [compile receipt](evidence/2026-09-20/bake3-compile.json) and + [Lab browser report](evidence/2026-09-20/bake3-browser.json) identify that state. + All 1,040 neutral PNGs and geometry match bake 2, as recorded by the + [complete identity comparison](evidence/2026-09-20/bake3-identity.json). + Its failed [handoff measurements](evidence/2026-09-20/legacy-handoffs.json) + therefore remain applicable. Historical screenshot paths inside that report + are local archival paths; the four current images are retained beside it. + +| Interpolation | X/Z normalized L1 | Y/Z normalized L1 | Fixed limit | +| --- | ---: | ---: | ---: | +| Smooth, original bank | 0.105794 | 0.094072 | 0.04 | +| Nearest, original bank | 0.096259 | 0.082798 | 0.04 | +| Smooth, adaptive bank | 0.124987 | 0.114655 | 0.04 | + +These checks ran on the working tree based on +`ef1e8b067f8f7d23d4bf13ea065f02f1dec7f4ad` plus the registration, photometric +compiler, compact replay, coordinate transport and adaptive-layer changes now +published in this branch. That base commit alone is not the tested version. +The [validation record](evidence/2026-09-20/validation.json) pins the tested sources +and records reused checks, local failures and omitted application qualification. + +## Adaptive-layer experiment — unaccepted + +New compiler bakes plan at most **500 total XYZ slabs** while integrating every +reference depth sample. This experiment reused bake 3's pinned field and both +materials without source acquisition or refitting. Its inspection identity is +`7a4f8781a7d19fafa57f11e65eae6ee24975082d3fcae0c1644cbdd68a5ac549`. +The [bake receipt](evidence/2026-09-20/layer-bake.json) records 461 planned slabs +(147/143/171), 459 retained slabs (146/142/171), and 230.94 seconds for the bake. +That is **41.1% fewer retained planes**, with approximately 5–7% fewer texture bytes. +It is not a corresponding bake-speed claim: depth sampling work is preserved. + +The [browser comparison](evidence/2026-09-20/layer-handoffs.json) uses the same +renderer, camera and interpolation for original and optimized banks. Front-view +normalized L1 stays below 0.0065 and luminance changes by about 1.2%. Both optical +lenses and neutral still fail the unchanged 0.04 X/Z and Y/Z image-handoff limit. +The additional X/Y diagnostic is recorded too; its old neutral outlier is not used +as a stable comparison. The planner's displacement estimate is not rendered-quality +acceptance. + +The [numerical alignment probe](evidence/2026-09-20/numerical-alignment.json) +fits translation, scale and rotation. It reduces L1 by only 2.6–5%; all twelve +old/new X/Z and Y/Z pairs remain failed. Native relative registration separately +passes at 0.097175 arcsec held-out RMS. These results do not support a simple global +2D misregistration as the explanation; they do not exclude sampling or compositing +defects. [Luminosity-weighted shape moments](evidence/2026-09-20/shape-moments.json) +in the retained envelope domain give approximate principal-axis ratios +1 : 0.98 : 0.83; this is not an observed isophotal shape measurement or side-view +rendering acceptance. + +The independent [Crab replay comparison](evidence/2026-09-20/crab-comparison.json) +reduces 542 retained slabs to 391 and verifies all 2,737 texture pins and decoded +alpha/geometry. Twelve of fourteen handoffs pass before and after. The two Spitzer +failures persist and worsen, so this experiment does not promote Crab either. + +Main-page delivery, cold compact replay, R2 publication/restoration, source-to-app +browser conformance and visual acceptance remain pending. The actual Lab publication +is still bake 3; the adaptive specimen is a separately identified inspection. + +## Historical spherical King-Abel attempt — rejected + +[king-abel-profile.json](king-abel-profile.json) and +[king-abel-derivation.mts](king-abel-derivation.mts) preserve the earlier reasoning; +they are **not the selected prior**. That experiment adopted a King (1962) projected +profile, substituted a 4.54 pc three-dimensional dynamical core radius for its +projected core radius, and approximated projected half-light radius as +0.75 × 10.42 = 7.815 pc from a three-dimensional half-mass radius. Solving those +constraints gave rt/rc ≈ 10.221 and rt ≈ 46.4 pc before numerical Abel inversion. +The 201-point table's recorded quadrature convergence established numerical +consistency of that assumed profile, not an observed photometric fit. + +Its two radius substitutions and spherical symmetry were insufficiently sourced +for the desired reconstruction. Calling it a published-model consequence did not +make those substitutions measured. Later primary-source intake supplied the MGE +table and a Wilson alternative; [shape evidence](shape-evidence.md) retains the +comparison, radius-dependent flattening and inclination limits. + +The original tooling note also described a genuine historical gap: the existing +simulation workflow required a particle-simulation baseline, while shell and +pulsar-wind recipes encoded unrelated physics. That gap motivated the generic +photometric-prior compiler now used above. No fabricated N-body baseline was added. +The current blocker is the measured renderer handoff failure, not that old tooling +gap, missing subject registration, or an absence of attempted bakes. diff --git a/labs/nebula/models/omega-centauri/candidates.json b/labs/nebula/models/omega-centauri/candidates.json new file mode 100644 index 0000000000..1fd64c2416 --- /dev/null +++ b/labs/nebula/models/omega-centauri/candidates.json @@ -0,0 +1,6 @@ +{ + "schema": "cssearth-nebula-candidates@1", + "candidates": [ + { "id": "omega-centauri", "compilerRecipe": "labs/nebula/models/omega-centauri/compiler.json" } + ] +} diff --git a/labs/nebula/models/omega-centauri/compiler.json b/labs/nebula/models/omega-centauri/compiler.json new file mode 100644 index 0000000000..1acd5bdc90 --- /dev/null +++ b/labs/nebula/models/omega-centauri/compiler.json @@ -0,0 +1,15 @@ +{ + "schema": "cssearth-nebula-compiler@1", + "id": "omega-centauri", + "label": "Omega Centauri", + "observationRecipe": "labs/nebula/models/omega-centauri/observations.json", + "observationCatalogue": ".local/nebula-lab/observations/omega-centauri/observations.json", + "structureRecipe": "labs/nebula/models/omega-centauri/observation-structures.json", + "structureCatalogue": ".local/nebula-lab/observations/omega-centauri/structures/catalogue.json", + "photometricPriorRecipe": "labs/nebula/models/omega-centauri/photometric-mge.json", + "defaultSourceId": "eso1119b", + "sourceWeights": { "eso1119b": 1, "eso0844a": 0 }, + "defaultControls": { "detail": 1, "faint": 0.35, "depth": 1 }, + "maximumStars": 0, + "interpretation": "The published oblate eight-Gaussian surface-brightness model supplies a conditional three-dimensional starlight prior at its selected inclination and position angle. Registered VST light fits finite emission components within that prior; the independent WFI image recolours the same geometry. Individual feature depths, finite supports and near/far tilt are conditional display choices, not measured stellar positions or membership. Integrated stellar light is preserved; no duplicate compact-star catalogue is added. This is relative display emission, not calibrated luminosity, gas density or a recovered dynamical model." +} diff --git a/labs/nebula/models/omega-centauri/dss2-fits-registration-report.json b/labs/nebula/models/omega-centauri/dss2-fits-registration-report.json new file mode 100644 index 0000000000..02eec85458 --- /dev/null +++ b/labs/nebula/models/omega-centauri/dss2-fits-registration-report.json @@ -0,0 +1,132 @@ +{ + "schema": "cssearth-image-alignment-report@1", + "pass": false, + "sources": [ + { + "id": "eso1119b", + "pass": false, + "sourcePath": ".local/nebula-lab/source-originals/eso1119b.tif", + "sourceSha256": "8df2e2ad462b9dc5b7437320fb2c6fd247c11746b4b2ffd3da95846b9083cad6", + "downsampledTo": [ + 3053, + 3053 + ], + "frameWidth": 225, + "geometry": { + "kind": "matched-star-homography-vs-dss2-fits", + "matrix": [ + 0.06270687861416066, + -0.00009665152495055059, + -0.00013531657182341058, + 0.062421519784384205, + 17.055830202431903, + 17.36069174483188 + ] + }, + "evidence": { + "status": "publisher", + "matchedStars": 2588, + "trainingStars": 646, + "trainingCandidates": 1725, + "rejectedTrainingStars": 1079, + "heldOutStars": 863, + "rmsPixels": 0.9754047610820139, + "maxResidualPixels": 2.551939937889531, + "spatialQuadrants": 4, + "coverageFraction": [ + 0.9897439576980328, + 0.9942620833466778 + ], + "relativeScale": 1.0010884923866699, + "centreShiftPixels": 0.05062707161605429, + "coverageDomain": { + "kind": "common-observed-footprint", + "sourcePixelPolygon": [ + [ + 3053, + -1.4210854715202004e-14 + ], + [ + 3053, + 3053 + ], + [ + 0, + 3053 + ], + [ + 0, + 0 + ] + ] + }, + "residualArcseconds": 15.60647617731222, + "interpretation": "Relative field-star alignment to the configured reference image; absolute sky scale and orientation remain publisher metadata. No stellar membership or physical depth.", + "matchTableNote": "Per-pair table omitted: 2588 pairs, reproducible by re-running labs/nebula/models/omega-centauri/verify-against-dss2-fits.mts against the pinned sources." + } + }, + { + "id": "eso0844a", + "pass": false, + "sourcePath": ".local/nebula-lab/source-originals/eso0844a.tif", + "sourceSha256": "384d1cfc31e6a2b78e5c7018f9eaecfe49a1014630bcb1bd8dceb563d69e6429", + "downsampledTo": [ + 1913, + 1799 + ], + "frameWidth": 225, + "geometry": { + "kind": "matched-star-homography-vs-dss2-fits", + "matrix": [ + 0.06242175929935033, + -0.00004287637872192954, + 0.00003435046586434953, + 0.06256983723152591, + 52.751600247196286, + 56.334478341107676 + ] + }, + "evidence": { + "status": "publisher", + "matchedStars": 1507, + "trainingStars": 606, + "trainingCandidates": 1004, + "rejectedTrainingStars": 398, + "heldOutStars": 503, + "rmsPixels": 0.6548057862204336, + "maxResidualPixels": 1.9186522832899346, + "spatialQuadrants": 4, + "coverageFraction": [ + 0.9941922186026076, + 0.9926392826751006 + ], + "relativeScale": 0.9998733807165251, + "centreShiftPixels": 0.07457734644866301, + "coverageDomain": { + "kind": "common-observed-footprint", + "sourcePixelPolygon": [ + [ + 1913, + 0 + ], + [ + 1913, + 1799 + ], + [ + 0, + 1799 + ], + [ + 0, + 0 + ] + ] + }, + "residualArcseconds": 10.476892579526936, + "interpretation": "Relative field-star alignment to the configured reference image; absolute sky scale and orientation remain publisher metadata. No stellar membership or physical depth.", + "matchTableNote": "Per-pair table omitted: 1507 pairs, reproducible by re-running labs/nebula/models/omega-centauri/verify-against-dss2-fits.mts against the pinned sources." + } + } + ] +} diff --git a/labs/nebula/models/omega-centauri/dss2-registration-report.json b/labs/nebula/models/omega-centauri/dss2-registration-report.json new file mode 100644 index 0000000000..ec231cdcfe --- /dev/null +++ b/labs/nebula/models/omega-centauri/dss2-registration-report.json @@ -0,0 +1,37 @@ +{ + "schema": "cssearth-image-alignment-report@1", + "pass": false, + "catalogue": "labs/nebula/models/omega-centauri/observations.json", + "sources": [ + { + "id": "eso1119b", + "pass": false, + "sourcePath": ".local/nebula-lab/source-originals/eso1119b.tif", + "sourceSha256": "8df2e2ad462b9dc5b7437320fb2c6fd247c11746b4b2ffd3da95846b9083cad6", + "geometry": { + "kind": "matched-star-homography", + "registration": null + }, + "evidence": { + "status": "publisher", + "matchedStars": 0, + "interpretation": "Fewer than 45 matched pairs against the DSS2 reference." + } + }, + { + "id": "eso0844a", + "pass": false, + "sourcePath": ".local/nebula-lab/source-originals/eso0844a.tif", + "sourceSha256": "384d1cfc31e6a2b78e5c7018f9eaecfe49a1014630bcb1bd8dceb563d69e6429", + "geometry": { + "kind": "matched-star-homography", + "registration": null + }, + "evidence": { + "status": "publisher", + "matchedStars": 0, + "interpretation": "Fewer than 45 matched pairs against the DSS2 reference." + } + } + ] +} diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/README.md b/labs/nebula/models/omega-centauri/evidence/2026-09-20/README.md new file mode 100644 index 0000000000..2b9dbedb0b --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/README.md @@ -0,0 +1,44 @@ +# Omega Centauri: 459-layer inspection + +These are four browser captures of the same retained 3D field, using the actual +compiler viewer and PolyCSS renderer in a local inspection wrapper. They are not +source photographs, main-page captures, or evidence of an accepted delivery. +The [capture record](captures.json) pins the result, served inputs, images, camera, +browser version, viewport (1100 × 820) and DPR (1). No image processing was applied. + +| Earth view: yaw 0°, pitch 0° | Oblique: yaw 35°, pitch 25° | +| --- | --- | +| ![Earth-facing 3D reconstruction](front.png) | ![Oblique 3D reconstruction](oblique.png) | + +| X side: yaw 90°, pitch 0° | Near Y side: yaw 0°, pitch 89° | +| --- | --- | +| ![X-side 3D reconstruction](side-x.png) | ![Near Y-side 3D reconstruction](side-y.png) | + +All views use VST/OmegaCAM colors, zoom 1 and zero pan. The interactive pitch limit +is 89°, so the final view is one degree short of the exact side. The visible field +represents integrated starlight with modeled depth: 4,085 fitted light features, +459 retained logical slabs, and no separate measured-star overlay. + +Color source: **ESO/INAF-VST/OmegaCAM. Acknowledgement: A. Grado and +L. Limatola/INAF-Capodimonte Observatory.** See the +[native observation and credit](../../observations.json) and +[ESO image-use terms](https://www.eso.org/public/outreach/copyright/). +The second available WFI lens is credited to ESO; it is not pictured here. + +These views illustrate different orientations, not a matched visual comparison. +No Pixelmatch result is claimed. The unchanged quantitative handoff gates remain +failed: [original browser measurements](layer-handoffs.json), +[bounded numerical alignment](numerical-alignment.json), and +[retained-input bake receipt](layer-bake.json). The grid and angle-dependent +appearance still need resolution. The images do not certify rotation stability. + +The [validation record](validation.json) identifies the tested source hashes, +reused checks, five full-suite failures and omitted app/R2 qualification. Its source +hashes describe the implementation captured here; publishing documentation and +evidence does not change that implementation. Historical receipts preserve their +original local paths and result identities; those paths are not public downloads. + +The four PNGs total 849,034 bytes and support the four-view inspection claim. +The 198,200-byte [bake-3 identity report](bake3-identity.json) retains all 1,040 +neutral texture comparisons needed to reuse the earlier failed handoff verdict. +No runtime slice bank or native observation bytes are committed with these images. diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake2-compile.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake2-compile.json new file mode 100644 index 0000000000..639b7fb457 --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake2-compile.json @@ -0,0 +1,21 @@ +{ + "schema": "cssearth-nebula-candidate-run@1", + "startedAt": "2026-09-20T09:23:03.906Z", + "updatedAt": "2026-09-20T09:26:09.633Z", + "catalogue": { + "path": "labs/nebula/models/omega-centauri/candidates.json", + "sha256": "be78206e67c31d36698c69818a383e922c48603cb157bbd31e8bcf824bb24240" + }, + "mode": "compile", + "selected": [ + "omega-centauri" + ], + "results": [ + { + "id": "omega-centauri", + "status": "failed", + "error": "Compiler 3D material must return finite RGB chromaticity in 0..255.", + "seconds": 185.725669875 + } + ] +} diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-browser.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-browser.json new file mode 100644 index 0000000000..053f03e4bb --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-browser.json @@ -0,0 +1,236 @@ +{ + "id": "5d934218dcc59475e632d503bea59dfeb3bb156431d8d88d3616830808b23df9", + "url": "http://127.0.0.1:4339/reconstruction?subject=omega-centauri&inspection=compiler", + "captures": [ + { + "name": "vst-front", + "pose": "0,0", + "lens": "eso1119b", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "visible", + "opacity": "1", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "vst-oblique", + "pose": "44.99999389648437,25.000006103515624", + "lens": "eso1119b", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "visible", + "opacity": "1", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "visible", + "opacity": "0.5", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "vst-x-positive", + "pose": "90.00000915527343,0", + "lens": "eso1119b", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "visible", + "opacity": "1", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "vst-x-negative", + "pose": "-89.99999847412109,0", + "lens": "eso1119b", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "visible", + "opacity": "1", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "vst-y-positive", + "pose": "0,88.99999694824218", + "lens": "eso1119b", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "visible", + "opacity": "1", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "vst-y-negative", + "pose": "0,-88.99999694824218", + "lens": "eso1119b", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "visible", + "opacity": "1", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "wfi-front", + "pose": "0,0", + "lens": "eso0844a", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "visible", + "opacity": "1", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "wfi-oblique", + "pose": "44.99999389648437,25.000006103515624", + "lens": "eso0844a", + "mode": "textured", + "original": "false", + "bankStates": [ + { + "visibility": "visible", + "opacity": "1", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "visible", + "opacity": "0.5", + "leaves": 1107 + } + ], + "retained": true + }, + { + "name": "neutral-oblique", + "pose": "44.99999389648437,25.000006103515624", + "lens": "eso0844a", + "mode": "neutral", + "original": "false", + "bankStates": [ + { + "visibility": "visible", + "opacity": "1", + "leaves": 615 + }, + { + "visibility": "hidden", + "opacity": "0", + "leaves": 615 + }, + { + "visibility": "visible", + "opacity": "0.5", + "leaves": 1107 + } + ], + "retained": true + } + ], + "errors": [], + "failed": [], + "posts": [], + "refreshVerified": true, + "status": "inspection verified; visual handoff UNACCEPTED" +} \ No newline at end of file diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-compile.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-compile.json new file mode 100644 index 0000000000..7f592efce1 --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-compile.json @@ -0,0 +1,33 @@ +{ + "schema": "cssearth-nebula-candidate-run@1", + "startedAt": "2026-09-20T09:44:55.121Z", + "updatedAt": "2026-09-20T09:49:26.736Z", + "catalogue": { + "path": "labs/nebula/models/omega-centauri/candidates.json", + "sha256": "be78206e67c31d36698c69818a383e922c48603cb157bbd31e8bcf824bb24240" + }, + "mode": "compile", + "selected": [ + "omega-centauri" + ], + "results": [ + { + "id": "omega-centauri", + "status": "complete", + "result": { + "path": ".local/nebula-lab/compiler/5d934218dcc59475e632d503bea59dfeb3bb156431d8d88d3616830808b23df9/result.json", + "sha256": "0839b8149a37b7ca2b4d54434fd5881a8e2e27eb0da451e5d028e3a0637b0f4a" + }, + "metrics": { + "components": 4085, + "unconstrainedComponents": 4085, + "stars": 0, + "fitRmse": 0.038251625699600056, + "baselineRmse": 0.24435542214110098, + "missingSignalFraction": 0.05902815700043809, + "excessSignalFraction": 0.17786660259727755 + }, + "seconds": 271.589149292 + } + ] +} diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-identity.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-identity.json new file mode 100644 index 0000000000..e7a0636284 --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/bake3-identity.json @@ -0,0 +1,7302 @@ +{ + "previous": "412d070141ce5119bd773d7a1eec65f12f78fa36ced3f930aa4fc9491fa7bdca", + "current": "5d934218dcc59475e632d503bea59dfeb3bb156431d8d88d3616830808b23df9", + "identical": true, + "imageCount": 1040, + "preparedGeometry": [ + "frame", + "anchors", + "stacks", + "resources", + "approximation" + ], + "sourceGeometry": [ + "quads", + "boundsUnits", + "approximation" + ], + "resources": [ + { + "path": "slices/x/00.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/01.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/02.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/03.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/04.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/05.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/06.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/07.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/08.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/09.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/10.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/100.png", + "bytes": 14849, + "sha256": "f3cd456668aace6836374a0d3cae22ac853494c4f42e3d958d6b4a94419c9b99", + "width": 357, + "height": 413 + }, + { + "path": "slices/x/101.png", + "bytes": 15595, + "sha256": "d1402e6b8c0ad2e32f3a4cf474c46f8304d14dd765a56c37ec1b04d41fd57b4e", + "width": 358, + "height": 579 + }, + { + "path": "slices/x/102.png", + "bytes": 15782, + "sha256": "d3c03b6ac95c34c3c48dd07f1d153a9c6641ff97670fc6986e76839b408894fd", + "width": 358, + "height": 610 + }, + { + "path": "slices/x/103.png", + "bytes": 16134, + "sha256": "4e7999e49da1192756534e6ce0543ad8d9db1b550a96dd279f3c0f8a9c0ba4ad", + "width": 359, + "height": 594 + }, + { + "path": "slices/x/104.png", + "bytes": 15805, + "sha256": "8e93454ca9d418ccd344e4e23def5b1290a73f32e1c7a075fa416de3093f4bb6", + "width": 358, + "height": 423 + }, + { + "path": "slices/x/105.png", + "bytes": 15823, + "sha256": "11e73c53996efb610b74c26ccb020a3490c3457ab94d6fe2f55b575544fc4083", + "width": 360, + "height": 415 + }, + { + "path": "slices/x/106.png", + "bytes": 16171, + "sha256": "da6e6104523d8202e6dfee30b8f699c3bca6ca47c51345e23059950d52ca6faa", + "width": 360, + "height": 433 + }, + { + "path": "slices/x/107.png", + "bytes": 16373, + "sha256": "9037e675ba1fc3363d978dc85d93879818daa72f7ce6111c72e67a97661d0b2c", + "width": 360, + "height": 432 + }, + { + "path": "slices/x/108.png", + "bytes": 16036, + "sha256": "b8b75327c0d9f4500c657770e6e6aa130ad3b98b4daa71254ae5edadf3af84c7", + "width": 358, + "height": 407 + }, + { + "path": "slices/x/109.png", + "bytes": 16896, + "sha256": "8de735439ad2082f548943ba7396fdda9ef56448ab18e5f77928deb8e360c40a", + "width": 359, + "height": 599 + }, + { + "path": "slices/x/11.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/110.png", + "bytes": 16991, + "sha256": "271c6e9d6092d6ef64906b9fd3fc9276a4e9faa06e55cf8fce9d630591c66279", + "width": 361, + "height": 599 + }, + { + "path": "slices/x/111.png", + "bytes": 16586, + "sha256": "746d9f4cdced0c71b4e97ef46360b784f856898540855e4337ff2f9e486066c1", + "width": 357, + "height": 465 + }, + { + "path": "slices/x/112.png", + "bytes": 17197, + "sha256": "79adf8fb7e595add12651a6a12969c004a233fa8a3d50fb01d1bf58eaf0e8272", + "width": 361, + "height": 524 + }, + { + "path": "slices/x/113.png", + "bytes": 17430, + "sha256": "06fc41f772c42be56c9ba3c1c3162674ab3421137d4193775a1195faa53574c1", + "width": 363, + "height": 523 + }, + { + "path": "slices/x/114.png", + "bytes": 17068, + "sha256": "e4bef6d1a4ec117688a5d0b7e332c29181c53bada82fb43013bf2812eb1074f1", + "width": 363, + "height": 467 + }, + { + "path": "slices/x/115.png", + "bytes": 17363, + "sha256": "5887ad6c674fe45b3780842e144cf3fff7811f00016960efb79c5fbf0c37ded3", + "width": 366, + "height": 543 + }, + { + "path": "slices/x/116.png", + "bytes": 17847, + "sha256": "cd483f3a038ee96d88c81f441caf122e67c40940a5e43ee822a5e8505c83f85e", + "width": 366, + "height": 545 + }, + { + "path": "slices/x/117.png", + "bytes": 18056, + "sha256": "24d632b49dc86d9c9876c039ba9afcc1f30fa9e4a477a3a0a6267cc011c33334", + "width": 367, + "height": 545 + }, + { + "path": "slices/x/118.png", + "bytes": 17862, + "sha256": "f23d61a31f8efbf4b1e1ff153fa9e26a7fe92c7aecc3fde0ea02830b7f8834cc", + "width": 370, + "height": 495 + }, + { + "path": "slices/x/119.png", + "bytes": 18975, + "sha256": "989fd4b0b61c8982eebedad8ae8ca4697ead5117dc3410d5ada226b1119780dd", + "width": 370, + "height": 787 + }, + { + "path": "slices/x/12.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/120.png", + "bytes": 18901, + "sha256": "1f3f2605e356b9a3ca94593fe39dc5b45c6cd35ea8618d79b45ea1de2d236371", + "width": 369, + "height": 768 + }, + { + "path": "slices/x/121.png", + "bytes": 18428, + "sha256": "c531cfc8a559e4e023b6ed13269a8d5e159d5a01d64d10c544ce928f47a05cce", + "width": 371, + "height": 573 + }, + { + "path": "slices/x/122.png", + "bytes": 18280, + "sha256": "b45759c0933b6b90e2d05fefd45aae080bd425acaabf3d3cf7e87c592fc6e582", + "width": 371, + "height": 495 + }, + { + "path": "slices/x/123.png", + "bytes": 18539, + "sha256": "c757f816c2596346c5ff26fe18a87bc39f055f2a5343d171e42d90fa49b11457", + "width": 373, + "height": 579 + }, + { + "path": "slices/x/124.png", + "bytes": 18520, + "sha256": "22e01e22d9b622d09981a3f604891a9d1fa741fcf2fa722295b799995f79ac35", + "width": 373, + "height": 581 + }, + { + "path": "slices/x/125.png", + "bytes": 18311, + "sha256": "fb7ceb99b441e2bb2e3e45950cc5906c9ac00a931243c672c847381946d824bd", + "width": 370, + "height": 507 + }, + { + "path": "slices/x/126.png", + "bytes": 18300, + "sha256": "93688d5a192a896b15bc871ccb6858189aa59292ce5b9b6fe9b79cdb3f9a5d2a", + "width": 373, + "height": 506 + }, + { + "path": "slices/x/127.png", + "bytes": 18341, + "sha256": "323d3b4c1007cad11ad3a04a32c37ef2217b19df42c4eee76f68c934bcdc4d2e", + "width": 373, + "height": 503 + }, + { + "path": "slices/x/128.png", + "bytes": 18234, + "sha256": "e2d3bd8c58005a602eb0b429c25e077bbde8b94a1062c932f5a667d9398a36d1", + "width": 372, + "height": 502 + }, + { + "path": "slices/x/129.png", + "bytes": 18392, + "sha256": "880e6e506b11cbd5559a6be9f7dcfe7e0bf3d8903c6d30aa8397be91d5623ef8", + "width": 372, + "height": 510 + }, + { + "path": "slices/x/13.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/130.png", + "bytes": 18571, + "sha256": "67a7683416978920256e406aaaa64d1fecef9158606a619dc3197e134ddf773a", + "width": 373, + "height": 510 + }, + { + "path": "slices/x/131.png", + "bytes": 18483, + "sha256": "3c1022a5fc82af7beaf3c1d8afadcf6ef40e11f49f2b7c05b5d512a15957ece7", + "width": 361, + "height": 480 + }, + { + "path": "slices/x/132.png", + "bytes": 18575, + "sha256": "879bf3984f4f9fcd6c959bfc7cc77742b23e1cd563ef6ec41d262fece6ea67db", + "width": 364, + "height": 479 + }, + { + "path": "slices/x/133.png", + "bytes": 18449, + "sha256": "35044a81ecd9e55a9ceba93aeb257d4c0978a867b0b47db98a8457c452795ad5", + "width": 376, + "height": 505 + }, + { + "path": "slices/x/134.png", + "bytes": 18371, + "sha256": "c8e9afb344bfc1e224e8d49fd6b663205865c8159967cc476f6bbf0390243fb7", + "width": 373, + "height": 477 + }, + { + "path": "slices/x/135.png", + "bytes": 18511, + "sha256": "9063b2d27cd79411256ce3f19f229b10b44dd183ba9dd5b5a4d043030ea2c1ca", + "width": 363, + "height": 480 + }, + { + "path": "slices/x/136.png", + "bytes": 18272, + "sha256": "864a92201b3b58a13133af8f247885cdd01914b564e02f013ba6575015bb780e", + "width": 363, + "height": 441 + }, + { + "path": "slices/x/137.png", + "bytes": 18257, + "sha256": "e9fdd8bb1670649ba3bb8e746d32a020bf3df461162e4641e9b737a412baced4", + "width": 362, + "height": 478 + }, + { + "path": "slices/x/138.png", + "bytes": 18181, + "sha256": "0799790d652bd8cb347dd750accd6f279d398f335a5c9c680d44fbdec6509648", + "width": 363, + "height": 484 + }, + { + "path": "slices/x/139.png", + "bytes": 17849, + "sha256": "7d78538ba674810118730b71553b94b7edb8bbfa029ba402395106d089d41161", + "width": 364, + "height": 382 + }, + { + "path": "slices/x/14.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/140.png", + "bytes": 18190, + "sha256": "2120a17f258c7b14c83ff266a953ac6b59bd8281b16b3df515ca46861f5bca9e", + "width": 362, + "height": 459 + }, + { + "path": "slices/x/141.png", + "bytes": 17893, + "sha256": "4977a93244c0f92b8b8dcc00d65343180edd9c9b7bfa8007a68bd2340bbd0558", + "width": 363, + "height": 396 + }, + { + "path": "slices/x/142.png", + "bytes": 18166, + "sha256": "185f23cb5022ba20602c4da969d0c2e49d71672c998300a7619a83bcbb909b70", + "width": 364, + "height": 481 + }, + { + "path": "slices/x/143.png", + "bytes": 18467, + "sha256": "702f991b243853a3409a95f7d1969a2eb1ebb20555f558cdf40ac7867ff76e2c", + "width": 365, + "height": 518 + }, + { + "path": "slices/x/144.png", + "bytes": 18336, + "sha256": "fe0bd2b3acb0d7f7add5bfa229a438fe6a1d7b910483b035e53a556b2638345f", + "width": 364, + "height": 448 + }, + { + "path": "slices/x/145.png", + "bytes": 18419, + "sha256": "994238c67731c24e256badb07891e2732c7dee5fbce3c6ffdce745314fec0cfb", + "width": 364, + "height": 485 + }, + { + "path": "slices/x/146.png", + "bytes": 18457, + "sha256": "b55d184d9c7e1ae80e77d300e121b94c7e3c91320658a9c748d9c70fded6c9c8", + "width": 366, + "height": 467 + }, + { + "path": "slices/x/147.png", + "bytes": 18028, + "sha256": "cd85aebf80438196e371def838be3d30963780f0ba6939a8446ca29ab4d534ad", + "width": 365, + "height": 400 + }, + { + "path": "slices/x/148.png", + "bytes": 18235, + "sha256": "2a32ed63efb6a6f5fe28f0ae2b0a6ef61ce78e1b68293327146c660973b6ea00", + "width": 366, + "height": 410 + }, + { + "path": "slices/x/149.png", + "bytes": 18251, + "sha256": "61860618193f0c545260313292903bd78736729262fc50d01fc2b14313c56807", + "width": 378, + "height": 411 + }, + { + "path": "slices/x/15.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/150.png", + "bytes": 17913, + "sha256": "c837727fc89d706bac3727e9e0f7fd6ee65bd404542c5f9734ec0a391e558479", + "width": 377, + "height": 410 + }, + { + "path": "slices/x/151.png", + "bytes": 17382, + "sha256": "517973fd5d999d76481ae85b770e57f2bb14eb6f4e22910384dff9435ade8b63", + "width": 364, + "height": 363 + }, + { + "path": "slices/x/152.png", + "bytes": 17563, + "sha256": "02eed9395f6a82f33b4499e55527ba2ce76cb4782138d52ee0b1904295c4fb6e", + "width": 372, + "height": 353 + }, + { + "path": "slices/x/153.png", + "bytes": 17725, + "sha256": "6b336460be35dc002a5b209af6ba801306421c542c05ed8aaddcb2069e03c3f8", + "width": 374, + "height": 421 + }, + { + "path": "slices/x/154.png", + "bytes": 17701, + "sha256": "8c1b5cb9a5a273d8c449cdf0a6446d76ef63494ffbff69f06ddd379a7f8df8cf", + "width": 368, + "height": 431 + }, + { + "path": "slices/x/155.png", + "bytes": 17536, + "sha256": "583801dc9b1b5a8bbf0202b18126a5fd394d7198166e96550e98eae8cc6f5626", + "width": 364, + "height": 432 + }, + { + "path": "slices/x/156.png", + "bytes": 18142, + "sha256": "d9bf00115174fb854330ddf255e7ccaa01dc8d879eb0e1a25d8c44916e01a9b1", + "width": 369, + "height": 527 + }, + { + "path": "slices/x/157.png", + "bytes": 17716, + "sha256": "a38a2ea34bb32064d8320b816a8811d2389414fbbe86bf6cf4e3aa8460643179", + "width": 368, + "height": 432 + }, + { + "path": "slices/x/158.png", + "bytes": 17707, + "sha256": "be11508b319ed7bc506a628e860c101def4c261a35520b360cd839153313dfc2", + "width": 365, + "height": 433 + }, + { + "path": "slices/x/159.png", + "bytes": 17012, + "sha256": "78e54d5c142b73da97c4cf12023f75ed6b9036399a869d3729710a03bd555514", + "width": 361, + "height": 358 + }, + { + "path": "slices/x/16.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/160.png", + "bytes": 16932, + "sha256": "22d23b869bfb19cb00a09bf115fd1713dbe3d55624b02a3e70880e72a7f98335", + "width": 370, + "height": 380 + }, + { + "path": "slices/x/161.png", + "bytes": 17069, + "sha256": "c2bac67cc8074ccff00d71d656b707e764c00adc56dafe997afbe17d53899105", + "width": 369, + "height": 402 + }, + { + "path": "slices/x/162.png", + "bytes": 16725, + "sha256": "91d17b2b9bf0ae03955fc617b9c2f662b049c8008ba2147c30fdcb82481c74d7", + "width": 369, + "height": 367 + }, + { + "path": "slices/x/163.png", + "bytes": 17015, + "sha256": "52325bd778b2b8e0bfe2eaab2a39e528c82c834ce6f9805baf1f6d6fe2c96176", + "width": 369, + "height": 449 + }, + { + "path": "slices/x/164.png", + "bytes": 17808, + "sha256": "d10c7bf215a976ec34cf9bc65026a0a7c20dff7a4db100b469c599f517ad452d", + "width": 368, + "height": 612 + }, + { + "path": "slices/x/165.png", + "bytes": 17432, + "sha256": "2e6276d4a767dacfce3e7346d73e79a87e5b49775ee4547c48b99a3863115eb6", + "width": 371, + "height": 611 + }, + { + "path": "slices/x/166.png", + "bytes": 17373, + "sha256": "f0dca34b083415c21fbe965c8b18e529aba5d5d3ecda7fe15125f7f4bc095276", + "width": 369, + "height": 551 + }, + { + "path": "slices/x/167.png", + "bytes": 16958, + "sha256": "36fc7784d4088df87279927a3e01d4f32913e3820414a35f67f00cafaa80b732", + "width": 369, + "height": 477 + }, + { + "path": "slices/x/168.png", + "bytes": 17731, + "sha256": "436fb59a9ab12e2976c0e3b13ec12bd833241b320806b10beed1352b2571580f", + "width": 367, + "height": 829 + }, + { + "path": "slices/x/169.png", + "bytes": 17637, + "sha256": "837341499278117934987d7ecd063cab800c3965922a2a23314b22b948be09db", + "width": 366, + "height": 829 + }, + { + "path": "slices/x/17.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/170.png", + "bytes": 16688, + "sha256": "0701e432debd0e909700b50eb4f43cf6538bebff26531e17030e458a47ef1ce6", + "width": 364, + "height": 620 + }, + { + "path": "slices/x/171.png", + "bytes": 16311, + "sha256": "d0137a350d893b18344602267ad02ea9785e7710f4c2068f759b7846afb318e2", + "width": 364, + "height": 632 + }, + { + "path": "slices/x/172.png", + "bytes": 16117, + "sha256": "7a9c59c9207488a84692993f7498857bfb83785a69ef76f9ff318ed750b66768", + "width": 363, + "height": 634 + }, + { + "path": "slices/x/173.png", + "bytes": 15752, + "sha256": "6ff8d53e91d1bcfdb9a78009efa756219820544e3685db01f21ef68c177333fb", + "width": 374, + "height": 473 + }, + { + "path": "slices/x/174.png", + "bytes": 15030, + "sha256": "ca19a2fe2ff7efff3bfcafa628543c6f805ddefaeb54864109a7bf057b706bae", + "width": 367, + "height": 361 + }, + { + "path": "slices/x/175.png", + "bytes": 14848, + "sha256": "f2a1b5f6c63477c0559ac9f92f20f80da1879ca0f7ea20552852ddfd1cb93ee8", + "width": 362, + "height": 397 + }, + { + "path": "slices/x/176.png", + "bytes": 14362, + "sha256": "f4313b31d4e4da52c162e6f715444892338ccc7ff939a999e0df5deb6afc62bd", + "width": 363, + "height": 397 + }, + { + "path": "slices/x/177.png", + "bytes": 14349, + "sha256": "e12ce30dd9a61133dc420653400871ab2c752bcee6b7bf6f9207eb1ba932e1f3", + "width": 367, + "height": 409 + }, + { + "path": "slices/x/178.png", + "bytes": 14298, + "sha256": "a1fb7acede8f7d9fbd74e58a6bf1593e2f86a0565db1861383c7a60b5ed067aa", + "width": 369, + "height": 415 + }, + { + "path": "slices/x/179.png", + "bytes": 14362, + "sha256": "fd3e0410d453117f07892d5ed49fa7935f90736dce226380a7a61a0f72d1a852", + "width": 368, + "height": 410 + }, + { + "path": "slices/x/18.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/180.png", + "bytes": 13921, + "sha256": "ffe777888891a454629b61bfd58c631514175a8a1f84ea1293d82b1e31d15aea", + "width": 372, + "height": 417 + }, + { + "path": "slices/x/181.png", + "bytes": 13608, + "sha256": "6a657e6a43610ed995ef0054ab23b236988a1bdf76fcac8313b20c08a32f8500", + "width": 369, + "height": 417 + }, + { + "path": "slices/x/182.png", + "bytes": 13395, + "sha256": "5136fcfec8d6fb23648895de40e332fc06264228126005e82e04bf20c6877bdd", + "width": 373, + "height": 417 + }, + { + "path": "slices/x/183.png", + "bytes": 12646, + "sha256": "ffd8e2a7adcc7544cf8b5a3277f7760ce0ed9cdad6276387bcc85627039fa0a0", + "width": 357, + "height": 375 + }, + { + "path": "slices/x/184.png", + "bytes": 12422, + "sha256": "d3fa8122b606666128f6cc20b1b909201f201ca4278060bd980a7248fc338f13", + "width": 372, + "height": 396 + }, + { + "path": "slices/x/185.png", + "bytes": 12294, + "sha256": "fbca2f4223eafdac1f177a8c580825eb206ecf4759cdabb909b925cf1c728392", + "width": 362, + "height": 492 + }, + { + "path": "slices/x/186.png", + "bytes": 11530, + "sha256": "008f4ea34f8b138edf54edfe3455ee2f285c3b3e6ab1a4a7a23c1f7011b453cf", + "width": 359, + "height": 493 + }, + { + "path": "slices/x/187.png", + "bytes": 10519, + "sha256": "ee81aeaf5efe69fd92183b0d21a385526cae3f420acfe1422e5a3b73e391391c", + "width": 355, + "height": 364 + }, + { + "path": "slices/x/188.png", + "bytes": 10613, + "sha256": "36f496aa57dbbed701fcd5582022252337ea9e7093e514d830ef952af9eadd8e", + "width": 345, + "height": 431 + }, + { + "path": "slices/x/189.png", + "bytes": 11038, + "sha256": "582df28e1f5fb221ca7c8206adedfa6192d2c20b70a800cccef953c6b8a598a7", + "width": 348, + "height": 656 + }, + { + "path": "slices/x/19.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/190.png", + "bytes": 10749, + "sha256": "d0e17daa68f9bd124c2d31e5f16221dccfcb9b2111c7e8e1b458cf2811957513", + "width": 345, + "height": 658 + }, + { + "path": "slices/x/191.png", + "bytes": 10089, + "sha256": "f4e1f34ddedc81149949d7ea95919474fdf2695e12b0ce500a00249361749afe", + "width": 358, + "height": 547 + }, + { + "path": "slices/x/192.png", + "bytes": 9892, + "sha256": "4edae607f20e59e9bc33715203f3f573a0df0519f2783816ce9579a8c713596f", + "width": 360, + "height": 561 + }, + { + "path": "slices/x/193.png", + "bytes": 9204, + "sha256": "9b57cc591193967974bc3de4d1e419a2b717cd3d256cfc6ae05b5aa8e09c160e", + "width": 362, + "height": 467 + }, + { + "path": "slices/x/194.png", + "bytes": 8577, + "sha256": "43934a71b3b58e7e90b8ef59d070ba7fee3427aace4a78f63acb683cf89c61b5", + "width": 346, + "height": 374 + }, + { + "path": "slices/x/195.png", + "bytes": 8537, + "sha256": "39c53ce86d4c12de4991e50b5ad0b14ae61c779955b1b415a9165cd1b1673f4f", + "width": 338, + "height": 443 + }, + { + "path": "slices/x/196.png", + "bytes": 8750, + "sha256": "26c084be4d121fb41e834252250116e15853122f5e3d65013ec39b0dbc1bd8ff", + "width": 337, + "height": 477 + }, + { + "path": "slices/x/197.png", + "bytes": 8688, + "sha256": "62c18a80e0908e112caa92461630cf76660101cfae91918ccc163fb3ffa00dfd", + "width": 347, + "height": 548 + }, + { + "path": "slices/x/198.png", + "bytes": 8226, + "sha256": "92658c36a6a65d5adf117ce3b642311006721bebccd84206345e9b8207668db4", + "width": 368, + "height": 550 + }, + { + "path": "slices/x/199.png", + "bytes": 7767, + "sha256": "81373dcd7c69cef949262c967c60a19837ee99a42b319df7672d298a1603ccb4", + "width": 358, + "height": 486 + }, + { + "path": "slices/x/20.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/200.png", + "bytes": 7696, + "sha256": "1a15346a250dcc323ae5a29a0f7f80a84deb46a4af74a3c2d17b7f27690a8a98", + "width": 358, + "height": 597 + }, + { + "path": "slices/x/201.png", + "bytes": 7396, + "sha256": "d9c1839657076ea965d667873bc850efbdb6702504c1d7b37c7fe31c8553c61b", + "width": 349, + "height": 598 + }, + { + "path": "slices/x/202.png", + "bytes": 7513, + "sha256": "23e816d5227af772a84ba7b1eddc08731cad30f1d92007ff2fa27c90e846135c", + "width": 349, + "height": 660 + }, + { + "path": "slices/x/203.png", + "bytes": 7217, + "sha256": "cb1f820426402bd8f9cdb836d33a1280d4149ccadcb00f35c5b1aa4eac19d0ee", + "width": 366, + "height": 626 + }, + { + "path": "slices/x/204.png", + "bytes": 7351, + "sha256": "a5bbcb53708e3210bc9588e0f9db5cb508801a44cf494eb6c6ce4ec3d6fc24b5", + "width": 367, + "height": 514 + }, + { + "path": "slices/x/205.png", + "bytes": 7430, + "sha256": "c4eda55360a07dd305b85fddcacf94608f7e5169a95eebc7ffb8fb65b0043a7c", + "width": 367, + "height": 599 + }, + { + "path": "slices/x/206.png", + "bytes": 7044, + "sha256": "4744d7fa8310c8e8f342352a7d0265718401bfa16af6864d6ae0e69fdef35fb0", + "width": 340, + "height": 538 + }, + { + "path": "slices/x/207.png", + "bytes": 6770, + "sha256": "58c9bb4a7775ddd057586f86e1de24318fc078e6b59f1d7b35dec5a8c616f1a7", + "width": 349, + "height": 592 + }, + { + "path": "slices/x/208.png", + "bytes": 6739, + "sha256": "f0bc3e3c77278dd0eb849e0ca449babeb03d8f334e0823a592d573f7a9c1f7c4", + "width": 349, + "height": 554 + }, + { + "path": "slices/x/209.png", + "bytes": 6474, + "sha256": "ca8867963bea8ab3b8e2c065cbf7080b089e6ade93da197e12dfbe420939630e", + "width": 353, + "height": 421 + }, + { + "path": "slices/x/21.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/210.png", + "bytes": 6211, + "sha256": "63c6edf06bcd0ae7480c52dca61d4774714620853c0e4d5d54dd8e3b6b4a49c0", + "width": 357, + "height": 418 + }, + { + "path": "slices/x/211.png", + "bytes": 5928, + "sha256": "c4fc0bd87b252045688c7ff196e66aaefe4a69d59366d62821828721a505f3bd", + "width": 358, + "height": 440 + }, + { + "path": "slices/x/212.png", + "bytes": 6222, + "sha256": "8dd181d4916e0b5044b7f1bcb5fd17cc23a4e211f4d29b44668c02a543462f9c", + "width": 344, + "height": 605 + }, + { + "path": "slices/x/213.png", + "bytes": 6019, + "sha256": "f93480d6dacffee5ce98d90903cc176e6bc60b9852618ff00fb4ca2192398d74", + "width": 354, + "height": 606 + }, + { + "path": "slices/x/214.png", + "bytes": 5832, + "sha256": "ad293bc80b4b53124e1c5ea9bfac83e2ff8a3cd5f6986314d0f4009bd2450705", + "width": 358, + "height": 490 + }, + { + "path": "slices/x/215.png", + "bytes": 5542, + "sha256": "658844db7d2f4951a1cf4ed081e553089730a6e661afcb1115c923066023da18", + "width": 363, + "height": 576 + }, + { + "path": "slices/x/216.png", + "bytes": 5290, + "sha256": "0da2db06752cd1b8102dee71b8389114ba4a719e5cb37f8017d592b493e3803c", + "width": 340, + "height": 578 + }, + { + "path": "slices/x/217.png", + "bytes": 5041, + "sha256": "4b24dd49a149ff6f4e7e4848b552a66aebcbe221dd4c7cc9486fd3f2dc4b04d9", + "width": 344, + "height": 489 + }, + { + "path": "slices/x/218.png", + "bytes": 4817, + "sha256": "274bfbc99eba6cb768cdcfb973dab312b532d2f0b0746efbe010854a4197a1dd", + "width": 361, + "height": 464 + }, + { + "path": "slices/x/219.png", + "bytes": 4668, + "sha256": "82d010088adc63a86be3d77848288d79fe1ebcd4ee07acd2775faad3c9fbabf6", + "width": 352, + "height": 527 + }, + { + "path": "slices/x/22.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/220.png", + "bytes": 4333, + "sha256": "ae404ba2f6ade39581216c8ee83b0c3cbdda34cb8b8f12c269b58fb28982e9a8", + "width": 364, + "height": 559 + }, + { + "path": "slices/x/221.png", + "bytes": 3683, + "sha256": "2d3c6cf8eddba37d68d35914f580ef8e56d2a848e3cde7f608b5c070bbae6a2e", + "width": 354, + "height": 560 + }, + { + "path": "slices/x/222.png", + "bytes": 2898, + "sha256": "3026a2e4b2b2ed3f631051902e320b35c16291f809674984c9cd59378b190a5e", + "width": 365, + "height": 504 + }, + { + "path": "slices/x/223.png", + "bytes": 2531, + "sha256": "7a1ed8f833b6f4b114543909de2c6da51fabc832e84f6735fdc5561058a1e8d6", + "width": 349, + "height": 575 + }, + { + "path": "slices/x/224.png", + "bytes": 1749, + "sha256": "f50b67881a94f2f5c846eadb4f29be5d19a8219f6874fcf985b139f1d6b6d19b", + "width": 361, + "height": 575 + }, + { + "path": "slices/x/225.png", + "bytes": 1015, + "sha256": "7d1505cecc1a8b5ae0e19e1b52c545d1a0dad9646c20e35e3eaff6d62e0c6c3c", + "width": 353, + "height": 392 + }, + { + "path": "slices/x/226.png", + "bytes": 1036, + "sha256": "9d401e45f68b03723142a8015b9df1f39957f3b585cd6f03c8cbdb862cd89f20", + "width": 343, + "height": 423 + }, + { + "path": "slices/x/227.png", + "bytes": 842, + "sha256": "e4f32b416cc6d6e93f4d2460265c570543b8e42942cf145dcae68b21cb811a4e", + "width": 324, + "height": 391 + }, + { + "path": "slices/x/228.png", + "bytes": 818, + "sha256": "c1b95324e3a6d2dc6fbadbe257f41b2be81fc63a2c1cc924555bcdba25a60bc5", + "width": 333, + "height": 377 + }, + { + "path": "slices/x/229.png", + "bytes": 771, + "sha256": "b8e38cca493a6a604faf11ad4bce9c3650a551c2f20bf05aa6cdca7c87accdc8", + "width": 318, + "height": 368 + }, + { + "path": "slices/x/23.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/230.png", + "bytes": 729, + "sha256": "e44f51dac2a5837d358c68e77e47469b8746806d61fe58ae1745537c88894a2c", + "width": 322, + "height": 379 + }, + { + "path": "slices/x/231.png", + "bytes": 674, + "sha256": "a0d1e45093aa7424f5a7f9f6ffe532590f75d796d35e72d4e13566c5d1932df0", + "width": 330, + "height": 337 + }, + { + "path": "slices/x/232.png", + "bytes": 636, + "sha256": "f82e70173be5328e4c620a43c8a7b6b68422f610e3dabb132339673700e42999", + "width": 293, + "height": 364 + }, + { + "path": "slices/x/233.png", + "bytes": 363, + "sha256": "4d3bccab339afcdccbe4275b0c6b6c092c3a309c90ae49a8365093c8d1cd5340", + "width": 182, + "height": 242 + }, + { + "path": "slices/x/234.png", + "bytes": 389, + "sha256": "6d93e3b68363bc3d40f1bfe9ae1fd700e89775f2726acbf4d76df519f0e38f7a", + "width": 223, + "height": 242 + }, + { + "path": "slices/x/235.png", + "bytes": 549, + "sha256": "cc50af48e7586b73e2e4c138c29694a54a4f105926cd92ee9ae20f41968579f1", + "width": 275, + "height": 348 + }, + { + "path": "slices/x/236.png", + "bytes": 342, + "sha256": "6f27d0f0ab8ce9f2beb55f2a101341f5c9cb339fa2b975b15fbc545b5ccb8b7f", + "width": 174, + "height": 290 + }, + { + "path": "slices/x/237.png", + "bytes": 209, + "sha256": "b19613c2d513528de3e4adf7a4058b0bb1d057e4cdffda4bb473b456d141ad92", + "width": 99, + "height": 166 + }, + { + "path": "slices/x/238.png", + "bytes": 122, + "sha256": "14b56d13a128ced9f664733cd9c8123b287025df49e61a2e09e37eba43bb8d35", + "width": 34, + "height": 43 + }, + { + "path": "slices/x/239.png", + "bytes": 173, + "sha256": "37f4f381c0e03641b8b83641fe99685d9ea87c3a76a38b0ee0fdb12fde7c654b", + "width": 149, + "height": 99 + }, + { + "path": "slices/x/24.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/240.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/241.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/242.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/243.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/244.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/245.png", + "bytes": 100, + "sha256": "233f1ca89a33ef5191accb21ab342237cbb92027d5140cda1c2a60cb8bb8552f", + "width": 5, + "height": 4 + }, + { + "path": "slices/x/246.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/247.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/248.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/249.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/25.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/250.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/251.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/252.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/253.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/254.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/255.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/256.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/257.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/258.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/259.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/26.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/260.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/261.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/262.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/263.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/27.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/28.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/29.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/30.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/31.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/32.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/33.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/34.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/35.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/36.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/37.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/38.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/x/39.png", + "bytes": 321, + "sha256": "d798830b8fbcd4ae43df36e692e9c729c75722e14c5842c547aa9f9dd64387f7", + "width": 139, + "height": 380 + }, + { + "path": "slices/x/40.png", + "bytes": 844, + "sha256": "329a2b12a05e970cd5afd8297709c9c18376cc87027e08c87cc53303518ccf5b", + "width": 310, + "height": 383 + }, + { + "path": "slices/x/41.png", + "bytes": 985, + "sha256": "4e710502e3f165b2a2dd87bd45d9537a39ee950fe8f2d575d87004d322825585", + "width": 310, + "height": 382 + }, + { + "path": "slices/x/42.png", + "bytes": 1019, + "sha256": "4371d803fd199a8bd851dc6aa168ccebe35f2e3240d4928ea13a1aca94612266", + "width": 305, + "height": 472 + }, + { + "path": "slices/x/43.png", + "bytes": 1185, + "sha256": "3e29ed2d8dac0e089434b6d475898e5af05f225ddc460b943b2cc7252f09bfea", + "width": 344, + "height": 499 + }, + { + "path": "slices/x/44.png", + "bytes": 1049, + "sha256": "700319c4c8a67e186a51098f54a1b4d37bc153c492d8a2aa1231b93c8d21842f", + "width": 345, + "height": 346 + }, + { + "path": "slices/x/45.png", + "bytes": 949, + "sha256": "ff42450ab26b6712c0cef742d27cf2d19027a261ce7181af1b7a23a32d88a7a3", + "width": 305, + "height": 349 + }, + { + "path": "slices/x/46.png", + "bytes": 1360, + "sha256": "0d7dee3ba0f787025b60083ff3da9dca19cc42c61305626f048459a6c85735a0", + "width": 341, + "height": 447 + }, + { + "path": "slices/x/47.png", + "bytes": 2199, + "sha256": "059c162fb38031c66fb5efa3da9407315633fcb130e80ed955244615787c3424", + "width": 347, + "height": 810 + }, + { + "path": "slices/x/48.png", + "bytes": 2388, + "sha256": "20aeeee6c2eb039fbfca371febe09abe6aafc50210e6b26969c7b734684d3207", + "width": 344, + "height": 759 + }, + { + "path": "slices/x/49.png", + "bytes": 2309, + "sha256": "3d88e5609b9112927f2a82f8472a3d40244f0674046d9678f6151d37d240b2b8", + "width": 336, + "height": 425 + }, + { + "path": "slices/x/50.png", + "bytes": 2395, + "sha256": "18ae63289a395c3b91badae8bcde01c45cbd08d576f2754f913d5f12059cd18f", + "width": 288, + "height": 479 + }, + { + "path": "slices/x/51.png", + "bytes": 2870, + "sha256": "479672b51b2dbc21d5a42f41801a25857684c87139edd463f23b00a95dc42ccd", + "width": 309, + "height": 509 + }, + { + "path": "slices/x/52.png", + "bytes": 3442, + "sha256": "d3f7af6dcb6fe3d551c34aac476d3880d366a7861f561545db13656b3c2b1f2a", + "width": 333, + "height": 570 + }, + { + "path": "slices/x/53.png", + "bytes": 3465, + "sha256": "eed5b727027f92255a73e46f8b0a591d0217a8701e61d4826f026d0086694d1c", + "width": 333, + "height": 570 + }, + { + "path": "slices/x/54.png", + "bytes": 3598, + "sha256": "a163297d30275c5d1045e9692819d0b453e873b47ce4415bd25d1c4b6e901030", + "width": 329, + "height": 537 + }, + { + "path": "slices/x/55.png", + "bytes": 4029, + "sha256": "ffc476d4f521223835feaa408ef131162d7995952a6881c4df4a921baa13fb8f", + "width": 336, + "height": 534 + }, + { + "path": "slices/x/56.png", + "bytes": 4108, + "sha256": "d2e03e3bd3541512f8a1c7dc218726ac6c19b645852bb177cb5d5ae34d955c75", + "width": 338, + "height": 534 + }, + { + "path": "slices/x/57.png", + "bytes": 4088, + "sha256": "deb534ed34fcec90c85b6851aa68c11d761660eb0aba8654ec22bdca326c82e2", + "width": 341, + "height": 446 + }, + { + "path": "slices/x/58.png", + "bytes": 4629, + "sha256": "89145393cc733b5bab611571045c5f1f5d5de2dfcd8be87fe880069634d52bdb", + "width": 341, + "height": 636 + }, + { + "path": "slices/x/59.png", + "bytes": 4732, + "sha256": "a0781cf8a32a9b21b761ab296a05ac09b849d9844b2a1a36583d12f5ff61743d", + "width": 323, + "height": 638 + }, + { + "path": "slices/x/60.png", + "bytes": 4722, + "sha256": "70c0b18950b7522b2d0c30946659f288acc373b4e425c4ce56f05a7d69475d06", + "width": 330, + "height": 636 + }, + { + "path": "slices/x/61.png", + "bytes": 4634, + "sha256": "fc7460aeb321dfaad83085070710faeac612cf48303437b8adafedce57b1e2e4", + "width": 331, + "height": 444 + }, + { + "path": "slices/x/62.png", + "bytes": 4990, + "sha256": "8e69dd527e5780299fd8817a1972592033a83a09b95ad713822617a541297b86", + "width": 334, + "height": 444 + }, + { + "path": "slices/x/63.png", + "bytes": 5300, + "sha256": "e0f761669cd0a5bd8cd9eac53801fd8fb06c73bf97bf2c06fa67ab3a548b88e0", + "width": 336, + "height": 445 + }, + { + "path": "slices/x/64.png", + "bytes": 5749, + "sha256": "e77889af962a9d22c058b9ccd4eacc4b212bde161af8725dcd2155a602f4214c", + "width": 333, + "height": 568 + }, + { + "path": "slices/x/65.png", + "bytes": 5667, + "sha256": "f702882a92cf70550d34329eb7da79409e888f7abd04f46c60f9057b74c26863", + "width": 335, + "height": 568 + }, + { + "path": "slices/x/66.png", + "bytes": 5967, + "sha256": "f4d062d4d88124161efa1f84f175e1e2c5b36fb6c14779158fcc00e36e6425e9", + "width": 334, + "height": 568 + }, + { + "path": "slices/x/67.png", + "bytes": 6145, + "sha256": "6c832c72a920f7bde909e17baa63f33faf7c40ae009a8340107fd1ab14ef3141", + "width": 328, + "height": 519 + }, + { + "path": "slices/x/68.png", + "bytes": 6504, + "sha256": "dc6d445a95705aae9f0f29a67b51811e73713b4479965277b8cf3c08ce358e9b", + "width": 338, + "height": 519 + }, + { + "path": "slices/x/69.png", + "bytes": 6782, + "sha256": "91c5298ee791fe9772ecffa07142b1146355faad2ec1cb67b88799c02505ebba", + "width": 345, + "height": 649 + }, + { + "path": "slices/x/70.png", + "bytes": 7093, + "sha256": "c222ab36e0528b8c88c81ebf914c2bfc99d388c05a5d36e1591cc92513facd8b", + "width": 350, + "height": 648 + }, + { + "path": "slices/x/71.png", + "bytes": 7268, + "sha256": "00f2bfeb31edb3203447b4878cc2cb1aa642a8701adb178920b69830663f8696", + "width": 356, + "height": 718 + }, + { + "path": "slices/x/72.png", + "bytes": 7289, + "sha256": "27989a86828eddd06e9016109be41cecf8d1d6ce7a2a6c9e4e4b40435a3502aa", + "width": 351, + "height": 541 + }, + { + "path": "slices/x/73.png", + "bytes": 7222, + "sha256": "8b029c50f45470524d3703073bf29f254dba7e0df246627b6ad1e97b4af3eb3f", + "width": 343, + "height": 474 + }, + { + "path": "slices/x/74.png", + "bytes": 7663, + "sha256": "130beca1bc63fa1b5991bddf9b19eae1edbe4f5f2b2911e63cccdaad605a1df0", + "width": 342, + "height": 485 + }, + { + "path": "slices/x/75.png", + "bytes": 7593, + "sha256": "b23fd9d05d90726f4bf8543d4b604663221e4b878dc309ba14bdac04120af37f", + "width": 343, + "height": 437 + }, + { + "path": "slices/x/76.png", + "bytes": 7859, + "sha256": "8a61ce4d9a7f12d9234e12fd8fc7841594ef68d8a8a56f326036b0b3e82591f0", + "width": 349, + "height": 503 + }, + { + "path": "slices/x/77.png", + "bytes": 8776, + "sha256": "8bb9a4a70261e98f158a8c8cc11a7869d6ea14127ad7c9431d6ba88a13d375f3", + "width": 356, + "height": 585 + }, + { + "path": "slices/x/78.png", + "bytes": 9127, + "sha256": "9e8bab7ac7390f0f3b58a8fa4508fa7d9a2b9ac3ba95bde9f537374179690596", + "width": 356, + "height": 584 + }, + { + "path": "slices/x/79.png", + "bytes": 8980, + "sha256": "0c15d961b5bd040d0ea7566bbca4eb6a510af6fe47ce390c488e8c9f7b94ee6c", + "width": 355, + "height": 541 + }, + { + "path": "slices/x/80.png", + "bytes": 8974, + "sha256": "35f8584ccc09d16454fb57c462779461ce4169389ad0e3333d5142ac0a0107e6", + "width": 346, + "height": 403 + }, + { + "path": "slices/x/81.png", + "bytes": 8960, + "sha256": "eb5b58152998f41243d5f8e0fdfada19956bb3429d005d13a868a6973b3294f2", + "width": 331, + "height": 362 + }, + { + "path": "slices/x/82.png", + "bytes": 9309, + "sha256": "767c43513b1782b28f8056079645898acf8288efaaf5150323858f22e6221520", + "width": 345, + "height": 343 + }, + { + "path": "slices/x/83.png", + "bytes": 9796, + "sha256": "14b65b82c8cc00f7e0b449b0248f665bda9b5740632a48ec63964b3ca3481aec", + "width": 353, + "height": 359 + }, + { + "path": "slices/x/84.png", + "bytes": 10284, + "sha256": "d498aac27c72971efcbca09a9aa299355c76e580d97cfbc8281fa8628c858c79", + "width": 340, + "height": 360 + }, + { + "path": "slices/x/85.png", + "bytes": 10408, + "sha256": "a1c54389f51bb9b295e79227483fd83fd7bf50f62db86555dc79187261acbb38", + "width": 354, + "height": 341 + }, + { + "path": "slices/x/86.png", + "bytes": 11139, + "sha256": "e1c5b1faeafdabbbd507cf43ab4ca087e0d59f11c1917d4b8fd58bc4254b01a5", + "width": 344, + "height": 480 + }, + { + "path": "slices/x/87.png", + "bytes": 11671, + "sha256": "d31e60b31d231630c5132a5ccef044e65299a3b45b91aeedb3e7881217223264", + "width": 349, + "height": 498 + }, + { + "path": "slices/x/88.png", + "bytes": 11566, + "sha256": "34a0501e00b3c9245275e7fc568a1c55327e41074c0dd899ed5d63db511379b8", + "width": 356, + "height": 400 + }, + { + "path": "slices/x/89.png", + "bytes": 11868, + "sha256": "1bd9f4e0ab8b83ba5620743668143000c0385a20661273dbc1e4e5a1aa1f4604", + "width": 356, + "height": 383 + }, + { + "path": "slices/x/90.png", + "bytes": 12152, + "sha256": "e0e3e17533998813efc731ffb4acfc44b76584e3e9ab006344cd926912aaf95b", + "width": 358, + "height": 384 + }, + { + "path": "slices/x/91.png", + "bytes": 12311, + "sha256": "0e1ee77369253fb4d091da49652b19fe79ab56633b801ef978882285994419ad", + "width": 356, + "height": 383 + }, + { + "path": "slices/x/92.png", + "bytes": 12915, + "sha256": "651f69ae52f2735f00db6c957e7dd08a7c0a1bcad154a83bc9897ae3bc963621", + "width": 355, + "height": 439 + }, + { + "path": "slices/x/93.png", + "bytes": 13573, + "sha256": "c021b467b60c91b6882b1b5ea5ac5514630ffc283c16c19fe0a92921553caed4", + "width": 348, + "height": 523 + }, + { + "path": "slices/x/94.png", + "bytes": 13675, + "sha256": "18d0265fa5ca6bbb783521a3ae0e274ddfe42a0a38ed90b5496dd469eaf0b396", + "width": 353, + "height": 464 + }, + { + "path": "slices/x/95.png", + "bytes": 13293, + "sha256": "196e7bdb26cadc55ba0bbcda8215ed017d064561b6bcf07be21ea7dadbb8563c", + "width": 353, + "height": 354 + }, + { + "path": "slices/x/96.png", + "bytes": 13564, + "sha256": "209321c1b84884f77cf9dca38d17ca1341a2d2eda2bfd83398b766f97cbead19", + "width": 354, + "height": 349 + }, + { + "path": "slices/x/97.png", + "bytes": 13587, + "sha256": "2a8045255d93e377b5ff2702286c77e2dd57b21012220b67c03596f6cbd61f59", + "width": 355, + "height": 346 + }, + { + "path": "slices/x/98.png", + "bytes": 13924, + "sha256": "6aa3f7b504fd158561438ea4fdf6afc761f4a1e9c794c67e2ed617c2b5061f43", + "width": 355, + "height": 356 + }, + { + "path": "slices/x/99.png", + "bytes": 14106, + "sha256": "76312f0d1cf791cd0c1ebc8ac6245354d8ec06ded91f611f454a392cfa2f939f", + "width": 357, + "height": 356 + }, + { + "path": "slices/y/00.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/01.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/02.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/03.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/04.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/05.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/06.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/07.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/08.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/09.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/10.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/100.png", + "bytes": 15937, + "sha256": "48a3525269f6f75d819ddbbb2d16a50c78240cb0ad97707fb99556a289e2826a", + "width": 348, + "height": 561 + }, + { + "path": "slices/y/101.png", + "bytes": 16056, + "sha256": "d6e59025a2a044392955267bfdc96cae8b635a2b8768de108522f3474c24b25e", + "width": 352, + "height": 559 + }, + { + "path": "slices/y/102.png", + "bytes": 15672, + "sha256": "2a831607777132208064486ffc692b2a806369accdd0db44ce19941e8faf54bd", + "width": 357, + "height": 406 + }, + { + "path": "slices/y/103.png", + "bytes": 15648, + "sha256": "886d3411a0ba86461475db699ce764a90a5f6ac1675176896438abff60b35182", + "width": 357, + "height": 396 + }, + { + "path": "slices/y/104.png", + "bytes": 15825, + "sha256": "5b4fa996b4feef132d4e1843b00965b87535131b03b49e6081023e8bc3c64181", + "width": 351, + "height": 417 + }, + { + "path": "slices/y/105.png", + "bytes": 15793, + "sha256": "db31d2262293fbd5c3da5a9c2b1dafca22ffd84ec8ef3b74269ddca8a2917f0a", + "width": 353, + "height": 370 + }, + { + "path": "slices/y/106.png", + "bytes": 16048, + "sha256": "67f8436d12eca6e19fdfd2e3538d18dcb7c5fcbf78dc9180a6d70c92f72d4d3a", + "width": 352, + "height": 385 + }, + { + "path": "slices/y/107.png", + "bytes": 16723, + "sha256": "30428940c9235338bbbcccc9654458523bafa353ed8e0e11009d769dea960f99", + "width": 355, + "height": 555 + }, + { + "path": "slices/y/108.png", + "bytes": 16703, + "sha256": "0fc4a3df2420e52a31300495c51243450c4308d9533e1924b405eed0b5db9328", + "width": 355, + "height": 509 + }, + { + "path": "slices/y/109.png", + "bytes": 17161, + "sha256": "3ea2b12c6de863045d92886fadd9d66b6bc2fc1aae033a7df7d7a4b69610a1ce", + "width": 353, + "height": 509 + }, + { + "path": "slices/y/11.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/110.png", + "bytes": 16671, + "sha256": "dba6a61edc631eafec1d39367fb5719dfc02bebc030354ab7846e08b7b758231", + "width": 352, + "height": 338 + }, + { + "path": "slices/y/111.png", + "bytes": 16854, + "sha256": "73bdfbb1f784697cf16810e8d06cd09d7f1a0d7fb1964561d8518983b1229160", + "width": 352, + "height": 377 + }, + { + "path": "slices/y/112.png", + "bytes": 16787, + "sha256": "25000308fa61fb1b79de0ef9479c02a4dfb51329e92957783d2b7ac21440386b", + "width": 352, + "height": 377 + }, + { + "path": "slices/y/113.png", + "bytes": 17136, + "sha256": "ddd07116242634d12fc5d94fed3ec9b779f2b86c8d8035c6494fdb614da3fd9f", + "width": 355, + "height": 404 + }, + { + "path": "slices/y/114.png", + "bytes": 17122, + "sha256": "150fb939b617bda1b62f6a4f0a3abb48fc0b0ce67a3d6cedf6fc0988b2caefff", + "width": 354, + "height": 377 + }, + { + "path": "slices/y/115.png", + "bytes": 17034, + "sha256": "29f994e4b18909b96f3df71c02deefddc6113cc114e5d47ec9de55758c58da51", + "width": 355, + "height": 349 + }, + { + "path": "slices/y/116.png", + "bytes": 17018, + "sha256": "b13d12e03af7be9f5bf1d15eb15cc1398badde169eadf56e08cc14e3f8b4b774", + "width": 355, + "height": 338 + }, + { + "path": "slices/y/117.png", + "bytes": 17967, + "sha256": "b27fffde4bfc08506c333578f638b8ef41df1dec84452fffa11a1a4a1026bba3", + "width": 356, + "height": 481 + }, + { + "path": "slices/y/118.png", + "bytes": 18074, + "sha256": "f047b9217eac40888a2bc7a894fa119318328e204265945653cad742d0e52750", + "width": 355, + "height": 482 + }, + { + "path": "slices/y/119.png", + "bytes": 18062, + "sha256": "fd3e0982ff7fecb2ea9334d787fd920b6eed6c6fa6710243d01ee3a48a7bf957", + "width": 356, + "height": 494 + }, + { + "path": "slices/y/12.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/120.png", + "bytes": 17789, + "sha256": "2e8f232abd07af9fc0d4a993c1eb8d900f315f54db866f5eb37e5b1ca9838e37", + "width": 356, + "height": 406 + }, + { + "path": "slices/y/121.png", + "bytes": 18537, + "sha256": "e08ff0d79f1384fc97d8ca09254e37e14aef5cabde9676721f1ab7cba69e2c6d", + "width": 356, + "height": 582 + }, + { + "path": "slices/y/122.png", + "bytes": 18551, + "sha256": "c0dc350f85cc5095d3da90838d9e532b0bb7a3ed1f93bb9868eed712331bd0fa", + "width": 356, + "height": 583 + }, + { + "path": "slices/y/123.png", + "bytes": 18189, + "sha256": "95a83a7e4446ef19c5c594bf598fbae56907ff482c7dece422a5292271b73a68", + "width": 357, + "height": 504 + }, + { + "path": "slices/y/124.png", + "bytes": 18246, + "sha256": "a8d79b3cf5c8cf2e5e0c10b711205346879f8990eb2f49e3c93cc3c002bb9899", + "width": 358, + "height": 502 + }, + { + "path": "slices/y/125.png", + "bytes": 17579, + "sha256": "b3bbc872dbffc30a7d3fb1e9da2c5373f54fd69ab12cb6249410b48dcab77722", + "width": 358, + "height": 380 + }, + { + "path": "slices/y/126.png", + "bytes": 17641, + "sha256": "36df33465bcb0cf7569e7267504657dc4cfb90391c897f6feedef49f80a9239b", + "width": 359, + "height": 372 + }, + { + "path": "slices/y/127.png", + "bytes": 17627, + "sha256": "7b56cdb3bb7a380f67214d12999f474491f848c47c5f2d63a67ab2f1d5d14d1f", + "width": 365, + "height": 372 + }, + { + "path": "slices/y/128.png", + "bytes": 18114, + "sha256": "3b52f3264a5f6b2b79980bd2109dbd7bbe41409130a12652c26224a477353548", + "width": 360, + "height": 440 + }, + { + "path": "slices/y/129.png", + "bytes": 18137, + "sha256": "9d4ebf1e1a1d0ff7369e6a4d2eca162dd79a745f43d59df646731c51a77f4570", + "width": 359, + "height": 441 + }, + { + "path": "slices/y/13.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/130.png", + "bytes": 17660, + "sha256": "272f009a5ea1ca542128d70b3379c6743249dbfc95a1380eb03a4025b96e4500", + "width": 360, + "height": 338 + }, + { + "path": "slices/y/131.png", + "bytes": 17788, + "sha256": "2e5c2a1e5641b99c2ae520862b36ffebcdcfc0ddaaa4b3e2880c470559ed2e5a", + "width": 361, + "height": 366 + }, + { + "path": "slices/y/132.png", + "bytes": 18522, + "sha256": "21c3ef96e9427e7fde8b8bda309cb99cd705775fbbbe02d2e5173ee3e5862caa", + "width": 363, + "height": 466 + }, + { + "path": "slices/y/133.png", + "bytes": 18317, + "sha256": "947f962ee4952be01a111ac52d92056ff7aae05ba8211325a35aa396fb3f4fd7", + "width": 362, + "height": 465 + }, + { + "path": "slices/y/134.png", + "bytes": 18327, + "sha256": "4159113a7535c0d6524865ff1bb0a0c153fc24a26a10ac13da3a89bd98657a2f", + "width": 362, + "height": 507 + }, + { + "path": "slices/y/135.png", + "bytes": 18442, + "sha256": "67c76b308a6d1e8ab1ebb9efa4b147a9492a086f251c124ce65548c0985f724d", + "width": 359, + "height": 469 + }, + { + "path": "slices/y/136.png", + "bytes": 18067, + "sha256": "ba0e2c6f1326563e061f8c3e4c47ac251ab6f1a590c7323fae445357fc3b272c", + "width": 368, + "height": 414 + }, + { + "path": "slices/y/137.png", + "bytes": 17871, + "sha256": "5d99835929321b4ae5b524b8ff0c70275019cd9877b1b9b5aa34f4f476eb826f", + "width": 367, + "height": 368 + }, + { + "path": "slices/y/138.png", + "bytes": 17668, + "sha256": "c1606945612ada73ab7cbe93b71c361a4880741355172bc3ec9697d1261276bd", + "width": 362, + "height": 341 + }, + { + "path": "slices/y/139.png", + "bytes": 17516, + "sha256": "14d9234444d2c92bff42f66536d29874bff6917af70cf3828e3d6cd880013c89", + "width": 363, + "height": 340 + }, + { + "path": "slices/y/14.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/140.png", + "bytes": 17638, + "sha256": "962b3cac1b514f26bc1b92f0fa67bdba38f59b795792c6554d6022aec1c18ade", + "width": 369, + "height": 363 + }, + { + "path": "slices/y/141.png", + "bytes": 18504, + "sha256": "c56483c86ed4469937d1f467a415d72611f1c797eecac65ca9918dc25f9ebc1c", + "width": 362, + "height": 513 + }, + { + "path": "slices/y/142.png", + "bytes": 19036, + "sha256": "c6564a69b67b8929349356e7a6667017aeca4a13d9fdbaea191536169dcb7357", + "width": 361, + "height": 637 + }, + { + "path": "slices/y/143.png", + "bytes": 18737, + "sha256": "e2ec476eb4e9cc08eb65a2ee6b30024aa0c0835a9567a2d7df7594a104152400", + "width": 363, + "height": 481 + }, + { + "path": "slices/y/144.png", + "bytes": 18059, + "sha256": "16bb3375a90d59945828bfc42ec095df9695f620d9cf86867c3e784b46342a48", + "width": 363, + "height": 365 + }, + { + "path": "slices/y/145.png", + "bytes": 17963, + "sha256": "f1c14e175c03662c61287f8b69a876e369214a500704d9b800bb68cb43915412", + "width": 368, + "height": 367 + }, + { + "path": "slices/y/146.png", + "bytes": 18016, + "sha256": "adf2262fb0acb317e34b14573583aff7ffacd579e8c790cdd4cca4f76b0018bc", + "width": 363, + "height": 362 + }, + { + "path": "slices/y/147.png", + "bytes": 18378, + "sha256": "f867f7bb8ae3d5bc7e1cb52e83582fa33a6adbd20854e5360671aab5dcc40dd1", + "width": 364, + "height": 440 + }, + { + "path": "slices/y/148.png", + "bytes": 18345, + "sha256": "3f6a8bcd565d0a8ef2f898d1ea4a6b576337b8bcc443a0e934d86923724c3d62", + "width": 364, + "height": 439 + }, + { + "path": "slices/y/149.png", + "bytes": 18090, + "sha256": "83f2c1343a2d9604314bd2ed7a68e734a95f6ccb94a44d5b3d2d75a91062b7ad", + "width": 365, + "height": 380 + }, + { + "path": "slices/y/15.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/150.png", + "bytes": 18200, + "sha256": "38b2f766f780e28c16cc1389d865e239fce98c00b47f866a9cd06b6751fafc37", + "width": 365, + "height": 445 + }, + { + "path": "slices/y/151.png", + "bytes": 18679, + "sha256": "3130b35c7fbfdfd6d2efe3a6a64257e1072e2e3c7604f1b0dd95c9a684037f43", + "width": 365, + "height": 643 + }, + { + "path": "slices/y/152.png", + "bytes": 18598, + "sha256": "5c66a8479db39b9dc51685b5001b0c2af41d9c76046fa1044afd26c171342aed", + "width": 366, + "height": 561 + }, + { + "path": "slices/y/153.png", + "bytes": 17805, + "sha256": "4a77d27f3597290e9dbae2dce6a137076dba620a11f3b7d1c642c7c14bcf3867", + "width": 368, + "height": 349 + }, + { + "path": "slices/y/154.png", + "bytes": 18144, + "sha256": "db8ff80524f9929d68b74cc3427a71d6343cc883102e6a58288b9d0e10c59f09", + "width": 372, + "height": 459 + }, + { + "path": "slices/y/155.png", + "bytes": 18129, + "sha256": "2ad57c98b1703353fc193839bbb7a48edfc611b6dd1ffb5a5899ed3491254da3", + "width": 368, + "height": 460 + }, + { + "path": "slices/y/156.png", + "bytes": 18400, + "sha256": "793ec379072b3511e8dcff6d84df86df195439da2eb9c3ebc339c6e76c2a0b5f", + "width": 367, + "height": 505 + }, + { + "path": "slices/y/157.png", + "bytes": 17550, + "sha256": "4d11b3d0cc3991bb3150b53024df542024f9261208d1c8d285efb61d01510e67", + "width": 368, + "height": 397 + }, + { + "path": "slices/y/158.png", + "bytes": 17334, + "sha256": "057f5754aba3bdd1875b4554799465fdaa56a11e55b2fe3e0971587f1c919205", + "width": 367, + "height": 385 + }, + { + "path": "slices/y/159.png", + "bytes": 17446, + "sha256": "a39e014dea0e9810680f46001a1f7d5c33363da19b318aaa9ce4b3e2b8a79cc2", + "width": 369, + "height": 404 + }, + { + "path": "slices/y/16.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/160.png", + "bytes": 17205, + "sha256": "1d148ca775fdb07520d28fa03cbc507a41199c32a9764abf71ec070fabbce673", + "width": 369, + "height": 424 + }, + { + "path": "slices/y/161.png", + "bytes": 17157, + "sha256": "2c8a4245c7da35d9f2004745e896963f7ba767c2f1ee79f00c4eb6a298ed5fd9", + "width": 370, + "height": 424 + }, + { + "path": "slices/y/162.png", + "bytes": 16633, + "sha256": "c70a08dcdfc94a6e5f893690eabd6d40d017a5a1e1fe43d645e5d56c39bb896c", + "width": 369, + "height": 362 + }, + { + "path": "slices/y/163.png", + "bytes": 16937, + "sha256": "433d85eb9c9c679c366976c43a81ff2f281457d72bc07915839ba6e66d932dce", + "width": 369, + "height": 436 + }, + { + "path": "slices/y/164.png", + "bytes": 16627, + "sha256": "da20ec40773d6c45697dc1158475eda53a1e444f502b0f9210d41a9f8dae342e", + "width": 368, + "height": 428 + }, + { + "path": "slices/y/165.png", + "bytes": 16845, + "sha256": "9a77da5555bc5503146f138689ccaf6e0cff23ff30fdd75f181226fef466dd90", + "width": 371, + "height": 529 + }, + { + "path": "slices/y/166.png", + "bytes": 16619, + "sha256": "fb1d669d3b8f35c62f7c394ae5fd4b64dd80b576a83ace3d08437aab2fe554c1", + "width": 370, + "height": 531 + }, + { + "path": "slices/y/167.png", + "bytes": 15620, + "sha256": "c7d4b280870dace7ddbcbb48f9c1dd4122ce4c688de065659703ea237c3beb37", + "width": 365, + "height": 463 + }, + { + "path": "slices/y/168.png", + "bytes": 15585, + "sha256": "1f7dd44e9e4bb84543ff77faac956a0a607e9c9f9e8a9e9fbed96ae5c947f947", + "width": 362, + "height": 426 + }, + { + "path": "slices/y/169.png", + "bytes": 16004, + "sha256": "2e05727d9ca9b8ac21405fd1c3a48be43c8d75f1b1673e7e94bf70607d1a4961", + "width": 372, + "height": 466 + }, + { + "path": "slices/y/17.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/170.png", + "bytes": 16671, + "sha256": "757489d6ed8f6449023388b2228e6c91650082f2bd48569ccd74754dbf018c9d", + "width": 372, + "height": 648 + }, + { + "path": "slices/y/171.png", + "bytes": 15995, + "sha256": "89641600b7bb3dbfafbe6074559c7906b55662df77bb337fdc19d0f547bb48d4", + "width": 359, + "height": 648 + }, + { + "path": "slices/y/172.png", + "bytes": 15450, + "sha256": "cf2236612d9ebf908174eaf0787b7683fa9398714aed69860f9e01d0aa2c8d99", + "width": 374, + "height": 466 + }, + { + "path": "slices/y/173.png", + "bytes": 14843, + "sha256": "bdaaf93ee092ad0db05eb0cba11609f6c82685d867100f73d00d64f2da52e329", + "width": 360, + "height": 399 + }, + { + "path": "slices/y/174.png", + "bytes": 15156, + "sha256": "8e67ae63f801dc393a52712249f016568dca54332bb401185e30e1e1ea74c70c", + "width": 361, + "height": 553 + }, + { + "path": "slices/y/175.png", + "bytes": 14623, + "sha256": "77c5a6e199bbdc34eb307ee816f97e2cc9831c54091a5c068a378e957b86325b", + "width": 360, + "height": 535 + }, + { + "path": "slices/y/176.png", + "bytes": 13966, + "sha256": "b795b4d3c96a5f937cf0a297f96cb6774da04bd24d09ebd44963ce496c8ff877", + "width": 371, + "height": 409 + }, + { + "path": "slices/y/177.png", + "bytes": 13480, + "sha256": "108f29a8e408b7988bf3439dcf1f27abe652582511a3721d7627f88e8b314573", + "width": 361, + "height": 430 + }, + { + "path": "slices/y/178.png", + "bytes": 13185, + "sha256": "d4dd154dec2168ea8716520a433182db79aa7fa86c0b5337b5c0c5a9be67d003", + "width": 361, + "height": 469 + }, + { + "path": "slices/y/179.png", + "bytes": 12874, + "sha256": "24441b8d0b48449335068ac17b975318fffdbf86a0db89816d9d850f09ca813e", + "width": 363, + "height": 456 + }, + { + "path": "slices/y/18.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/180.png", + "bytes": 11841, + "sha256": "627c935fd47941639049e2f81221ccb95e6ea6c8baf82ab723614f792eae73e1", + "width": 358, + "height": 397 + }, + { + "path": "slices/y/181.png", + "bytes": 11240, + "sha256": "801548897aa1ab924330b5a5e7c8878a23e187beb967cccedf59fbee2cc52eba", + "width": 357, + "height": 355 + }, + { + "path": "slices/y/182.png", + "bytes": 11409, + "sha256": "a1633664e022312b4105b078d5aeff5ef8d43b5db395c477349e8502c76dbd86", + "width": 362, + "height": 426 + }, + { + "path": "slices/y/183.png", + "bytes": 11274, + "sha256": "af6a33d3a6550c6ee277a119d3f507576668789490b914985fcee9b28beed3be", + "width": 358, + "height": 425 + }, + { + "path": "slices/y/184.png", + "bytes": 10779, + "sha256": "35fb8cb64a78aa2062acf7f22c2e89fef7f6e852fef96f529cf1462074c7fefa", + "width": 357, + "height": 382 + }, + { + "path": "slices/y/185.png", + "bytes": 10606, + "sha256": "92483b14fcf1655aa359ac68ef4693be2102ad0269a99a599ae9cc8da50794af", + "width": 357, + "height": 424 + }, + { + "path": "slices/y/186.png", + "bytes": 10104, + "sha256": "692eb220d887bf7d5755eb47476d43e91a96dd282a15226da02eab14fbfb7dd6", + "width": 364, + "height": 426 + }, + { + "path": "slices/y/187.png", + "bytes": 9368, + "sha256": "1bdb0f5c30750540c15c71e531ed575a996137baba22f0b87e2ab6bcaa9da74f", + "width": 355, + "height": 337 + }, + { + "path": "slices/y/188.png", + "bytes": 8945, + "sha256": "8086ce5eb7d234785aed10ce48d1698d0abb5457e4afe6002a9845dcbceddd9f", + "width": 357, + "height": 337 + }, + { + "path": "slices/y/189.png", + "bytes": 8904, + "sha256": "d58e5ad5c31c28cee0665598ee947a76c7a8134dc1ec10c11d7687f543e49f58", + "width": 363, + "height": 423 + }, + { + "path": "slices/y/19.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/190.png", + "bytes": 9036, + "sha256": "65d930fcf095db416e0926535004d6f6f47aa4856b09fd479dd1dc0c39fda1f4", + "width": 356, + "height": 677 + }, + { + "path": "slices/y/191.png", + "bytes": 8673, + "sha256": "ab0c93480fcabab371acb7e435c322744acb1238016f987e8dff6e22c646f586", + "width": 354, + "height": 766 + }, + { + "path": "slices/y/192.png", + "bytes": 8161, + "sha256": "eed58cca39f55a2aac8abf04593ab361ac575b78d38f8394e084ea62da342341", + "width": 363, + "height": 584 + }, + { + "path": "slices/y/193.png", + "bytes": 7416, + "sha256": "6a6358830c465b7aed0a5b32717664ba505429b8bb565b75ce70ae85a7a3ad96", + "width": 356, + "height": 432 + }, + { + "path": "slices/y/194.png", + "bytes": 7028, + "sha256": "997ec6e6f143ffdf95b1a7ead6f5474d074df84eaa8e39c4ff4efe18daf62863", + "width": 353, + "height": 420 + }, + { + "path": "slices/y/195.png", + "bytes": 6733, + "sha256": "cf8a8f65b2e279fbb0f675f02c890f5bb2a4ae471e85a2b1bea86a229a8d4dec", + "width": 356, + "height": 405 + }, + { + "path": "slices/y/196.png", + "bytes": 6539, + "sha256": "5d5c0c474d840de7446e0a4d2dcfcf63f60d7dc66ec8886b0f8f99ad09d3a510", + "width": 356, + "height": 525 + }, + { + "path": "slices/y/197.png", + "bytes": 6684, + "sha256": "067625be11dc12d7bbfcb3b213677ddfc2ca30d0364744e37695b9e1289262e6", + "width": 359, + "height": 525 + }, + { + "path": "slices/y/198.png", + "bytes": 6625, + "sha256": "25ddf74e9c0b4e2e61745244fedf10cf25cf3fbc5c7e4d6d9e2d753dbbab8fbe", + "width": 356, + "height": 448 + }, + { + "path": "slices/y/199.png", + "bytes": 6357, + "sha256": "898ee2897d9c7da7bbeff1837eb0188b8f37311e52ce96272e3c5224da8cd05d", + "width": 360, + "height": 450 + }, + { + "path": "slices/y/20.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/200.png", + "bytes": 6286, + "sha256": "1f9e1a353ea387e13c40a7fa5a013157d253350d0f79b53481f5e065c5648058", + "width": 360, + "height": 387 + }, + { + "path": "slices/y/201.png", + "bytes": 6683, + "sha256": "24c97d13fbef411ab176f7e71384da53a8b229465a4392da2e84af5e83901ae9", + "width": 356, + "height": 388 + }, + { + "path": "slices/y/202.png", + "bytes": 6492, + "sha256": "f5addf9b0a8254a9352865348d28d6655305ef48bfa967723b3b645ba729f54a", + "width": 357, + "height": 421 + }, + { + "path": "slices/y/203.png", + "bytes": 6310, + "sha256": "e5332c36284a443adc41ecb90753b386b47709875cbd9cd2ec5dafd76cfe7550", + "width": 353, + "height": 449 + }, + { + "path": "slices/y/204.png", + "bytes": 6180, + "sha256": "bb54a794d886824aa9a7fc85e17800e9ce9b726483cd49bda71a3f4919283e85", + "width": 357, + "height": 533 + }, + { + "path": "slices/y/205.png", + "bytes": 5601, + "sha256": "14f9e1b1275b5300d1601709f37347effd8bcdf284d4ba213923751d469e33d9", + "width": 325, + "height": 434 + }, + { + "path": "slices/y/206.png", + "bytes": 5576, + "sha256": "dd741bcf9327a6c7ff4817d174767d4cafd0289b5df67406dc588f34544fc326", + "width": 354, + "height": 514 + }, + { + "path": "slices/y/207.png", + "bytes": 5382, + "sha256": "0e78cf6825210be842061c90f2201807509b6edcda5fd38ca32d5b18712ecba1", + "width": 358, + "height": 520 + }, + { + "path": "slices/y/208.png", + "bytes": 5166, + "sha256": "89205b8b10069018db4f73fa72ac889b3ec571a775b3ff932821adf75db07583", + "width": 358, + "height": 573 + }, + { + "path": "slices/y/209.png", + "bytes": 4979, + "sha256": "736c8a24ed74235268760dd456aca72b44490d5ae2261279b88b954f013af979", + "width": 356, + "height": 592 + }, + { + "path": "slices/y/21.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/210.png", + "bytes": 4546, + "sha256": "132d169e13a75df224ae0a96854c80eafd42af11499fa2f151b80301b83e8a74", + "width": 355, + "height": 460 + }, + { + "path": "slices/y/211.png", + "bytes": 4771, + "sha256": "c075ba2b6165c4c2b000066e613f50b2be51f8d3a7609f429c6a9d1dea470903", + "width": 351, + "height": 457 + }, + { + "path": "slices/y/212.png", + "bytes": 4554, + "sha256": "602ac18f150dc3b84f06a6c7c6ccbe5ff9f5c0b8f6ea8b6a67a66bba50ba3886", + "width": 350, + "height": 438 + }, + { + "path": "slices/y/213.png", + "bytes": 4406, + "sha256": "8a254e6e66e9ffa311579abcc5bce6ce070d4afecbe72a9c830a1ca1881acd74", + "width": 343, + "height": 480 + }, + { + "path": "slices/y/214.png", + "bytes": 4446, + "sha256": "9d1fe18971c7ade5b7797657994ac5902022daaac9ec206ea1bc1c7e8bbe91a1", + "width": 345, + "height": 480 + }, + { + "path": "slices/y/215.png", + "bytes": 4689, + "sha256": "52d4a841d61bf41114c35a65ed33d8b753b5c0c9cabdb8aea42f18970e0f2662", + "width": 347, + "height": 625 + }, + { + "path": "slices/y/216.png", + "bytes": 4874, + "sha256": "a8b337a3fba2a3c9d1fcef465bf666ed4fef7f3fe835681794740806fb83af58", + "width": 349, + "height": 672 + }, + { + "path": "slices/y/217.png", + "bytes": 4517, + "sha256": "3456432c98da208cccee3d2db5152a1c0781405c28cc4a93a4edbca0af1ac090", + "width": 349, + "height": 574 + }, + { + "path": "slices/y/218.png", + "bytes": 4157, + "sha256": "48e653e6ba2b35c60708a49afab462d0175aa02aac1cbfa667deb8b54abe5a8c", + "width": 348, + "height": 535 + }, + { + "path": "slices/y/219.png", + "bytes": 3980, + "sha256": "fe9da402c26ef5a91ec4b9aa66366417eb21fff610b6d067779f0426a82e5f98", + "width": 343, + "height": 477 + }, + { + "path": "slices/y/22.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/220.png", + "bytes": 3634, + "sha256": "3ece6dd033ffb43e98c97af4c185c9d38493047f25276e2531a531fead3b28f7", + "width": 341, + "height": 437 + }, + { + "path": "slices/y/221.png", + "bytes": 4183, + "sha256": "9f089843c90da550f24a2a343480cabeb40cd01fc61986533d300a9d899af710", + "width": 346, + "height": 981 + }, + { + "path": "slices/y/222.png", + "bytes": 4053, + "sha256": "7405a40dfe219bea742a11212e06e2df670d4ddeb4f946128c9d27435733e1a1", + "width": 347, + "height": 981 + }, + { + "path": "slices/y/223.png", + "bytes": 3327, + "sha256": "c74b0015a3fe3a23afc396f01cd0b415fd58aef96ac5ddfecfcefc2815947cc0", + "width": 350, + "height": 716 + }, + { + "path": "slices/y/224.png", + "bytes": 2610, + "sha256": "873ea8d2e8275cd587e3b4c1287ddfc47b506e76ed2c545757d16ce567095dbe", + "width": 350, + "height": 715 + }, + { + "path": "slices/y/225.png", + "bytes": 1405, + "sha256": "e62c68940ea1a4eb7044fb9781eb311335d12ccfa3b4ed27845d6afc8551822a", + "width": 338, + "height": 538 + }, + { + "path": "slices/y/226.png", + "bytes": 814, + "sha256": "5815e741972c53d90e33ac943294ecbaacc9a0bdb2d98d74e75613974daf8684", + "width": 349, + "height": 222 + }, + { + "path": "slices/y/227.png", + "bytes": 823, + "sha256": "b01d0c1dd528066016a1548cf191100f0b3f719d71dc2c3f72730ef4a189d651", + "width": 348, + "height": 268 + }, + { + "path": "slices/y/228.png", + "bytes": 719, + "sha256": "1bdde2eeb0188f4a7a880d788477151b04e45b06cad87a2185ebc6df3c0f0a20", + "width": 336, + "height": 228 + }, + { + "path": "slices/y/229.png", + "bytes": 682, + "sha256": "014b3bab44dc73b4f98201809ec6673d1f168ca2f1677417976c44378149c56f", + "width": 321, + "height": 233 + }, + { + "path": "slices/y/23.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/230.png", + "bytes": 556, + "sha256": "c4238b5481abdc7957174c53fe37791d9da8fc4a0e3eea1cb9882d070748e846", + "width": 332, + "height": 191 + }, + { + "path": "slices/y/231.png", + "bytes": 429, + "sha256": "06f46fe110ee6ef530ffc520c75e86479c48ff04a7aeede99e2d397187ace92f", + "width": 243, + "height": 157 + }, + { + "path": "slices/y/232.png", + "bytes": 481, + "sha256": "aff0d722feefc65295cc05389542c5fac85d452dfff11771a293e56adc74e067", + "width": 301, + "height": 200 + }, + { + "path": "slices/y/233.png", + "bytes": 353, + "sha256": "80499ce0fc62fe1134b0bcf99903ad847ff2a8bfdff2832e4b95e5ebb6e06601", + "width": 239, + "height": 152 + }, + { + "path": "slices/y/234.png", + "bytes": 398, + "sha256": "5d690c9e00756752b820eb78a937623bf890f1b51f64210f9850efdb7a6f236c", + "width": 310, + "height": 171 + }, + { + "path": "slices/y/235.png", + "bytes": 281, + "sha256": "a3d1090b49983a1a17e7559f0a468dbf23f37015e2d2b2bf6fec22241e2ce2ff", + "width": 200, + "height": 140 + }, + { + "path": "slices/y/236.png", + "bytes": 286, + "sha256": "e90e243a93365ef9ba560f851db58b8c21d86d869f2bc2f17356843a72082c24", + "width": 227, + "height": 119 + }, + { + "path": "slices/y/237.png", + "bytes": 283, + "sha256": "a4e1c1f91ed35953e9bf6f64c0bdd0bf460fd5ef01082914d092bb52120c326f", + "width": 290, + "height": 118 + }, + { + "path": "slices/y/238.png", + "bytes": 184, + "sha256": "58db3cb67aaab4b0998797fb8f006943865e846357a69453181b0b927b50e268", + "width": 192, + "height": 74 + }, + { + "path": "slices/y/239.png", + "bytes": 172, + "sha256": "3f38f1618c9f09d34b894cc9808827e9f2a06dde5072a763557a4c1d3cb216b0", + "width": 190, + "height": 65 + }, + { + "path": "slices/y/24.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/240.png", + "bytes": 158, + "sha256": "f46cc6c467b7b005cfed253180dff3fc17128825d4200ec9c0631ae339c4b707", + "width": 99, + "height": 81 + }, + { + "path": "slices/y/241.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/242.png", + "bytes": 178, + "sha256": "a2b1f2884d2cb8e39927ef0f5efca8ae0de85fce5dbdac8abe06758f1e51e634", + "width": 148, + "height": 92 + }, + { + "path": "slices/y/243.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/244.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/245.png", + "bytes": 162, + "sha256": "035afaa4bacb3ba6e4301e6d9d6f43c29d24a1707f295c1d79cfc428b2a8a8d9", + "width": 104, + "height": 116 + }, + { + "path": "slices/y/246.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/247.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/248.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/249.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/25.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/250.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/251.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/252.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/253.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/254.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/255.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/256.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/257.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/258.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/259.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/26.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/260.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/261.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/262.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/263.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/27.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/28.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/29.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/30.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/31.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/32.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/33.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/34.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/35.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/36.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/37.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/38.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/39.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/y/40.png", + "bytes": 309, + "sha256": "99c26b6b73f4ed22d82fc7e56dae027a3b4252cd3c290f6b0a48bbb37b233a82", + "width": 160, + "height": 203 + }, + { + "path": "slices/y/41.png", + "bytes": 749, + "sha256": "a409937f7e8bc9833ada1840dde0c5162605d3a0847609a60479f9a351759a43", + "width": 260, + "height": 280 + }, + { + "path": "slices/y/42.png", + "bytes": 1027, + "sha256": "709ad4588d6b41f6fd586cad99678105bebea216ab85c3171e25a7aaa7a50ba9", + "width": 327, + "height": 311 + }, + { + "path": "slices/y/43.png", + "bytes": 1140, + "sha256": "f7095717016dd2eb215174b765a9a2350670a1e56ad8937aae4be96eba1d7eb6", + "width": 346, + "height": 416 + }, + { + "path": "slices/y/44.png", + "bytes": 1269, + "sha256": "56a898a0d7946303fa7b03ce6bc5d631e8d463d0d30ddcabe02398b537cb4f37", + "width": 336, + "height": 465 + }, + { + "path": "slices/y/45.png", + "bytes": 1299, + "sha256": "c68ed129b1feab7d7c17938c8bb920a40cb39d7db4ec0ce6cd15c9984ec6bfe4", + "width": 334, + "height": 465 + }, + { + "path": "slices/y/46.png", + "bytes": 1356, + "sha256": "e6c9fe6b7db0bc01cd84e95b569f14d6276d24e102716cd229f857256ae07110", + "width": 347, + "height": 340 + }, + { + "path": "slices/y/47.png", + "bytes": 2098, + "sha256": "7dee9afbdec9e22e2643099f020a3243ec4c6c30ad80ef1d1786ea49973e1495", + "width": 348, + "height": 703 + }, + { + "path": "slices/y/48.png", + "bytes": 2385, + "sha256": "6e5eeac752bc9ace69950dee68649124d0f5422665efdf10f65a53e5594961cc", + "width": 346, + "height": 740 + }, + { + "path": "slices/y/49.png", + "bytes": 1955, + "sha256": "c6165e50d165aff1b41b835e2bd187525e521a3ae705971d9a89158ad644513d", + "width": 341, + "height": 438 + }, + { + "path": "slices/y/50.png", + "bytes": 2179, + "sha256": "ff2f7176399d543db33a1a6432f47143c2f32cd75d7a3752019a7a7969bd8cee", + "width": 330, + "height": 418 + }, + { + "path": "slices/y/51.png", + "bytes": 3222, + "sha256": "8961f761c5e963c439cf3969978018cf49181225965c41efbe00ed56302b9351", + "width": 350, + "height": 523 + }, + { + "path": "slices/y/52.png", + "bytes": 4248, + "sha256": "9759b9a579a342bc0873d5330fd24871119f3fc8d24af151b1b6226e55699d8d", + "width": 350, + "height": 703 + }, + { + "path": "slices/y/53.png", + "bytes": 4516, + "sha256": "02720e4aac68232a66b93e8eab385929d004c5c39d24ea332bcdcdee8d9987b6", + "width": 347, + "height": 703 + }, + { + "path": "slices/y/54.png", + "bytes": 4808, + "sha256": "89dc6aecdfe49a9b33dfd2cd010853e79257cf1f80cb1dd47d8e40a1e1a2c37c", + "width": 308, + "height": 604 + }, + { + "path": "slices/y/55.png", + "bytes": 5605, + "sha256": "469f381522379af727998088b1dd2ebecfad37e12688721e641821a6d4423372", + "width": 322, + "height": 733 + }, + { + "path": "slices/y/56.png", + "bytes": 5517, + "sha256": "66d8eb55b51e1bce534655a1fec2d5a36e4ea48a90c2d5a36a09eb72541e3368", + "width": 323, + "height": 732 + }, + { + "path": "slices/y/57.png", + "bytes": 5516, + "sha256": "4da398a7f05416a52924624d322c5e646475c6fbc4c994410cde3c00fb1c1fe5", + "width": 338, + "height": 708 + }, + { + "path": "slices/y/58.png", + "bytes": 5160, + "sha256": "215a0a6e607e9fed1f7b1f6d5302ceef40ca6815ae59cf3e1eb460b2cb3279e3", + "width": 337, + "height": 569 + }, + { + "path": "slices/y/59.png", + "bytes": 4960, + "sha256": "6c8848f84aec74e9faeab8f787375e2ff31d4b25c7103de72a004207b8b2453b", + "width": 306, + "height": 478 + }, + { + "path": "slices/y/60.png", + "bytes": 5137, + "sha256": "e209e7462f5307f4ff4c9e53a4843b2da018bf3a94ad4d971c12fcdce23c002f", + "width": 328, + "height": 480 + }, + { + "path": "slices/y/61.png", + "bytes": 5193, + "sha256": "b35cbf82787f863776fbec87d91a05efba5f56f78d57585911ffd4b1a00d7edc", + "width": 347, + "height": 425 + }, + { + "path": "slices/y/62.png", + "bytes": 5730, + "sha256": "912fe883e47bef63fcffeffa726f90fc6617f0cb802bc2cf9de0004c8c6a1aec", + "width": 348, + "height": 702 + }, + { + "path": "slices/y/63.png", + "bytes": 6108, + "sha256": "a3484e79abaf3b0b744c0d315580b7f099178ad632d7bc47cb3ceb8222dd4bfd", + "width": 340, + "height": 758 + }, + { + "path": "slices/y/64.png", + "bytes": 6305, + "sha256": "cf331d8be6ab9c3586669755e578db19d583d3b0480f507f6d3a088015521353", + "width": 357, + "height": 619 + }, + { + "path": "slices/y/65.png", + "bytes": 6620, + "sha256": "02f23d4f0ac20bc9b3594ed979bd6a00c185bf5e15f8eab6cbab08cb987b1d3d", + "width": 358, + "height": 621 + }, + { + "path": "slices/y/66.png", + "bytes": 7008, + "sha256": "fd6a62a36d4c9c14dfdc6ea548b13e0de98ff4b54b0a3f7abdf2e341bb6fd5a2", + "width": 359, + "height": 653 + }, + { + "path": "slices/y/67.png", + "bytes": 7363, + "sha256": "cb745df29afc06e41f6198c4eff641d0af05f4733dc145aa866e7effbac1437c", + "width": 356, + "height": 677 + }, + { + "path": "slices/y/68.png", + "bytes": 7633, + "sha256": "baccc4526a1f596cd62c3dbafcd7840b25cd515ca27b3e7b3f96268ddbee0751", + "width": 357, + "height": 592 + }, + { + "path": "slices/y/69.png", + "bytes": 7945, + "sha256": "d1b881ffae27a4e94e33f88b436fe46a2055478fd3709504784af6138e1002ee", + "width": 351, + "height": 592 + }, + { + "path": "slices/y/70.png", + "bytes": 8039, + "sha256": "6b65e14789a625ffd0c9a77fdce49ad3b5484ec426c510e5fa011c1c91166140", + "width": 361, + "height": 617 + }, + { + "path": "slices/y/71.png", + "bytes": 8010, + "sha256": "1bf5d406cf669f736e54b21f112a574004c338a701c268a8910337ecfa1145a7", + "width": 362, + "height": 619 + }, + { + "path": "slices/y/72.png", + "bytes": 7909, + "sha256": "05c9b45e85c3840c079a3b981d7bdab2634cc482ab5e3ba331880b06745e339c", + "width": 361, + "height": 618 + }, + { + "path": "slices/y/73.png", + "bytes": 8369, + "sha256": "536240b03aa2fd4cc17d178508bfa1bc20ebf81f3b48506437df3e4d5f529971", + "width": 352, + "height": 595 + }, + { + "path": "slices/y/74.png", + "bytes": 8208, + "sha256": "aba6d28e28cabf893c417d03bf20e911f0408b9ce1181cfcd25c7aa4aaefcd9d", + "width": 352, + "height": 513 + }, + { + "path": "slices/y/75.png", + "bytes": 8598, + "sha256": "033cf2d60b816793207e1f4b6bc8d28cb68b9d97b65ba0e1e71c497b6ed73555", + "width": 348, + "height": 570 + }, + { + "path": "slices/y/76.png", + "bytes": 8928, + "sha256": "b7c013cad06ae7a5c9a856fe3dc7d0b220dad793c3c76093ede2012bf93e6952", + "width": 353, + "height": 571 + }, + { + "path": "slices/y/77.png", + "bytes": 9006, + "sha256": "6f2d20a9418fb5399647bcf25ed3302e484b2f2e094a2cf9decf9ae678b88941", + "width": 352, + "height": 516 + }, + { + "path": "slices/y/78.png", + "bytes": 9060, + "sha256": "920df1841b744650523d79514d71de2ca9da433f2e66954cc4a70b08ea79899d", + "width": 361, + "height": 495 + }, + { + "path": "slices/y/79.png", + "bytes": 9268, + "sha256": "b14c1256244b3b29cf3784f5c1a11a3e778e44cc44b75165abd6b5f9596032e3", + "width": 362, + "height": 481 + }, + { + "path": "slices/y/80.png", + "bytes": 9679, + "sha256": "2596887f8d962de82016972993cc20a068129b8cfcd24868f8ac78445adad00e", + "width": 358, + "height": 503 + }, + { + "path": "slices/y/81.png", + "bytes": 10167, + "sha256": "259cd41384935a652577468aea3cb6bf1ed23cd3d200c2e2b047af61053ceb61", + "width": 352, + "height": 558 + }, + { + "path": "slices/y/82.png", + "bytes": 10007, + "sha256": "f92d2767eeafc259089319ed5e22ffe4d6727c38d3dbd6e645f986859a4ae962", + "width": 333, + "height": 563 + }, + { + "path": "slices/y/83.png", + "bytes": 10236, + "sha256": "68c35822606f49b3126053cfee3b359aa3c9251f7b3ddb4d3b4f8aa0a1f85960", + "width": 353, + "height": 470 + }, + { + "path": "slices/y/84.png", + "bytes": 10865, + "sha256": "9b1ec5ca7258a9cee6050e5c44f7c9734b67b2c1f66c566f7613542a93c435c8", + "width": 356, + "height": 525 + }, + { + "path": "slices/y/85.png", + "bytes": 11009, + "sha256": "791954884d7a410ac25bb81d7e7e184ef0f4787ace7f9af1241b278ee501f248", + "width": 353, + "height": 527 + }, + { + "path": "slices/y/86.png", + "bytes": 11070, + "sha256": "3d135fcad89d5342b78315ef0f86613e61ab20509b20d71ad040d1d931b636fa", + "width": 342, + "height": 508 + }, + { + "path": "slices/y/87.png", + "bytes": 12045, + "sha256": "06a0fe140d32d991d1e0b241c868b32dd9d1af001ce4928c883a5f07a62b121a", + "width": 359, + "height": 593 + }, + { + "path": "slices/y/88.png", + "bytes": 12075, + "sha256": "5923eed377135f4a996a088aabd433373203ac388866d9a99ea1ef7b224be390", + "width": 358, + "height": 505 + }, + { + "path": "slices/y/89.png", + "bytes": 12199, + "sha256": "32eb9864463985afe09acb9fac3e3e51209e1445b3091aadbcb71031c371a522", + "width": 347, + "height": 503 + }, + { + "path": "slices/y/90.png", + "bytes": 13212, + "sha256": "d5eb503d80fa3f64a479157b53a8931d0b0067e71ef7c9bb9f8a969362927b55", + "width": 351, + "height": 659 + }, + { + "path": "slices/y/91.png", + "bytes": 13070, + "sha256": "890266876cca236c74668b94515d777485120fff5b2a68a34ee5b67324b4fce5", + "width": 352, + "height": 495 + }, + { + "path": "slices/y/92.png", + "bytes": 13425, + "sha256": "23b836049939f253ee0553971309a310a67b664e253d7658f027f97798547038", + "width": 357, + "height": 509 + }, + { + "path": "slices/y/93.png", + "bytes": 13687, + "sha256": "39bba62a6c02b3f4d08be05f44dba9c903d54e243738b166a322b3dc2c1a052d", + "width": 351, + "height": 509 + }, + { + "path": "slices/y/94.png", + "bytes": 14021, + "sha256": "5e9238a4368e725a1054a71228e9094fcb0cea707827f780a8a91d2d5c9824fd", + "width": 351, + "height": 486 + }, + { + "path": "slices/y/95.png", + "bytes": 13827, + "sha256": "3e7a349e0c32625c35b2b30027aa215adfabb73c19a54bdb8e1a40821475289a", + "width": 352, + "height": 358 + }, + { + "path": "slices/y/96.png", + "bytes": 14389, + "sha256": "5a9532475dfcccf32612b4d05ebbaae360e20e0df6249821ea3cf7a134deb18c", + "width": 351, + "height": 389 + }, + { + "path": "slices/y/97.png", + "bytes": 14769, + "sha256": "8c2cf18c334ced48e5eac0fd1ae26a166111726cc6c92aca81ec1ce5d82640ca", + "width": 348, + "height": 378 + }, + { + "path": "slices/y/98.png", + "bytes": 14681, + "sha256": "6ea5cc842796eaf59359c8b8c916658af5c9ee78467c943da1eec40c3268762c", + "width": 351, + "height": 344 + }, + { + "path": "slices/y/99.png", + "bytes": 15473, + "sha256": "e5ba527d49a10804437a1cc04703828f32c9084c7d3d764cc66c83d4da45a8cf", + "width": 351, + "height": 481 + }, + { + "path": "slices/z/00.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/01.png", + "bytes": 114, + "sha256": "847e22ebc7f7ff670f1cd72c57aa485fcf5a1ec50d2041a14b0e1ee2346d5453", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/02.png", + "bytes": 94, + "sha256": "9c25a1889ab983cbd62789e419111838196ceac0de2630f76adb1d0110bc46b0", + "width": 1, + "height": 2 + }, + { + "path": "slices/z/03.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/04.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/05.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/06.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/07.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/08.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/09.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/10.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/100.png", + "bytes": 114, + "sha256": "e0e7fffa98ea5f08400673dff8fe21128f7f04fe8b46d2f1ab54e22158cd207e", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/101.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/102.png", + "bytes": 265, + "sha256": "563268da3236343d0e312dabe3e758ace865881df7dee2e14d3f6f528645f809", + "width": 224, + "height": 94 + }, + { + "path": "slices/z/103.png", + "bytes": 287, + "sha256": "c6076098e127382fc7f306a6dcec37271f6b73ed80dd5f6d8f47d8816f9d445c", + "width": 224, + "height": 94 + }, + { + "path": "slices/z/104.png", + "bytes": 117, + "sha256": "9ac4ac472eaac078aaeeae0993ad73564e7053f5f20ef36ca37c9bafcf8f7fcc", + "width": 4, + "height": 4 + }, + { + "path": "slices/z/105.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/106.png", + "bytes": 116, + "sha256": "fe8b5d3fb11e3bd3ed1d98c0a044281f276e0b2ab2939ff98eaa395cd5100bb6", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/107.png", + "bytes": 114, + "sha256": "bbd49ba99eec2585761ba0e6314e56b00b225dcac1babaa237d4deb4defa9262", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/108.png", + "bytes": 102, + "sha256": "4898780f7a10241a8b7458140e66cf66dfd8e4bf82702fac321a7572c5d9a3b0", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/109.png", + "bytes": 104, + "sha256": "1eb3f8565dc7d94ded50d53f5a2fd03be19f265d21261f7329938881708c8d8c", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/11.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/110.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/111.png", + "bytes": 214, + "sha256": "8e7b9175f0d3a1201685281c86c7f39553baec6bcbf06690a1ca28f1abbaa124", + "width": 98, + "height": 228 + }, + { + "path": "slices/z/112.png", + "bytes": 106, + "sha256": "11a9fd44c9f3b2b3611c8883febd25be1fc53bf689ebf005822cc0c540146830", + "width": 3, + "height": 2 + }, + { + "path": "slices/z/113.png", + "bytes": 143, + "sha256": "036afebde5592af92fef2d046313fceeba62c9253a3638ed277d0a22870e2829", + "width": 25, + "height": 51 + }, + { + "path": "slices/z/114.png", + "bytes": 277, + "sha256": "92a91a6d8723d94dcd85786a4613c790ae4c99327377ce367acc0159c050eacf", + "width": 161, + "height": 147 + }, + { + "path": "slices/z/115.png", + "bytes": 121, + "sha256": "6571bd2581ef20debd600823f8d136e70b1b9084c48030a6878df77c2203ce28", + "width": 23, + "height": 50 + }, + { + "path": "slices/z/116.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/117.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/118.png", + "bytes": 340, + "sha256": "d675ae9cbe7a6d0b03011a259f3064de41bc549ec865455db0a109dc6e61cea5", + "width": 200, + "height": 275 + }, + { + "path": "slices/z/119.png", + "bytes": 513, + "sha256": "820221541e941a6e515acadda5230ed0365a014b5dfac4d85102ded06940319e", + "width": 317, + "height": 275 + }, + { + "path": "slices/z/12.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/120.png", + "bytes": 531, + "sha256": "f15e6cee7bc5f35e91555bcdbbbe35a2ccb4b8eacaf5a58a4f1fb5ebbae9fea7", + "width": 317, + "height": 301 + }, + { + "path": "slices/z/121.png", + "bytes": 267, + "sha256": "b520b703ec074e18edea197eb2aa22a38993fea2841edf640cad72efc44eff2f", + "width": 131, + "height": 236 + }, + { + "path": "slices/z/122.png", + "bytes": 203, + "sha256": "08c1630b28cc77429021a9c97c84dd9c5ee030d6d16e78954d13d39673654279", + "width": 209, + "height": 41 + }, + { + "path": "slices/z/123.png", + "bytes": 227, + "sha256": "3b0668856277d332c141a36e4eac9b2196ea1ca1e7a918eab55620af4316d0e9", + "width": 121, + "height": 20 + }, + { + "path": "slices/z/124.png", + "bytes": 256, + "sha256": "4014ea48f53ffc938f41b008ab5e8c230f79071342f6cdce5464ea0ee835c8ff", + "width": 123, + "height": 33 + }, + { + "path": "slices/z/125.png", + "bytes": 495, + "sha256": "7d24c88b83f8d9983b617fc52e22b85f65d4063e58e72932192a765a07cc09c9", + "width": 215, + "height": 271 + }, + { + "path": "slices/z/126.png", + "bytes": 514, + "sha256": "72a0605084c08d11b913c1bb0989aaf398bc17d8f33f85b7641829218ceef923", + "width": 217, + "height": 272 + }, + { + "path": "slices/z/127.png", + "bytes": 314, + "sha256": "ba4b061442383e517c4eba05d6e72819738a2e85f2598bd7fc9aad56a3ad4a6f", + "width": 217, + "height": 34 + }, + { + "path": "slices/z/128.png", + "bytes": 293, + "sha256": "dae0ec1361125cdcbec944ad5f978330bef42853d84382c2741c95ef8cb94792", + "width": 218, + "height": 34 + }, + { + "path": "slices/z/129.png", + "bytes": 308, + "sha256": "9c0e3d4c0f000865828565d4102dd7be8483ff10a599e0d792ab245eee7e03ba", + "width": 126, + "height": 48 + }, + { + "path": "slices/z/13.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/130.png", + "bytes": 501, + "sha256": "b4cea5b3761c831b24083226a28992b28c2872f4305e09e6a0494c57108607a2", + "width": 154, + "height": 322 + }, + { + "path": "slices/z/131.png", + "bytes": 348, + "sha256": "9070f00dfd151972679450af74f1919fb6e1e41dd92b36dff43febba1c1653c1", + "width": 65, + "height": 312 + }, + { + "path": "slices/z/132.png", + "bytes": 286, + "sha256": "ba865f862037b18aba5d72726082751de724d62aa2a24491f4c0e0cfbddb4b83", + "width": 182, + "height": 40 + }, + { + "path": "slices/z/133.png", + "bytes": 258, + "sha256": "e15ffdbdf1669ceb1971cf7bf05a761ed95785d3142bcb34511a28f6d2ddeffe", + "width": 182, + "height": 40 + }, + { + "path": "slices/z/134.png", + "bytes": 356, + "sha256": "ae0e395fa751a909e5924fe9f0900d1949347d52a58d92915af2d5c88136c9ef", + "width": 165, + "height": 180 + }, + { + "path": "slices/z/135.png", + "bytes": 355, + "sha256": "9c5720c297a565a7b69cf12de9600ef04e5ab1ac8de7b8d93605caac2211f93c", + "width": 165, + "height": 181 + }, + { + "path": "slices/z/136.png", + "bytes": 281, + "sha256": "d143b6de5c5c131a0b34119280ba7031134e2a839ae45d7ed1e6251d12e91a27", + "width": 140, + "height": 153 + }, + { + "path": "slices/z/137.png", + "bytes": 603, + "sha256": "e46479c8e4968cac064b1186b53491b6de1ad7dcdc0b43188a1648e98444c2bb", + "width": 292, + "height": 331 + }, + { + "path": "slices/z/138.png", + "bytes": 729, + "sha256": "671ce13ff75aa1e0703be6d7d4f7058c479fe58cb838de11e6a79c29651b5dde", + "width": 297, + "height": 331 + }, + { + "path": "slices/z/139.png", + "bytes": 649, + "sha256": "449cc1abc4d038c9e7b51038497d1df7a094174977f089e3c414512ba2f6a7ab", + "width": 296, + "height": 328 + }, + { + "path": "slices/z/14.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/140.png", + "bytes": 154, + "sha256": "b8c6e1b9da5c0a67f4f6edcce4759b3aeaebe2e721c80f3e8ac3df3c27ce2c9c", + "width": 43, + "height": 38 + }, + { + "path": "slices/z/141.png", + "bytes": 368, + "sha256": "b41cc0898189c243e0801099a625f447d53ef892825b97c2a6f10728da5f89cd", + "width": 232, + "height": 247 + }, + { + "path": "slices/z/142.png", + "bytes": 386, + "sha256": "f1dd4980abff5fcff9555ad1fddd9a13b976a5fc1ebaec462bb82be139f692ba", + "width": 232, + "height": 253 + }, + { + "path": "slices/z/143.png", + "bytes": 456, + "sha256": "4cf9759f4a9ecc1acbe80ccf6a64af6e68065aa8ffdd61483fade45b905bce5c", + "width": 230, + "height": 307 + }, + { + "path": "slices/z/144.png", + "bytes": 413, + "sha256": "c54b29955469eb8fd4ff37274b7da35b3d9ecfe57e88a646227851166126afd5", + "width": 212, + "height": 315 + }, + { + "path": "slices/z/145.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/146.png", + "bytes": 184, + "sha256": "1bb44ad983165273aed3ee517cec2c3b78fcbbde962a0fd6ccb10e4c51b1a1d0", + "width": 77, + "height": 193 + }, + { + "path": "slices/z/147.png", + "bytes": 410, + "sha256": "f4b00042c7c0ef2b9c63b1c30ef0dfcb7f7c51c14bc3b479da41f94b64209f8c", + "width": 294, + "height": 212 + }, + { + "path": "slices/z/148.png", + "bytes": 188, + "sha256": "00aa85e6b199e875db19036996e4c60d6f0f9e5bb4d90c435ff53e0849f33e38", + "width": 38, + "height": 277 + }, + { + "path": "slices/z/149.png", + "bytes": 278, + "sha256": "ec9eb8288809a8374f940e649e79108f48858b64eddf7eacf60bf62c26638a08", + "width": 148, + "height": 231 + }, + { + "path": "slices/z/15.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/150.png", + "bytes": 262, + "sha256": "b6b6a29e7d3213bbdf7cb92a1aa44656a9bdeeeb7c3ad03020def97887a77148", + "width": 290, + "height": 60 + }, + { + "path": "slices/z/151.png", + "bytes": 255, + "sha256": "0158ec93fca46429629586f40475cc6f20a8f7fec755897d25827995e5a75ffb", + "width": 289, + "height": 66 + }, + { + "path": "slices/z/152.png", + "bytes": 383, + "sha256": "df05be1ae9b4a55e10ec1bfa8bb963bca8f214ae72cfe63f9e12ed6d535b601a", + "width": 287, + "height": 217 + }, + { + "path": "slices/z/153.png", + "bytes": 389, + "sha256": "d9f4f50b1b1130ff4e16ac4fc8cca839c6655fd676f89f6f2709acb5e8ce8f82", + "width": 289, + "height": 171 + }, + { + "path": "slices/z/154.png", + "bytes": 340, + "sha256": "8b2bfcba7be718325a7ca7a765990d7adf891fcf3312548771473a72ad635422", + "width": 288, + "height": 171 + }, + { + "path": "slices/z/155.png", + "bytes": 147, + "sha256": "a51f10b5bf4642361b9ce9cfe5f045d6a5d47ccc0b507b5004e564feba5bcf7b", + "width": 25, + "height": 17 + }, + { + "path": "slices/z/156.png", + "bytes": 479, + "sha256": "2819016f889204112686b9fb7d79571c89a5c8e4421fc360999362c9d1c7551d", + "width": 265, + "height": 196 + }, + { + "path": "slices/z/157.png", + "bytes": 648, + "sha256": "68ae56253ca02c41edf8b96894850f787df5e31d3deaef7a61a859dd12dee59b", + "width": 268, + "height": 265 + }, + { + "path": "slices/z/158.png", + "bytes": 628, + "sha256": "4ca1b5df202ac806501ece0bbc8883e773c18a3ccf93748acac780082510f6b8", + "width": 274, + "height": 266 + }, + { + "path": "slices/z/159.png", + "bytes": 339, + "sha256": "f30264a40f5b27f5b7c7ec10893ed2fd4a790486c79129c1e651da4c3876558f", + "width": 142, + "height": 67 + }, + { + "path": "slices/z/16.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/160.png", + "bytes": 334, + "sha256": "473f8a6563660a4d90e60798bb9cf2202deaff6a925ab3cdbc292c00f69b0e40", + "width": 125, + "height": 70 + }, + { + "path": "slices/z/161.png", + "bytes": 291, + "sha256": "852f8b10dc16488f7ca2d0c8da75bd519afe9751ba45e7dc387392e3d22ba250", + "width": 124, + "height": 68 + }, + { + "path": "slices/z/162.png", + "bytes": 402, + "sha256": "d230493fef9819505da37f41fd11f99e418c2228ad40fcac9f40b30d15ddfd07", + "width": 295, + "height": 61 + }, + { + "path": "slices/z/163.png", + "bytes": 790, + "sha256": "731c208c8c17f8eed6e9c2d8b057d7db5e764899adf15872f597c99182241a01", + "width": 296, + "height": 337 + }, + { + "path": "slices/z/164.png", + "bytes": 808, + "sha256": "d29d64b04e3108c4924bf1946a13b8c6f196d35d7396f398d49294867a1a0569", + "width": 296, + "height": 337 + }, + { + "path": "slices/z/165.png", + "bytes": 718, + "sha256": "57d8a21140fabad8fdd7ab7afe1365af736919244eac705e71a9377766b0c9fc", + "width": 285, + "height": 336 + }, + { + "path": "slices/z/166.png", + "bytes": 644, + "sha256": "982e0ee0e69add44cf6e7b8b96b5432ae319d198b06fd71e838dcacb82fd07bf", + "width": 284, + "height": 318 + }, + { + "path": "slices/z/167.png", + "bytes": 190, + "sha256": "1848aa268ec7ec95b25fa82f86abc5b5db3e0f6cd5f64d13368cb955bf69994e", + "width": 39, + "height": 39 + }, + { + "path": "slices/z/168.png", + "bytes": 175, + "sha256": "1d36bdf2382ce780ee5cd76be195c31d1e363c8e4a1b2a84f1c423bcc067ddda", + "width": 40, + "height": 40 + }, + { + "path": "slices/z/169.png", + "bytes": 206, + "sha256": "bab71c6e799b94c099c2474dd4bf76b8a919e43acb08ce36e0aceca1aecb4b82", + "width": 40, + "height": 150 + }, + { + "path": "slices/z/17.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/170.png", + "bytes": 361, + "sha256": "f727dfe8d516508eff2d72f5e9687fc8fae6f3e096717ff6aefc63205ef2c421", + "width": 101, + "height": 320 + }, + { + "path": "slices/z/171.png", + "bytes": 625, + "sha256": "c8cb94c33432ba1277f35523bc0195cc123abf55235c0e3465434ad0ee54abb6", + "width": 293, + "height": 320 + }, + { + "path": "slices/z/172.png", + "bytes": 718, + "sha256": "25322a83b9072baf9ac262423aa428bd92aed82cf0ff0b6b6ec12b345ce85783", + "width": 335, + "height": 329 + }, + { + "path": "slices/z/173.png", + "bytes": 721, + "sha256": "645d0a083dfcdc842258e2d877ac9c4ad23bfba68ef099f602720e858bd1b5d3", + "width": 335, + "height": 320 + }, + { + "path": "slices/z/174.png", + "bytes": 564, + "sha256": "189d6cc686df4ea90648d45ec95fbc50f91e970234ccdbe8e16133f080ddff1e", + "width": 331, + "height": 233 + }, + { + "path": "slices/z/175.png", + "bytes": 438, + "sha256": "6f06992b4deee907f0b75885d8d42f32c9917b95d2ca32f9e4686aeec74037e8", + "width": 284, + "height": 234 + }, + { + "path": "slices/z/176.png", + "bytes": 508, + "sha256": "8ea4ba4b16b640b6cb693b74dbd99a2acea8275742fecb3edf6f52596cbee9a4", + "width": 341, + "height": 219 + }, + { + "path": "slices/z/177.png", + "bytes": 515, + "sha256": "687eea67f95b51fd9db911ce0972af0a4ca97ac51fb77e9ff6340a61a23ac587", + "width": 257, + "height": 228 + }, + { + "path": "slices/z/178.png", + "bytes": 673, + "sha256": "f7208f9e76abeab9ebd3bc4435ef7e4659f4035f3f8f713c75624c7e7cf3641f", + "width": 318, + "height": 297 + }, + { + "path": "slices/z/179.png", + "bytes": 731, + "sha256": "534da440a9a9a2b7b44faef774e7edbc1c5ce65ff1c4c2682deefded035370a4", + "width": 326, + "height": 298 + }, + { + "path": "slices/z/18.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/180.png", + "bytes": 711, + "sha256": "d8f2ee8da53ca9daee9d9c684aedff4c9b1005c5738909e5edd302be0bd735f6", + "width": 327, + "height": 305 + }, + { + "path": "slices/z/181.png", + "bytes": 722, + "sha256": "bb47e66e87a79f33db84e0a604db5a1eeb517b77cc6f9a836f9e6911a8de3fbe", + "width": 335, + "height": 304 + }, + { + "path": "slices/z/182.png", + "bytes": 751, + "sha256": "09f43619c3e43ec5961005a674662ddc262a5c47400cefb07163c9ac08d25943", + "width": 318, + "height": 295 + }, + { + "path": "slices/z/183.png", + "bytes": 633, + "sha256": "367ce3bbe7b430792b03697ad7a6ddbe0dff51a176465ac0380c30e228c3a8d9", + "width": 260, + "height": 295 + }, + { + "path": "slices/z/184.png", + "bytes": 619, + "sha256": "34a20ed90d0e8784bdd478a39be3f37833c811d0d7fd94e11e636f9897a11d5a", + "width": 228, + "height": 294 + }, + { + "path": "slices/z/185.png", + "bytes": 699, + "sha256": "d344ad4142089bb1b14a675da30c2fd5f79dcd3d0be4da389dee0bdf0dace6b1", + "width": 261, + "height": 270 + }, + { + "path": "slices/z/186.png", + "bytes": 623, + "sha256": "4094301f789629d2dcaf674640f1eb30101bfdfde5318be2d7415d1171fb3b37", + "width": 268, + "height": 273 + }, + { + "path": "slices/z/187.png", + "bytes": 833, + "sha256": "60dfeb9f6bc71bfebc7ef6ed7b53e52b05c4a6919cb274e3c59e29ddaa6d46c0", + "width": 309, + "height": 335 + }, + { + "path": "slices/z/188.png", + "bytes": 1060, + "sha256": "ce35ad00e8a8501818f127e9724cdf989698cac2f749a41adc93254c1dcb3244", + "width": 343, + "height": 337 + }, + { + "path": "slices/z/189.png", + "bytes": 1101, + "sha256": "4bcc496a8d3a4b527b0a1f5616ff9f09198ed0bddd78b951f4677430e0900474", + "width": 343, + "height": 356 + }, + { + "path": "slices/z/19.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/190.png", + "bytes": 1090, + "sha256": "5b8d9336f5a92f48df99270aa2bb1b0b555772713b3f24176ac9d0748a1446ff", + "width": 302, + "height": 356 + }, + { + "path": "slices/z/191.png", + "bytes": 1057, + "sha256": "3f93b32d46f95690c69e62b0f8e01f946f94b7671bb03eb362734b58a4560c7b", + "width": 318, + "height": 347 + }, + { + "path": "slices/z/192.png", + "bytes": 1125, + "sha256": "5e51d72912e373f80c9553f33344b2f24ef94e79a15c187ec84b195cfe8ab41f", + "width": 335, + "height": 329 + }, + { + "path": "slices/z/193.png", + "bytes": 1127, + "sha256": "e277b3f9387daa01eb0a6f356fedca6a8b33703f2b1b2f553bd34e802bcc5c1e", + "width": 337, + "height": 314 + }, + { + "path": "slices/z/194.png", + "bytes": 1145, + "sha256": "508d01f27b88b48de83504df7572d1ece74913ef25a32d23eee1b3443382c1d7", + "width": 342, + "height": 315 + }, + { + "path": "slices/z/195.png", + "bytes": 1305, + "sha256": "0774a469aa134b70bb0187e3fdb78f3a54c1708712238d530b5932a4f91f0415", + "width": 331, + "height": 333 + }, + { + "path": "slices/z/196.png", + "bytes": 1336, + "sha256": "c4e3ffc7fbb93abbf84421d98ae413c11da2608d9e9567baaa56ff135e9625ea", + "width": 347, + "height": 341 + }, + { + "path": "slices/z/197.png", + "bytes": 1499, + "sha256": "3079862bccf9cde9cf675265131814f018f084dab7eb9e04014e7f5caf8ac48d", + "width": 361, + "height": 341 + }, + { + "path": "slices/z/198.png", + "bytes": 1642, + "sha256": "455c034d3a94f4499d47f2433021cc70c1f8d9c1c5d6c01e3d115e8c9f250856", + "width": 362, + "height": 343 + }, + { + "path": "slices/z/199.png", + "bytes": 1999, + "sha256": "d8f4c07c6a558c21f08020cd970f6c3b5c3f14e94da76d7e3d75d584c72c47b6", + "width": 341, + "height": 312 + }, + { + "path": "slices/z/20.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/200.png", + "bytes": 2592, + "sha256": "d0f500ee64e2e417e5f56c52787f919cbb7860064729c2f469166f239570a238", + "width": 366, + "height": 340 + }, + { + "path": "slices/z/201.png", + "bytes": 3465, + "sha256": "89ba3aaf177c40084c3aa8ef1e706e374a57903b4a52e4b4d1dc619ae4bc8f47", + "width": 366, + "height": 339 + }, + { + "path": "slices/z/202.png", + "bytes": 3881, + "sha256": "de120802be0876cba0917a3aa225b3d02dc7bad00f5717170e0af8434fefbc38", + "width": 348, + "height": 334 + }, + { + "path": "slices/z/203.png", + "bytes": 3891, + "sha256": "0f9bf45460bc90cbe79ebb6a25d12f309c365730d11e9e4f621f2ae9f4edd0d5", + "width": 356, + "height": 353 + }, + { + "path": "slices/z/204.png", + "bytes": 4060, + "sha256": "66f42c61b2f32200643d1ede6241871b39defe4ed212d2cccb25c3cf21a5ac70", + "width": 357, + "height": 354 + }, + { + "path": "slices/z/205.png", + "bytes": 4177, + "sha256": "dda0b47df7888921cff1d617e36284209d46b6c5e709669cded3cd4706c1f634", + "width": 356, + "height": 324 + }, + { + "path": "slices/z/206.png", + "bytes": 4131, + "sha256": "cb9e63156e53de249a29d6a386c4fa566252271ad59d514d3775868e843de5bd", + "width": 352, + "height": 352 + }, + { + "path": "slices/z/207.png", + "bytes": 4318, + "sha256": "1db8ab4447eba57cb841c4ba63643b7e159c8a4e9135892d4e1ee2cc20597d5e", + "width": 363, + "height": 352 + }, + { + "path": "slices/z/208.png", + "bytes": 4302, + "sha256": "cb8017830f123f66260fdd457730da9dc1294514fc9e2255780c623e8ab1e5ac", + "width": 364, + "height": 331 + }, + { + "path": "slices/z/209.png", + "bytes": 4353, + "sha256": "9a5d397c8680fed545ebdc30501b7fa98a559762529205a48ab96619dea8a6e0", + "width": 364, + "height": 351 + }, + { + "path": "slices/z/21.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/210.png", + "bytes": 4352, + "sha256": "d7c21fdd66b1bc00dd7b76de83f20808081d003173282091b02f9ccf82b3f5bd", + "width": 351, + "height": 349 + }, + { + "path": "slices/z/211.png", + "bytes": 4649, + "sha256": "e06af0c3dcc647153bf8671566a249110a1e96addf0bb7e9c4c8d8ba34ee5603", + "width": 359, + "height": 355 + }, + { + "path": "slices/z/212.png", + "bytes": 5157, + "sha256": "5592453d9736dd57378f4960c8f6ce14617840000d862b47e4ded96087f348b5", + "width": 358, + "height": 353 + }, + { + "path": "slices/z/213.png", + "bytes": 5510, + "sha256": "1c90dd908b073058c26f31240d21507f7b50298cb99d247b9daf2b6e62ce7dda", + "width": 358, + "height": 352 + }, + { + "path": "slices/z/214.png", + "bytes": 5812, + "sha256": "69946ce01e1d19a79f5755f471915694bb094763095b86112dade21f3e3aec47", + "width": 361, + "height": 349 + }, + { + "path": "slices/z/215.png", + "bytes": 6054, + "sha256": "55d224774ea8837b56a09c9822f035df0ba9588534d631ccab90d09dd97a9f13", + "width": 358, + "height": 352 + }, + { + "path": "slices/z/216.png", + "bytes": 6710, + "sha256": "7e23003e4052ca1e1f012562c8a4f0c1210f1f32ac62b21ceb555a259ad1ef5c", + "width": 364, + "height": 352 + }, + { + "path": "slices/z/217.png", + "bytes": 6835, + "sha256": "17ea96eead22282115d63b2d46d1c015617219ba71456b3f7eb002a0c6eea0c5", + "width": 360, + "height": 350 + }, + { + "path": "slices/z/218.png", + "bytes": 7054, + "sha256": "6b89672a19076dbd41a4a5b8b08a606d444fd78b9c1b78c8662f4c1207fd02c9", + "width": 356, + "height": 353 + }, + { + "path": "slices/z/219.png", + "bytes": 7211, + "sha256": "03de403621f687ccd4a158541e024b7132f4072f35df036c5d6747d8b833d6b6", + "width": 362, + "height": 355 + }, + { + "path": "slices/z/22.png", + "bytes": 114, + "sha256": "6e54ba94b75b2db34f86403b73f12ff862b69a2867ef8e60f4264a0e3ff6e216", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/220.png", + "bytes": 7547, + "sha256": "7a91c18edfed5270c701fbb7764267d6ffe7d50a6fb00f98937afa1a03a14a72", + "width": 362, + "height": 353 + }, + { + "path": "slices/z/221.png", + "bytes": 7803, + "sha256": "3943646acffdc3ff66d7cc8e8ee8150c04c094662ad62aad10896402a5bbe48f", + "width": 359, + "height": 353 + }, + { + "path": "slices/z/222.png", + "bytes": 8001, + "sha256": "5be2ccf76a7d7ef6067aad5beb957db20eb88a81e03c8aa2a5be0e206984a2f4", + "width": 360, + "height": 355 + }, + { + "path": "slices/z/223.png", + "bytes": 8076, + "sha256": "251454daa46819063a97f427dd93991f98a8a5152325ad4beebffb294cd6aa69", + "width": 361, + "height": 353 + }, + { + "path": "slices/z/224.png", + "bytes": 8390, + "sha256": "34e84b7f7ae5ee6577b9800aa232f8f24fbcfeda5dec699e38610b90eef08ae0", + "width": 360, + "height": 354 + }, + { + "path": "slices/z/225.png", + "bytes": 8764, + "sha256": "0afd75e78ece9fc443ce94f01aa6f951ad542ed307f01d282ea166ddbe83302a", + "width": 361, + "height": 358 + }, + { + "path": "slices/z/226.png", + "bytes": 9007, + "sha256": "ce18de782e1982d765be0b81f13b15c4eaa167a31c9471c019c6195c42553767", + "width": 361, + "height": 358 + }, + { + "path": "slices/z/227.png", + "bytes": 8959, + "sha256": "e052024f5678b5ff3c2ba3a166e4de1ba558c718a79e5b8723be37f3e6a6adaa", + "width": 357, + "height": 357 + }, + { + "path": "slices/z/228.png", + "bytes": 9240, + "sha256": "223b559cda36ab4543db852e263b07388ce5ffecb3d05eea363deae7ac493be4", + "width": 359, + "height": 359 + }, + { + "path": "slices/z/229.png", + "bytes": 9622, + "sha256": "0264f54fd15862edc8f1b1c20e9f33ac6c5d3f9a9855c76642f3aabc4f9623df", + "width": 361, + "height": 361 + }, + { + "path": "slices/z/23.png", + "bytes": 94, + "sha256": "844834f70fda51dc9ba4ab6c00b780d8374e818997088c5a983d6cfe29f9dcb7", + "width": 1, + "height": 2 + }, + { + "path": "slices/z/230.png", + "bytes": 9830, + "sha256": "a144b9b2a7714410439d247ce61ebe025f6aa2345a4926bbe441775cdf93e379", + "width": 359, + "height": 363 + }, + { + "path": "slices/z/231.png", + "bytes": 10025, + "sha256": "b68076950f06d84e34be6fb9db2ae7f85f063e4bfdf54e1063c3e29038bf990b", + "width": 360, + "height": 365 + }, + { + "path": "slices/z/232.png", + "bytes": 10414, + "sha256": "e77d45e842792167bbc3daa8179d86193272ef5f3f465a34f877f86b05dcc412", + "width": 361, + "height": 366 + }, + { + "path": "slices/z/233.png", + "bytes": 10741, + "sha256": "077bb2bebd6c4f23951101f75ba1204ceedb42d51fb031910d0240c634357cfc", + "width": 357, + "height": 364 + }, + { + "path": "slices/z/234.png", + "bytes": 10681, + "sha256": "04607c77e3750a0f3e7adcfff8a0f39a0f5f014c7edce503b550076340025d6f", + "width": 361, + "height": 366 + }, + { + "path": "slices/z/235.png", + "bytes": 11108, + "sha256": "a4522790288e7c4ab3ea0c66c98fa006b5f0e477671dc4d710b6c4eccb2f11c1", + "width": 363, + "height": 367 + }, + { + "path": "slices/z/236.png", + "bytes": 11144, + "sha256": "e45522def9cf39604d7e479ed12f5a3b00f91b99f2c45e9cf6071299738cfa14", + "width": 359, + "height": 368 + }, + { + "path": "slices/z/237.png", + "bytes": 11837, + "sha256": "3632e0245c8315083e7cb31bdc5e1dc5fafb5c7058ec8513a2dd2937ba341736", + "width": 364, + "height": 369 + }, + { + "path": "slices/z/238.png", + "bytes": 12028, + "sha256": "fb6b47242317fb9b6bda89c49e4f64f89ceab09d427960c04edfad9b6c1723cd", + "width": 364, + "height": 369 + }, + { + "path": "slices/z/239.png", + "bytes": 12117, + "sha256": "1e667e03e6f36a3f4ec50a530707845ad23fff61bea1c147eadf3a3e33503086", + "width": 355, + "height": 370 + }, + { + "path": "slices/z/24.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/240.png", + "bytes": 12563, + "sha256": "c1a062e145188c5c658dd7a45e7bfbf862668b3bda356982c4587d204c64345f", + "width": 355, + "height": 369 + }, + { + "path": "slices/z/241.png", + "bytes": 13174, + "sha256": "e54524925d26a4665d127b8c58fed50407a7d8b6ed0c0bb79762931a2dfb34af", + "width": 356, + "height": 369 + }, + { + "path": "slices/z/242.png", + "bytes": 13479, + "sha256": "da5b0b4dc61405e657bdb653547e420aded2586df993f923804b30ae9b91c91d", + "width": 362, + "height": 368 + }, + { + "path": "slices/z/243.png", + "bytes": 13730, + "sha256": "3d90b41fcec0d685c362f5f4d75f21489c9ce0388bebf3007486023d5efbf29d", + "width": 356, + "height": 366 + }, + { + "path": "slices/z/244.png", + "bytes": 14349, + "sha256": "2e3d87878f7b5415a282248aaf8492efd5879e84fe0bdc460584aa4f78931952", + "width": 359, + "height": 368 + }, + { + "path": "slices/z/245.png", + "bytes": 14651, + "sha256": "94832deac3870fcfcea988948561ac970573cd1ab967b28ab059fd9c8e5a2246", + "width": 356, + "height": 368 + }, + { + "path": "slices/z/246.png", + "bytes": 14786, + "sha256": "6faea90c8d4dc23726517df056a66f2d2b4a63dac8cfde2061a0d329d73bc3a3", + "width": 355, + "height": 369 + }, + { + "path": "slices/z/247.png", + "bytes": 15189, + "sha256": "cc32e8a3b2c95a8276a61f5ba364e1e53d295bf9e7b2a8e40dafb25b7e83b0a3", + "width": 356, + "height": 364 + }, + { + "path": "slices/z/248.png", + "bytes": 15512, + "sha256": "c9801b1039682a262d0626459da71753c7a71bcb2091ea57ece51584cd9c1464", + "width": 363, + "height": 364 + }, + { + "path": "slices/z/249.png", + "bytes": 15841, + "sha256": "885dcd7c17922996ec33cd2391a6296f723f84e01ee82011ba0506467cc18ab6", + "width": 357, + "height": 360 + }, + { + "path": "slices/z/25.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/250.png", + "bytes": 16029, + "sha256": "43054f3a20105487a98422a6cb108a883524684d0679f1e24b14daf8e802e344", + "width": 359, + "height": 363 + }, + { + "path": "slices/z/251.png", + "bytes": 16270, + "sha256": "fb58ad8867eca0b02b6e1c151c84057269f0900fd22762c4819a9e995abb05aa", + "width": 359, + "height": 356 + }, + { + "path": "slices/z/252.png", + "bytes": 16512, + "sha256": "1aaa623d5550034e71f333a70efda7e0ec4352cb11e52f3c86e9bad3fd448002", + "width": 364, + "height": 363 + }, + { + "path": "slices/z/253.png", + "bytes": 16600, + "sha256": "94c24b2279ce706d5d59ddf5d231a4ce76be68b880c47eb99a5413fe7128054a", + "width": 357, + "height": 355 + }, + { + "path": "slices/z/254.png", + "bytes": 16842, + "sha256": "0c6ae04af01925ecbecfa47a1da54f303c0bd3876b57b363ab68f5e02448f788", + "width": 362, + "height": 357 + }, + { + "path": "slices/z/255.png", + "bytes": 17444, + "sha256": "6bd83acdc4b34e868dee86d96acbb4470d125c519fceb4bb2a035bb806e0023f", + "width": 359, + "height": 367 + }, + { + "path": "slices/z/256.png", + "bytes": 17473, + "sha256": "0b9f28b7fa12c94c90c5f773da7e3fc3ca6921f5bb614836e1b064d9fad04db6", + "width": 365, + "height": 358 + }, + { + "path": "slices/z/257.png", + "bytes": 17495, + "sha256": "cdc36aefe4577d39f05f1b835fb615faddefee0d6a1a50ad7b888e08bbdcf04c", + "width": 359, + "height": 359 + }, + { + "path": "slices/z/258.png", + "bytes": 17937, + "sha256": "4ae82b33e6f8f1ed45f5730e693fae3826dbc8b7d27fcf3df25f4058c906f16a", + "width": 358, + "height": 357 + }, + { + "path": "slices/z/259.png", + "bytes": 17968, + "sha256": "5a223f716e31d316ccb92cf2ffc0cb1438881a6f581051202ced2a38fdb106e2", + "width": 364, + "height": 358 + }, + { + "path": "slices/z/26.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/260.png", + "bytes": 17668, + "sha256": "0146c02248b689293f5cd7ed64037385b0a8ac3831a1703dbe071ab257c424fd", + "width": 357, + "height": 356 + }, + { + "path": "slices/z/261.png", + "bytes": 18051, + "sha256": "bfcb98f23ac52ef70a1e42832209364603ddd9a99ab03d4a3bfdee5e82007e45", + "width": 353, + "height": 357 + }, + { + "path": "slices/z/262.png", + "bytes": 18333, + "sha256": "c94e316e48442f92630fd0e2d15bd8b08ba8745adde7cc7c11b6583e43030b48", + "width": 356, + "height": 356 + }, + { + "path": "slices/z/263.png", + "bytes": 18775, + "sha256": "9bf2056fa7a9d3f7ad3b66dacdb36fa7a7fcc8a61dddb70bf8cd8c90d1c9148f", + "width": 355, + "height": 355 + }, + { + "path": "slices/z/264.png", + "bytes": 19040, + "sha256": "313e8f901536a1707094ab7bf6f72cd7e7c721718d98e32144f6e7cfaff2b99b", + "width": 354, + "height": 355 + }, + { + "path": "slices/z/265.png", + "bytes": 19114, + "sha256": "8399794efef9ee315099e3e3cb9692995a3c629a892e126b4c491f9bbc3453da", + "width": 354, + "height": 357 + }, + { + "path": "slices/z/266.png", + "bytes": 18978, + "sha256": "d504e68175cfa35fb3760945dbe61e588596682af42f65b7a6a170c728c6a0dc", + "width": 354, + "height": 357 + }, + { + "path": "slices/z/267.png", + "bytes": 19209, + "sha256": "5866fdd94305a1c435999c86a7e6c0d43d21604400ae6d8037d7b853e16121b7", + "width": 354, + "height": 358 + }, + { + "path": "slices/z/268.png", + "bytes": 19390, + "sha256": "a4b4a872ead06a49459ce3fc19cbbe997bfe3a3bd2bf98e3a5f456a0bb58a32f", + "width": 361, + "height": 357 + }, + { + "path": "slices/z/269.png", + "bytes": 19719, + "sha256": "679ef7ca36f62b639292f449ed76a2ea3a8af36584901295bd5b44dcaac7c4c2", + "width": 355, + "height": 355 + }, + { + "path": "slices/z/27.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/270.png", + "bytes": 19810, + "sha256": "b482e5ffdf7ff09496a5ae2c9b9f0587b833a65cb59fd7cba6bba201de75753f", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/271.png", + "bytes": 19977, + "sha256": "272efe886afa35a93be3d9d95e7ce43c748a9347b44500f2aab5e5bb1329e3e0", + "width": 355, + "height": 359 + }, + { + "path": "slices/z/272.png", + "bytes": 20005, + "sha256": "c3f0e3e0e440e54fcb094ca9d7e38e6d0b3ce90dd86c7ffea1e3d2d8f5acad3c", + "width": 359, + "height": 356 + }, + { + "path": "slices/z/273.png", + "bytes": 19912, + "sha256": "02e5047428a2d0fd55295aab94a2d2a63a9b2d8fc62069f0268b1117478a4e68", + "width": 355, + "height": 356 + }, + { + "path": "slices/z/274.png", + "bytes": 20004, + "sha256": "c4cf8b5115217508c41f0ebf00dc692cf2c91f69433ce6d8beca4471ac1d5611", + "width": 355, + "height": 358 + }, + { + "path": "slices/z/275.png", + "bytes": 20028, + "sha256": "87007e8292d4e8dd937a49d67472674f8c3bc733b5bf301e480cd93346241e11", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/276.png", + "bytes": 20061, + "sha256": "54c5d30d13a301b0658431ecd825889cd54b6010eef78d15567bf2acb42b9b5c", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/277.png", + "bytes": 20077, + "sha256": "535b9f9fb58b00b254ae480ec9f51d69906c556a95d06a21f8d19f5b2d86fa0f", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/278.png", + "bytes": 20093, + "sha256": "1057f3cd6c5212ed5dfd68a0edf9c46e97dffc4cfdd2bf01db5c7eb2511bbd5d", + "width": 356, + "height": 356 + }, + { + "path": "slices/z/279.png", + "bytes": 20147, + "sha256": "e8b44aefa243e223752f29a95768410e7759a991a79ed24a54790016ec23f9e2", + "width": 358, + "height": 354 + }, + { + "path": "slices/z/28.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/280.png", + "bytes": 19838, + "sha256": "8b300f9b3771b39a83e49bc8870337dac1235ddd22b1401afd6f326965e77d03", + "width": 356, + "height": 355 + }, + { + "path": "slices/z/281.png", + "bytes": 19992, + "sha256": "3d2ad0680047217376667d2b0709b07cb69d22df76a8295b4cfcd6140a121560", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/282.png", + "bytes": 19922, + "sha256": "4bb638f0d93c415690de74ff21d42d6013620db347cbcc192b4f9b84b41d8726", + "width": 358, + "height": 357 + }, + { + "path": "slices/z/283.png", + "bytes": 19749, + "sha256": "897188e06b9a233778a5fec4f891648e8a58dc4bffa31df45fc374f83c68ee04", + "width": 355, + "height": 355 + }, + { + "path": "slices/z/284.png", + "bytes": 19446, + "sha256": "0b7939161d496e17e9bb25681d9ff03c9a3b40d8c7db91e49597d21b6307b314", + "width": 355, + "height": 356 + }, + { + "path": "slices/z/285.png", + "bytes": 19476, + "sha256": "f33a83210d4eccacf88956c79094b0abdaa7d6c784867243757fdcea4bd2b680", + "width": 357, + "height": 357 + }, + { + "path": "slices/z/286.png", + "bytes": 19555, + "sha256": "bb65e3d8092e9b84598a8f253143a93c97043fb6f3f2e809a69d7a718a1ab73f", + "width": 358, + "height": 354 + }, + { + "path": "slices/z/287.png", + "bytes": 19290, + "sha256": "36cbda4c16704f13647c9d4f7e5cba6f1c0a3389cc811a8373721d873d968a7b", + "width": 357, + "height": 356 + }, + { + "path": "slices/z/288.png", + "bytes": 19417, + "sha256": "2cee86afb39bb041c85307a8421f38a774c16470f2330149cea484894e7c0b50", + "width": 359, + "height": 357 + }, + { + "path": "slices/z/289.png", + "bytes": 19377, + "sha256": "279ca80ae46594cbd61521aa7756d29c47d6ea800d6d52e2d5b126ff16f3c713", + "width": 359, + "height": 354 + }, + { + "path": "slices/z/29.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/290.png", + "bytes": 19286, + "sha256": "3858fee0abb6553112e68f6cd6638e672987443516ca09546324c8c375f5771a", + "width": 358, + "height": 357 + }, + { + "path": "slices/z/291.png", + "bytes": 18833, + "sha256": "1004f8b90032e621ed8c6bf38463580455e50b95b8c915d491c9ed97d30dc6bd", + "width": 359, + "height": 356 + }, + { + "path": "slices/z/292.png", + "bytes": 19016, + "sha256": "b7f496002024a6ceb269281ac39b3d0f1ce3c6f7a620fe5e0e675bf9616726ad", + "width": 359, + "height": 357 + }, + { + "path": "slices/z/293.png", + "bytes": 18536, + "sha256": "54bb1667975abbd6d137720d0ca439dd21e8d47bf9317cf36efde7b442bf636c", + "width": 360, + "height": 357 + }, + { + "path": "slices/z/294.png", + "bytes": 18452, + "sha256": "0fb90d1815dbdec6ab42c5e0cfdc169294775b7b3af3c0f88ec520484c65cb8c", + "width": 360, + "height": 358 + }, + { + "path": "slices/z/295.png", + "bytes": 18435, + "sha256": "32d1d20a7906e1f6cbc116ec939e49eaa1758c7b9cac816c119a292e8b4439f3", + "width": 361, + "height": 356 + }, + { + "path": "slices/z/296.png", + "bytes": 18074, + "sha256": "933e8f1a52ce6537251c4063975450d2e37030a3abfc596b2923b07ae290ec06", + "width": 361, + "height": 356 + }, + { + "path": "slices/z/297.png", + "bytes": 18116, + "sha256": "21a64d1da318b5a156ce9a41427b76998f2914b11a32fd33d0aebf7b7e9e0339", + "width": 362, + "height": 358 + }, + { + "path": "slices/z/298.png", + "bytes": 18091, + "sha256": "3a53415a47f1c0e1e433b570db685c7613489197b35c83ed85e26747be22891c", + "width": 361, + "height": 357 + }, + { + "path": "slices/z/299.png", + "bytes": 18060, + "sha256": "9bb99b759d024689bb909adf763464358fdd4e9cd594640f22764867c3fb4ae4", + "width": 361, + "height": 362 + }, + { + "path": "slices/z/30.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/300.png", + "bytes": 17665, + "sha256": "8c5cd0881e0c9cb211a9595176b1051b50b52a5c060e8cfba3bc5f4be8141ea0", + "width": 356, + "height": 360 + }, + { + "path": "slices/z/301.png", + "bytes": 17561, + "sha256": "639757896d83b31afab53c5e16ac86a95d976844de12ec42bf0ea731eabf5b9b", + "width": 361, + "height": 357 + }, + { + "path": "slices/z/302.png", + "bytes": 17291, + "sha256": "41316fd36e8a889ab564b4df2c9d0ce22af6fef30a8ef41cd48ee79b29328fc2", + "width": 362, + "height": 356 + }, + { + "path": "slices/z/303.png", + "bytes": 17235, + "sha256": "1f8d44c152910f6cc3c8b30b3d1cf36fae350f523e1db49dde7c54f7b35246a8", + "width": 362, + "height": 362 + }, + { + "path": "slices/z/304.png", + "bytes": 17210, + "sha256": "3d8b166dae8e0f98baa19ed60f71d99f1e25ff39692ac4f2845d073c07caef76", + "width": 363, + "height": 370 + }, + { + "path": "slices/z/305.png", + "bytes": 16835, + "sha256": "1fbd0493919fa8fbeaf743c7bb76796843b197c8fde0f83fa66ccfbe6f6de24c", + "width": 357, + "height": 361 + }, + { + "path": "slices/z/306.png", + "bytes": 16839, + "sha256": "4f0414300bce044fd05bc2b6ded65764f9bdb823b817306cadcd7accc94a5399", + "width": 354, + "height": 357 + }, + { + "path": "slices/z/307.png", + "bytes": 16667, + "sha256": "6c5e526b22b785598622a6c2d651352d29fd11344055313c124badd86cdd5477", + "width": 362, + "height": 359 + }, + { + "path": "slices/z/308.png", + "bytes": 16331, + "sha256": "06b51b82a40da983a8d53adca9cc356f3fb06aa53b06c8c80fdba9c715c40a60", + "width": 354, + "height": 364 + }, + { + "path": "slices/z/309.png", + "bytes": 16146, + "sha256": "dcc4de85a7f1a04984dc7b251838574648e8dd2f8313f0cbed0beb8dba006205", + "width": 361, + "height": 365 + }, + { + "path": "slices/z/31.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/310.png", + "bytes": 15976, + "sha256": "00e8cdb00eb5b51b83aa40b3f7524099eb237f48bb5d87c0ad4c9258358d085b", + "width": 355, + "height": 366 + }, + { + "path": "slices/z/311.png", + "bytes": 15866, + "sha256": "b4ca6dc4a67ae99cfa9d999c6a02ffebd54f77d2303056f5ef5552006900337a", + "width": 355, + "height": 369 + }, + { + "path": "slices/z/312.png", + "bytes": 15530, + "sha256": "b7fe23e5b140a008b02b6a5c2307c83836ade416b80022d053f7944da0b5363c", + "width": 356, + "height": 361 + }, + { + "path": "slices/z/313.png", + "bytes": 15307, + "sha256": "19e15bbb1b3108b79644cb1eb91f4d16b3f9b9d6e6ce6330a60ada8baa9ad76c", + "width": 353, + "height": 371 + }, + { + "path": "slices/z/314.png", + "bytes": 14635, + "sha256": "2756c97b38d3abfc169366b8812ccc8c683014bc08586bf157c9d25ef8e31736", + "width": 354, + "height": 367 + }, + { + "path": "slices/z/315.png", + "bytes": 14538, + "sha256": "2352e5c35300c2aa04775d489eecc9788194119578a4f43bff3f2c1d381f8b66", + "width": 352, + "height": 371 + }, + { + "path": "slices/z/316.png", + "bytes": 14327, + "sha256": "dac33eb8008ab9b855b12c056b8aae89473a9cab27ccbf99f9d87ed675c7b909", + "width": 356, + "height": 372 + }, + { + "path": "slices/z/317.png", + "bytes": 14031, + "sha256": "89cfac42786607117685160d6f467ab94a5ffdd1e22532f724b1c3bd002e9fe3", + "width": 357, + "height": 367 + }, + { + "path": "slices/z/318.png", + "bytes": 13533, + "sha256": "4eafb1344020cac0c96f0b35d594202b55c924da56304d7e18f7176f8ffdf2e7", + "width": 357, + "height": 363 + }, + { + "path": "slices/z/319.png", + "bytes": 13456, + "sha256": "c67d802a6efd67c975f3d00e92a14cd409fc9d62a3b6814919a2a51c9f159eb0", + "width": 356, + "height": 371 + }, + { + "path": "slices/z/32.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/320.png", + "bytes": 13060, + "sha256": "1a68e9441dbed665c6d4b8d3eb0bc8043dd7befaaf42153e45b32d19b4c06306", + "width": 351, + "height": 369 + }, + { + "path": "slices/z/321.png", + "bytes": 12599, + "sha256": "859568c9f32be4a41f09964f3d298bbf60dec57f19eaa54cad2ea8dbda930365", + "width": 355, + "height": 365 + }, + { + "path": "slices/z/322.png", + "bytes": 12461, + "sha256": "4fd4ae6b1899b7fba773ac8a68e9944aed52a74ee235eba66ea92b0146d6f046", + "width": 352, + "height": 368 + }, + { + "path": "slices/z/323.png", + "bytes": 12159, + "sha256": "f46a0b57fe88670422dad305fea594185462bb93f808036bd20550e7188c84d5", + "width": 356, + "height": 369 + }, + { + "path": "slices/z/324.png", + "bytes": 11845, + "sha256": "29c0c69a1b07954b181da3399f649fc350c16ed748782034b0005a9f3a56d393", + "width": 356, + "height": 373 + }, + { + "path": "slices/z/325.png", + "bytes": 11820, + "sha256": "22c767993e8b76fa851e63cdd2dd087d70c5ee2f95dd9793f8aa6b83437b4eb5", + "width": 356, + "height": 364 + }, + { + "path": "slices/z/326.png", + "bytes": 11226, + "sha256": "21d730a277e7d280e1be482d55e0e5657d3add7ffe52705f2b8628d27be330b9", + "width": 353, + "height": 363 + }, + { + "path": "slices/z/327.png", + "bytes": 11281, + "sha256": "6891d54b3373911da217c7bfb86adb4be2c0004b9577e8e3a4a94870c2d93f4d", + "width": 355, + "height": 368 + }, + { + "path": "slices/z/328.png", + "bytes": 11053, + "sha256": "2af5ea5d9c9014ea4d2fc1e9d49df362b4b9c529d1bf3d38b6a1492146a61402", + "width": 354, + "height": 367 + }, + { + "path": "slices/z/329.png", + "bytes": 10779, + "sha256": "5fb19ffda837a968a7c51d6b097cc3246d33ef637b2d15fd3c788014cd7e510b", + "width": 356, + "height": 361 + }, + { + "path": "slices/z/33.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/330.png", + "bytes": 10540, + "sha256": "3acaf90a00d4210ed0348ba7b190d22cf92b6a9405fb6d1960afe1939a634fea", + "width": 352, + "height": 366 + }, + { + "path": "slices/z/331.png", + "bytes": 10266, + "sha256": "a36b2fb153e35c4d0e9e41a8ed210bff853c187e85139aefd6a6d70c9a432860", + "width": 354, + "height": 360 + }, + { + "path": "slices/z/332.png", + "bytes": 10027, + "sha256": "9146687c64a7082c0d1c5d3337888e05512671d8f466cd6e07d3b1e7b51d2e0c", + "width": 356, + "height": 362 + }, + { + "path": "slices/z/333.png", + "bytes": 9594, + "sha256": "1d3cb85ec8e0c3664039d1cbde4a854331daf6647e108645f92da8846f1ba155", + "width": 350, + "height": 357 + }, + { + "path": "slices/z/334.png", + "bytes": 9339, + "sha256": "6f72f104f8c0a0791a4c62f179acda94dcada15a4e558f77c58517509881dd61", + "width": 353, + "height": 359 + }, + { + "path": "slices/z/335.png", + "bytes": 9280, + "sha256": "40444d97da426955abcb70faf6a4b64201d9b13bafb18d5156f8cfceb66e6b04", + "width": 353, + "height": 362 + }, + { + "path": "slices/z/336.png", + "bytes": 8758, + "sha256": "8015acb25fc4a64e3e1ae8eebff78a8c0fe5432810c1a65333ed693df23594cf", + "width": 351, + "height": 357 + }, + { + "path": "slices/z/337.png", + "bytes": 8498, + "sha256": "11ec7bf6cdf73dd060fe715278de40b20ed2141dec9d52a7b91dd4280a5b0eaf", + "width": 355, + "height": 358 + }, + { + "path": "slices/z/338.png", + "bytes": 8454, + "sha256": "c896262cb0800d40a7b381faacb7175f45f44dffb82cdd5b2e60ce31df7d17d2", + "width": 354, + "height": 359 + }, + { + "path": "slices/z/339.png", + "bytes": 8205, + "sha256": "04fb4f36ecfb1efa6cf2dd7a7c8262ebc0566b1be6b8f630987992989de8a59b", + "width": 356, + "height": 357 + }, + { + "path": "slices/z/34.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/340.png", + "bytes": 7902, + "sha256": "f916182e7e791864f63a84d8d3979d4fe3849c96eb5feb935f2059a82a562df7", + "width": 351, + "height": 363 + }, + { + "path": "slices/z/341.png", + "bytes": 7589, + "sha256": "0b1d6a7d3324ed2ba3a301d964eafeb11b58ab392d2aea8d128a7931f6aab6c5", + "width": 354, + "height": 358 + }, + { + "path": "slices/z/342.png", + "bytes": 7408, + "sha256": "89bd3570179bdec1c7347115f89d304a5af2aae32b7e98de5f050d975a125b98", + "width": 355, + "height": 360 + }, + { + "path": "slices/z/343.png", + "bytes": 6893, + "sha256": "f604d546244c7b78eb247864e9defb583f22e427173b5fdb3304bbb5fbdf16e2", + "width": 355, + "height": 358 + }, + { + "path": "slices/z/344.png", + "bytes": 6720, + "sha256": "9bf5dc50e89b6af28df88c0150bf64fb6131ba83223878ec79240e91f0730e63", + "width": 352, + "height": 358 + }, + { + "path": "slices/z/345.png", + "bytes": 6475, + "sha256": "c62e360736044461e630cf008af6bd8aa0b1cd6245c6ed501641c971e03049c4", + "width": 353, + "height": 359 + }, + { + "path": "slices/z/346.png", + "bytes": 6124, + "sha256": "ac49f337b1e043debfcc61d4e7f699f75f7ceeb76f956caeb2d522178aa95f84", + "width": 354, + "height": 359 + }, + { + "path": "slices/z/347.png", + "bytes": 6121, + "sha256": "b03732db4fc76c797cac2afc1f1ea6c4d05f0000dc855874b9a58c289d2fd5d1", + "width": 353, + "height": 353 + }, + { + "path": "slices/z/348.png", + "bytes": 6106, + "sha256": "357a100cb756b6bbfb832033e7d77e2d93c6bb2025c4045bd750c096b4ec941e", + "width": 354, + "height": 358 + }, + { + "path": "slices/z/349.png", + "bytes": 5646, + "sha256": "aa0d3f6b23e8fda03c29c20289d9e5c9bff9f248bfc28736b5a8a76a9fff824d", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/35.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/350.png", + "bytes": 5521, + "sha256": "d65650d982c538244ad50b9f158ac6470f4b88954319a23f00381a6dd20845c5", + "width": 349, + "height": 355 + }, + { + "path": "slices/z/351.png", + "bytes": 5376, + "sha256": "acff46cf07ac1d777d396917eeb8222a63c878d33926cf904808b7f0c34aadeb", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/352.png", + "bytes": 5080, + "sha256": "2bd854df48f8a0ec3dff9f907c8c92844f7ab7b16c6e2ca3e888ee8c9eafe1b9", + "width": 353, + "height": 355 + }, + { + "path": "slices/z/353.png", + "bytes": 4989, + "sha256": "bde8705861ad6642c708485935e49b534780878ed50653cdc2ffe6c9181ecf25", + "width": 355, + "height": 355 + }, + { + "path": "slices/z/354.png", + "bytes": 4939, + "sha256": "2ec93325d95b59adbdc20177950a5c989c80e2a4d22ce88d4e86a29ff0c8aebb", + "width": 352, + "height": 356 + }, + { + "path": "slices/z/355.png", + "bytes": 4830, + "sha256": "da1b04027c82def26fd1db1ddd9bfcd617eb0f887de0f0d306d3c2ab9cd95b84", + "width": 352, + "height": 359 + }, + { + "path": "slices/z/356.png", + "bytes": 4895, + "sha256": "38baa03b833fbc0c90b128fcb7d69d0a696a17761ed1bb36d56f3e4994a25a9f", + "width": 351, + "height": 355 + }, + { + "path": "slices/z/357.png", + "bytes": 4919, + "sha256": "f76ae4bdfb8f8afd8caa63cc17e194ce6f6d6fbe8c811da7b51efe28eabc0786", + "width": 355, + "height": 357 + }, + { + "path": "slices/z/358.png", + "bytes": 4618, + "sha256": "692a55fdfcbae0581e4112f3624e3a13b6ad2d8c4612dca1490adf57cb54f170", + "width": 353, + "height": 357 + }, + { + "path": "slices/z/359.png", + "bytes": 4385, + "sha256": "eb19f418a04fdfe00482b89311eb3fc4424a574b6d2ba9d411d24ca4eecf9b17", + "width": 355, + "height": 359 + }, + { + "path": "slices/z/36.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/360.png", + "bytes": 4356, + "sha256": "78dec019eca304b76585c1d9bc88f5c4a62099f860c592544bcd5ffcd5cda0e6", + "width": 352, + "height": 361 + }, + { + "path": "slices/z/361.png", + "bytes": 1009, + "sha256": "e437aa694faca8532d6cd2ac734f9cd2980e33c558a5f1ae0c2585432a4c49c3", + "width": 325, + "height": 352 + }, + { + "path": "slices/z/362.png", + "bytes": 877, + "sha256": "4e80f55c4aafd9d8f8c26625b41926b7fec710e7ba4cc1506630efe03d136c84", + "width": 308, + "height": 353 + }, + { + "path": "slices/z/363.png", + "bytes": 801, + "sha256": "f13025ac61b705bd963cdf74a93721b884597fd7c78fc701517f429be38ce7c0", + "width": 259, + "height": 349 + }, + { + "path": "slices/z/364.png", + "bytes": 778, + "sha256": "245110c0e6a3be5aba4604f3392ae409c5768049d93843ea8feb926d7bea30aa", + "width": 261, + "height": 352 + }, + { + "path": "slices/z/365.png", + "bytes": 869, + "sha256": "ac4334f3691f2862e7827732a7e35799ab88a6a3cf3c22ee6aaee3d1525b6cbc", + "width": 309, + "height": 353 + }, + { + "path": "slices/z/366.png", + "bytes": 862, + "sha256": "5747a1fe5925f8e70e5f36823173851f3a535afe075ef7c5634a01d89e41bf55", + "width": 342, + "height": 352 + }, + { + "path": "slices/z/367.png", + "bytes": 781, + "sha256": "a5cd3a98f60a4da7bde5e5597a41e545a152a3fd293ed0f2846cb563a0af2c24", + "width": 319, + "height": 329 + }, + { + "path": "slices/z/368.png", + "bytes": 739, + "sha256": "652cecc349fa976f3d4a0d1e9ebafe2c5661a8b3f0093ec53d22593b3a1f5e95", + "width": 318, + "height": 341 + }, + { + "path": "slices/z/369.png", + "bytes": 719, + "sha256": "257f6cd9b69516a62300cb8b253d4491176051c286846521347c0d96932d4ca1", + "width": 309, + "height": 342 + }, + { + "path": "slices/z/37.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/370.png", + "bytes": 619, + "sha256": "79f111a168622f7e614bd06b57287e5a2cda3362487920f461cc7f4c5dc79162", + "width": 263, + "height": 342 + }, + { + "path": "slices/z/371.png", + "bytes": 660, + "sha256": "6efda159a0fcc8fc534d2fcfbed5cfb85b89c16574a0cb02ab9eb3827aa756af", + "width": 306, + "height": 304 + }, + { + "path": "slices/z/372.png", + "bytes": 801, + "sha256": "0b3ba4eedad17a2302b2ec5db280a0c58eb0c62e1cd7869bab2560c15354ea1c", + "width": 303, + "height": 347 + }, + { + "path": "slices/z/373.png", + "bytes": 857, + "sha256": "e92d301661ad68b968a62c68af2c1112e4ce7a8a0c66485800662c96dc93a06a", + "width": 298, + "height": 359 + }, + { + "path": "slices/z/374.png", + "bytes": 854, + "sha256": "ff07c172f110ba9ed93d86cc9fab7207c3b7cefdec06145e5ffc604d56a271a7", + "width": 298, + "height": 359 + }, + { + "path": "slices/z/375.png", + "bytes": 684, + "sha256": "5436634cdd95b2c6d006773e92dca180e046ecff38512f60523f2a43109608a9", + "width": 270, + "height": 354 + }, + { + "path": "slices/z/376.png", + "bytes": 434, + "sha256": "30f96886674c3049dc958db8fb9d607b9ebab149f645164158cf1fe4aabaf153", + "width": 189, + "height": 285 + }, + { + "path": "slices/z/377.png", + "bytes": 621, + "sha256": "3b3044a24f30f5a835073d2e1f530d73e958d309d4b4bf87329b55fa8d238f82", + "width": 324, + "height": 305 + }, + { + "path": "slices/z/378.png", + "bytes": 637, + "sha256": "b38154e089e323b2c949a73f54ebce6bd4a61028584598ccd5b57c97fd5d70d0", + "width": 305, + "height": 352 + }, + { + "path": "slices/z/379.png", + "bytes": 635, + "sha256": "32ddc6664267ee3a027a377c5e0d35085c05e646e6002f5c62eb9a2c318b9d89", + "width": 325, + "height": 361 + }, + { + "path": "slices/z/38.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/380.png", + "bytes": 201, + "sha256": "2b205c6714705365febe5195fa4d921866eb50c7ec12b5a0a0c6d5de134d79fc", + "width": 122, + "height": 69 + }, + { + "path": "slices/z/381.png", + "bytes": 560, + "sha256": "b3d747fd8ff45c2dafa7bfb3f75023bd761db074e89e79e4c9cae559a493cb99", + "width": 331, + "height": 263 + }, + { + "path": "slices/z/382.png", + "bytes": 615, + "sha256": "c36f333247d689ff40edc28f1e3cf6ac4c360cd7d658e22ba833bf4b4a384bf5", + "width": 298, + "height": 325 + }, + { + "path": "slices/z/383.png", + "bytes": 237, + "sha256": "0c127d6a9b69db55920d017f42d4f6a07bec636cbfcaf355dc5b811d9d701cc4", + "width": 283, + "height": 71 + }, + { + "path": "slices/z/384.png", + "bytes": 585, + "sha256": "66bf89ca96029955479a61803243e81f91fdaeff9719e8b90207c417987c4cb3", + "width": 319, + "height": 330 + }, + { + "path": "slices/z/385.png", + "bytes": 534, + "sha256": "13f32c4116385ba41e736cd6376d092d82527212366b2c643a05b83ece8c19ec", + "width": 350, + "height": 250 + }, + { + "path": "slices/z/386.png", + "bytes": 555, + "sha256": "e63097ccaa4f28a7b653edf1da98b81978a64d7b60501f694d15e89131c59f71", + "width": 291, + "height": 334 + }, + { + "path": "slices/z/387.png", + "bytes": 473, + "sha256": "723ca3f871fe62fce01ef1b0f042f7e29f432e6fab627d90d26ec7eb3b1e5a74", + "width": 199, + "height": 347 + }, + { + "path": "slices/z/388.png", + "bytes": 351, + "sha256": "3641b1e2542cfa11957c3af52122641da38db4fe1e7a1f126f9373db2f5ed850", + "width": 201, + "height": 240 + }, + { + "path": "slices/z/389.png", + "bytes": 391, + "sha256": "15aa1366a480f43a7aae2523fdbbe293183cdae301df954f37579e0d7bca940d", + "width": 269, + "height": 220 + }, + { + "path": "slices/z/39.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/390.png", + "bytes": 565, + "sha256": "6fc26d41145d912f074c841a0dc53ab6d33af6af104c2e6ba31991c51d06a60b", + "width": 272, + "height": 325 + }, + { + "path": "slices/z/391.png", + "bytes": 524, + "sha256": "35e7600adf69c51afd56aa3b868128c54c42a0129cf36305d76f441d8964ad88", + "width": 252, + "height": 325 + }, + { + "path": "slices/z/392.png", + "bytes": 310, + "sha256": "2510d83b7bbb71ebd3326f4dca08b7a479307e809d6ad122b6d459088f4d0b82", + "width": 99, + "height": 303 + }, + { + "path": "slices/z/393.png", + "bytes": 583, + "sha256": "1aa97b936b676181a6178a8a2a09b2e8592538ca141c747c014d0572e1062222", + "width": 259, + "height": 328 + }, + { + "path": "slices/z/394.png", + "bytes": 599, + "sha256": "abd8ee6b683c9b3047ad799fd342f8c33bc18ed987e9bd9851e98a4670b3ee6f", + "width": 263, + "height": 328 + }, + { + "path": "slices/z/395.png", + "bytes": 597, + "sha256": "8e0cf513da60ec21834c275ca97594d1979b16616696d957915228a4b22df6f6", + "width": 341, + "height": 275 + }, + { + "path": "slices/z/396.png", + "bytes": 716, + "sha256": "2f91e5daabc26ea0b5bacd18c9691421dcc91cb271a73b1d2abcb049bb6a6997", + "width": 344, + "height": 337 + }, + { + "path": "slices/z/397.png", + "bytes": 606, + "sha256": "3528e55785d866f8d44e46f56b8d947844318b86288593417bac900625bd1ecf", + "width": 296, + "height": 327 + }, + { + "path": "slices/z/398.png", + "bytes": 712, + "sha256": "b490deef802e0ab5f6c66efba0808e98a9f1b202a419cf849a75ed6531f37059", + "width": 342, + "height": 313 + }, + { + "path": "slices/z/399.png", + "bytes": 727, + "sha256": "fd19c11daee30c69ad2591096e09f139abbcd0859d64b810e4da1c8eda06df2c", + "width": 349, + "height": 324 + }, + { + "path": "slices/z/40.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/400.png", + "bytes": 802, + "sha256": "ea4b83a46895a34dd78b1bc6dfaf32f2ba2902395be2901bbbfca1291b9dd7c8", + "width": 355, + "height": 333 + }, + { + "path": "slices/z/401.png", + "bytes": 821, + "sha256": "3a5c2f5c61fb2a4cfb3d5afba2cd2204e6a4f9b078ec9969760bb9f184f2c41a", + "width": 318, + "height": 331 + }, + { + "path": "slices/z/402.png", + "bytes": 745, + "sha256": "7c3164fae76b5baf5569e96e458944feb16b340e4d40e4f909bb36f308650cc2", + "width": 317, + "height": 267 + }, + { + "path": "slices/z/403.png", + "bytes": 434, + "sha256": "7a48c5921047d78a5251c525656f1a5d006636f02fb5d1b3498b3c9a97e53447", + "width": 71, + "height": 273 + }, + { + "path": "slices/z/404.png", + "bytes": 442, + "sha256": "fe7bb1bb0558bd75deee6ce4c04eea4c2fe74527fb02558747d6bf21a3e09bfc", + "width": 351, + "height": 72 + }, + { + "path": "slices/z/405.png", + "bytes": 422, + "sha256": "1c56b65e59ce064466a9bbb6d1ceb09bb5da634a81181cc7fe1112ad30d306c6", + "width": 350, + "height": 70 + }, + { + "path": "slices/z/406.png", + "bytes": 273, + "sha256": "305b484118216d6cc880f83d99b3568ebdeb3f15ca555f8461c29c58a7bab9c1", + "width": 57, + "height": 56 + }, + { + "path": "slices/z/407.png", + "bytes": 564, + "sha256": "72dd516c98e6fa637425cfaf4527bba1cdb0c57bd56c68714496645cedaae072", + "width": 220, + "height": 343 + }, + { + "path": "slices/z/408.png", + "bytes": 587, + "sha256": "343d218bbc5f829d894f9ee8123784c2bbd40c95b54fb7bfd1926566086e985f", + "width": 222, + "height": 344 + }, + { + "path": "slices/z/409.png", + "bytes": 768, + "sha256": "64baa41b0b669bc3a79ccc96193f5cf2db7472ffea5ef12471ffc570d293b830", + "width": 348, + "height": 339 + }, + { + "path": "slices/z/41.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/410.png", + "bytes": 729, + "sha256": "6d360bb9a3ae8eed0014df27e96f9d7e435dfc1dd99351b136fb0cc4fada5b44", + "width": 359, + "height": 293 + }, + { + "path": "slices/z/411.png", + "bytes": 452, + "sha256": "5fdae19b8b18dfc8cf57fc55c5dad887f092567e3d80b90eb8116fb752e46629", + "width": 166, + "height": 318 + }, + { + "path": "slices/z/412.png", + "bytes": 458, + "sha256": "ce7160d6a1751be89b53129e5deefee5cad42b9473478825f556a3d257357d63", + "width": 161, + "height": 318 + }, + { + "path": "slices/z/413.png", + "bytes": 638, + "sha256": "dac963ae37498e894c2efd79136e4c2e62b4c5e3141d959c6d8d441989b45f12", + "width": 302, + "height": 319 + }, + { + "path": "slices/z/414.png", + "bytes": 418, + "sha256": "ac47cabc7976d7c255705e87a8af5033d4efd2dfecdcd0d34c91479ac9a6f267", + "width": 307, + "height": 138 + }, + { + "path": "slices/z/415.png", + "bytes": 355, + "sha256": "8c5f44eee52a340ed7ac166e48976f6b980df9d35e92b3e2f36bfc84564f1f0a", + "width": 299, + "height": 129 + }, + { + "path": "slices/z/416.png", + "bytes": 340, + "sha256": "99334251add6cca0120103ba4cd5ce0e5d29ad5c44d0f932e9cbed8ee2e97ec3", + "width": 296, + "height": 128 + }, + { + "path": "slices/z/417.png", + "bytes": 239, + "sha256": "e2c0db02f616845e68da68f459dac028eb0a7de03f6fcbfcf387419a17ee8d85", + "width": 54, + "height": 258 + }, + { + "path": "slices/z/418.png", + "bytes": 216, + "sha256": "a3fa846ab4936b0e0629e2dc6af6ec33dbc7ec56ccf88c3d5d74d3c4c0a66558", + "width": 61, + "height": 255 + }, + { + "path": "slices/z/419.png", + "bytes": 176, + "sha256": "5f6553846730873af39d32add8a0570e138b3b7075eb83a8e6bd42ade039e35f", + "width": 40, + "height": 258 + }, + { + "path": "slices/z/42.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/420.png", + "bytes": 499, + "sha256": "1e9a277d1d4363c3df717b591e666c32d96662063fb93897b47cf9cdb42ddd3f", + "width": 305, + "height": 289 + }, + { + "path": "slices/z/421.png", + "bytes": 510, + "sha256": "6f97e4af0a4c7cfea5ac17199287e14a792b55f537b86fcaa41710dc0cfb75d1", + "width": 344, + "height": 275 + }, + { + "path": "slices/z/422.png", + "bytes": 164, + "sha256": "a4fd0616f49f70ed6347f99e2949944bf063d4c4fe9b5c7eedc679fad3c884aa", + "width": 345, + "height": 19 + }, + { + "path": "slices/z/423.png", + "bytes": 169, + "sha256": "cbdeef4d8a8ef13730f9b6527a7ff61ad686c6fd04561afbe73ba2abfc8e1e21", + "width": 341, + "height": 37 + }, + { + "path": "slices/z/424.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/425.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/426.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/427.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/428.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/429.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/43.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/430.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/431.png", + "bytes": 205, + "sha256": "0c19134612efad0243730e05fa54aa399a8e1284cbf5bff1e3caba308a81bf63", + "width": 86, + "height": 267 + }, + { + "path": "slices/z/432.png", + "bytes": 115, + "sha256": "f50f2d57af3c1825f87db3d2331145e6f6e3baf7dda396a475f80e4711ff85ce", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/433.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/434.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/435.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/436.png", + "bytes": 177, + "sha256": "e03545c8b4eb9f7d1c73437e56e54848f9c5b410a3b1e41ae507f2bfe5258e1a", + "width": 34, + "height": 297 + }, + { + "path": "slices/z/437.png", + "bytes": 173, + "sha256": "6321be2d926bf099d3048820625f1a91e8a61d30c54f25c6b53710b5d7f1afe2", + "width": 34, + "height": 297 + }, + { + "path": "slices/z/438.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/439.png", + "bytes": 151, + "sha256": "827217482addbe932449162ce8aabbe428e7b00566243a000fe31a2c3e95132d", + "width": 12, + "height": 149 + }, + { + "path": "slices/z/44.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/440.png", + "bytes": 303, + "sha256": "aebd76f129adbb7f8a71b81bb3a2cfa9fc101647a5dc718eed8358248e67f9fa", + "width": 221, + "height": 149 + }, + { + "path": "slices/z/441.png", + "bytes": 105, + "sha256": "3173867bf7b96080a2e0fd66169cabbb6f6547b543f7f8e584cccb5e2594b0cb", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/442.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/443.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/444.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/445.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/446.png", + "bytes": 102, + "sha256": "8e9220445da173706f4fc17a2bfdb0ee6e626fc61e42f1ce63c89916e4fbf442", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/447.png", + "bytes": 163, + "sha256": "173e305c29a0e92115a110b1bc02b0e9299cfc1e3a2216009959b2b5f153dfad", + "width": 8, + "height": 104 + }, + { + "path": "slices/z/448.png", + "bytes": 159, + "sha256": "28fc5c8a7585162f0adca92d7f11473c3235efa5fedfd10e32d84c3de379e907", + "width": 9, + "height": 103 + }, + { + "path": "slices/z/449.png", + "bytes": 98, + "sha256": "e801f04c3298f3f05553ad3b1430583e3eb43dcb8469791b0e3289c7d6a337b1", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/45.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/450.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/451.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/452.png", + "bytes": 112, + "sha256": "45230de7933083ed4b5ebd9ca32e0afc85888f324f4725a96645782f65642392", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/453.png", + "bytes": 111, + "sha256": "3e3143587425a2a380d3fbea5449d8b28f485e38d27e24d4c1fc0dec8b35ab8a", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/454.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/455.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/456.png", + "bytes": 114, + "sha256": "c8c0bed928d0d391806a39d40030121351fa168bf16d32b0e05667bb9a1cbd6d", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/457.png", + "bytes": 115, + "sha256": "95cd798117f3b348b42f5163c662e9139d33f580c8b3bd33376f0d263ed9459f", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/458.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/459.png", + "bytes": 115, + "sha256": "d9f1e38a738f52d98620fe7959b90aecbc7f79ee9dd067331b00e60259c068af", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/46.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/460.png", + "bytes": 100, + "sha256": "33596d96b5721dfb9d589fa496816dfaf073180da3c8663358a472d9de088f16", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/461.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/462.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/463.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/464.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/465.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/466.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/467.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/468.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/469.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/47.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/470.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/471.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/472.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/473.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/474.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/475.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/476.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/477.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/478.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/479.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/48.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/480.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/481.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/482.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/483.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/484.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/485.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/486.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/487.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/488.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/489.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/49.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/490.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/491.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/492.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/493.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/494.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/495.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/496.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/497.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/498.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/499.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/50.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/500.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/501.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/502.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/503.png", + "bytes": 139, + "sha256": "ea71eb64c182c6329b90a02b4519692d14f648810cbefcaa65d5a6a4f8274e19", + "width": 4, + "height": 64 + }, + { + "path": "slices/z/504.png", + "bytes": 162, + "sha256": "d310175759e9f67d3c8fcf0eb7e1347f3829777ea983bb090a5d5a1476c4bd0a", + "width": 5, + "height": 66 + }, + { + "path": "slices/z/505.png", + "bytes": 113, + "sha256": "441880487190520a0bd5a63cf1108a3d7a16f0e099c603e69de1cb1b8b6104ca", + "width": 3, + "height": 65 + }, + { + "path": "slices/z/506.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/507.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/508.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/509.png", + "bytes": 96, + "sha256": "19a19897b7e175583ec6dcbec149ec7ceeb17ba5cb5767c6f091f3b551848f7e", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/51.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/510.png", + "bytes": 103, + "sha256": "c1c07a41a13a31129d8b0665b71273e8dd4cf47cf88532ea56cc219f27794880", + "width": 3, + "height": 2 + }, + { + "path": "slices/z/511.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/52.png", + "bytes": 101, + "sha256": "f01deff89203818da5d4f56c65f6bd0a1d6f191a907a98dcee7a109f6029055d", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/53.png", + "bytes": 115, + "sha256": "f438cd2effa5a6992c265ef9bfda20ba817c3a9dcfe1c9de87a61c21a9a642d3", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/54.png", + "bytes": 101, + "sha256": "ca4606ef4c2569bf678950bfe6af53c2cc3cbc6b4cc7b434dcd22992ac34384a", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/55.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/56.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/57.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/58.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/59.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/60.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/61.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/62.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/63.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/64.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/65.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/66.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/67.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/68.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/69.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/70.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/71.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/72.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/73.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/74.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/75.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/76.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/77.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/78.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/79.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/80.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/81.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/82.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/83.png", + "bytes": 97, + "sha256": "2728f1721236afd351fdae5b478cf1bab3554070c56efa8f465251bef06eb56a", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/84.png", + "bytes": 169, + "sha256": "4c11a71143675862369a77aaa735d0d00dca7b3a3fd45ed6562fae7c026c4a5d", + "width": 5, + "height": 191 + }, + { + "path": "slices/z/85.png", + "bytes": 274, + "sha256": "fcc2c9f45bb2f4cf5c27f8a2aee7b5b876bbf5124970470904c441757f926eee", + "width": 89, + "height": 235 + }, + { + "path": "slices/z/86.png", + "bytes": 213, + "sha256": "992a9178d41b3ccf02a96890dec5152bd961504e24bb1ff47e700a66b9a66d99", + "width": 87, + "height": 233 + }, + { + "path": "slices/z/87.png", + "bytes": 93, + "sha256": "4efaabedc32b5564a7e8041df3cd0b50e0be86676a39f6629926ffd3f703fca9", + "width": 2, + "height": 1 + }, + { + "path": "slices/z/88.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/89.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/90.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/91.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/92.png", + "bytes": 101, + "sha256": "f01deff89203818da5d4f56c65f6bd0a1d6f191a907a98dcee7a109f6029055d", + "width": 2, + "height": 2 + }, + { + "path": "slices/z/93.png", + "bytes": 115, + "sha256": "5885a1303cadee146f12e6cdf9b3459ee4ee1da6a5fe6e1a56d00c0e2d39bf1a", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/94.png", + "bytes": 91, + "sha256": "defd343952dae18492be8e941378a82925f1f4e67b94c98e5980f39d4a759f3a", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/95.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/96.png", + "bytes": 106, + "sha256": "857f80ecce90bcb40c6e9f8df4d32c21c41fe4588c1548b7a3eb3d21358fa102", + "width": 3, + "height": 2 + }, + { + "path": "slices/z/97.png", + "bytes": 114, + "sha256": "8d5bea921fad53b8b64d8e9ab863eb809a30f435b6454cdce008b22741cf2f4d", + "width": 3, + "height": 3 + }, + { + "path": "slices/z/98.png", + "bytes": 91, + "sha256": "2fe8e6c2a228cc8932b1a02ef77d563dddc0618eb038ea3ea29338b35f37fdc6", + "width": 1, + "height": 1 + }, + { + "path": "slices/z/99.png", + "bytes": 104, + "sha256": "f0479c17280bc1eab93dbc0869bba7d1e2768c6b50d3426980c08c71b002950a", + "width": 2, + "height": 2 + } + ], + "reusedHandoff": "round2-neutral/handoffs.json", + "verdict": "The unchanged neutral bytes and geometry retain the measured failed handoff verdict. This comparison is not visual acceptance." +} \ No newline at end of file diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/captures.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/captures.json new file mode 100644 index 0000000000..135bb37708 --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/captures.json @@ -0,0 +1,96 @@ +{ + "capturedAt": "2026-09-20T20:13:54.133Z", + "browser": "148.0.7778.96", + "platform": "darwin", + "viewport": { + "width": 1100, + "height": 820 + }, + "deviceScaleFactor": 1, + "url": "http://127.0.0.1:4339/@fs/private/tmp/cssearth-pr390/output/pr390-audit/layer-optimization/omega-preview.html", + "resultId": "7a4f8781a7d19fafa57f11e65eae6ee24975082d3fcae0c1644cbdd68a5ac549", + "logicalLayers": 459, + "domLeaves": 1377, + "stars": 0, + "source": "ESO/INAF-VST/OmegaCAM eso1119b photographic color on modeled integrated-starlight geometry", + "meaning": "Actual retained-DOM compiler viewer in a local inspection wrapper. This is not the main application or a promoted Lab delivery. Captures illustrate four camera poses, not matched before/after comparisons. No Pixelmatch comparison is claimed.", + "sideYLimit": "The interactive pitch clamp is 89 degrees, so this is a near-side view.", + "ignoredInputPins": [ + { + "path": "output/pr390-audit/layer-optimization/omega-preview.html", + "bytes": 1907, + "sha256": "867d1a6e11ceffc7f3dcb0f75e68ac92913fd03e839b8be71c05c49f134c9432" + }, + { + "path": "output/pr390-audit/layer-optimization/omega-preview.ts", + "bytes": 3699, + "sha256": "09ea277a99d21ae375a9ff9dacce952146e05a6eb8b6171eeead08efb6c9429d" + }, + { + "path": "output/pr390-audit/layer-optimization/omega-7a4f8781a7d19fafa57f11e65eae6ee24975082d3fcae0c1644cbdd68a5ac549/scene.json", + "bytes": 17276, + "sha256": "250bccd18011bd0fafd5b5d17c756b393b17f886206ad1383b3fb47aab492fc8" + }, + { + "path": ".local/nebula-lab/compiler/5d934218dcc59475e632d503bea59dfeb3bb156431d8d88d3616830808b23df9/field.json", + "bytes": 4970176, + "sha256": "2f688583e71134410d5362c10068a7e51dc90db03b284592bdd28207f8a9bc94" + } + ], + "captures": [ + { + "file": "front.png", + "bytes": 210440, + "sha256": "8aced76277035d66135f7b6afc130a8fc72613ed67b0ef1e712889b777684c6f", + "yawDegrees": 0, + "pitchDegrees": 0, + "framing": { + "zoom": 1, + "panX": 0, + "panY": 0 + }, + "lens": "eso1119b" + }, + { + "file": "oblique.png", + "bytes": 213943, + "sha256": "4d57deb3c2b8baded9b54703fc69895842bf5b4f77cd31573d793fe2c03bbffd", + "yawDegrees": 35, + "pitchDegrees": 25, + "framing": { + "zoom": 1, + "panX": 0, + "panY": 0 + }, + "lens": "eso1119b" + }, + { + "file": "side-x.png", + "bytes": 210233, + "sha256": "f31ffa91c300ef717eaeefc3fc208f953a4ca0ffdcf15efe3ea9be77149ebfef", + "yawDegrees": 90, + "pitchDegrees": 0, + "framing": { + "zoom": 1, + "panX": 0, + "panY": 0 + }, + "lens": "eso1119b" + }, + { + "file": "side-y.png", + "bytes": 214418, + "sha256": "5e8b3a91fbd411056326a4ea8e6757ba1bdb2d2b5a6152d87734fca9b59997b8", + "yawDegrees": 0, + "pitchDegrees": 89, + "framing": { + "zoom": 1, + "panX": 0, + "panY": 0 + }, + "lens": "eso1119b" + } + ], + "errors": [], + "failures": [] +} diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/crab-comparison.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/crab-comparison.json new file mode 100644 index 0000000000..552067690e --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/crab-comparison.json @@ -0,0 +1,277 @@ +{ + "id": "b3dba61dfa3cdc744220bde4abf59e3e7d52a4bc7f499d131edbac83f0effb5d", + "sourceResult": "7ffff9eabf29c89d06afe87187dfc3a9565044619b23d4d48aa47df01e9fb9dd", + "inputPin": { + "path": "src/objects/m1/source/compact/model.json.gz", + "sha256": "19a8d6d41d35694861e2ce5db6414f2d8f2a59ad9ea6d0129c3dc1d628b60be5" + }, + "seconds": 494.772349208, + "plannedLayers": 391, + "referenceLayers": 547, + "proxy": { + "schema": "cssearth-layer-optimization@1", + "method": "gradient-weighted-depth-displacement@1", + "maximumLayers": 500, + "referenceLayers": 547, + "plannedLayers": 391, + "probeWidth": 64, + "probeSubpixels": 2, + "targetNormalizedL1": 0.01, + "estimatedNormalizedL1": { + "x": 0.00994595469364007, + "y": 0.009937762653267417, + "z": 0.00935854498311306 + }, + "status": "target-met" + }, + "thresholds": { + "relativeLuminanceDifference": 0.05, + "normalizedL1": 0.04 + }, + "oldPassingHandoffs": 12, + "newPassingHandoffs": 12, + "newlyFailingHandoffs": [], + "rows": [ + { + "id": "neutral", + "seam": "xz", + "oldL1": 0.01611342389813306, + "newL1": 0.021557419464845146, + "deltaL1": 0.005443995566712087, + "oldLuminance": 0.00027552104184480587, + "newLuminance": 0.00153794084585362, + "oldPassed": true, + "newPassed": true + }, + { + "id": "neutral", + "seam": "yz", + "oldL1": 0.014773440583234947, + "newL1": 0.02140600176955358, + "deltaL1": 0.0066325611863186345, + "oldLuminance": 0.00013169512030918756, + "newLuminance": 0.002474425224846249, + "oldPassed": true, + "newPassed": true + }, + { + "id": "hubble-optical", + "seam": "xz", + "oldL1": 0.019883459215999356, + "newL1": 0.025121290268514982, + "deltaL1": 0.005237831052515626, + "oldLuminance": 0.0012833102136353902, + "newLuminance": 0.0010019973280881017, + "oldPassed": true, + "newPassed": true + }, + { + "id": "hubble-optical", + "seam": "yz", + "oldL1": 0.018124596469084063, + "newL1": 0.024306401397345925, + "deltaL1": 0.006181804928261862, + "oldLuminance": 0.0007133230669537579, + "newLuminance": 0.0005227232072247526, + "oldPassed": true, + "newPassed": true + }, + { + "id": "webb-infrared", + "seam": "xz", + "oldL1": 0.021317259108527307, + "newL1": 0.025931641487936547, + "deltaL1": 0.00461438237940924, + "oldLuminance": 0.0018783274754755708, + "newLuminance": 0.0007795748246750415, + "oldPassed": true, + "newPassed": true + }, + { + "id": "webb-infrared", + "seam": "yz", + "oldL1": 0.019996894922608893, + "newL1": 0.025260506157460182, + "deltaL1": 0.005263611234851289, + "oldLuminance": 0.0004364466961828152, + "newLuminance": 0.0005879246850327958, + "oldPassed": true, + "newPassed": true + }, + { + "id": "webb-components", + "seam": "xz", + "oldL1": 0.024794299034011966, + "newL1": 0.028528778292168, + "deltaL1": 0.0037344792581560336, + "oldLuminance": 0.005105976928289425, + "newLuminance": 0.004902312949147532, + "oldPassed": true, + "newPassed": true + }, + { + "id": "webb-components", + "seam": "yz", + "oldL1": 0.024191560556441335, + "newL1": 0.02795225760892037, + "deltaL1": 0.0037606970524790354, + "oldLuminance": 0.00180017315430286, + "newLuminance": 0.0015339890776214166, + "oldPassed": true, + "newPassed": true + }, + { + "id": "spitzer-infrared", + "seam": "xz", + "oldL1": 0.04162007961576139, + "newL1": 0.04730136058002308, + "deltaL1": 0.005681280964261688, + "oldLuminance": 0.00817396217391176, + "newLuminance": 0.010624923970739386, + "oldPassed": false, + "newPassed": false + }, + { + "id": "spitzer-infrared", + "seam": "yz", + "oldL1": 0.040298190851867435, + "newL1": 0.046997640170076405, + "deltaL1": 0.006699449318208969, + "oldLuminance": 0.000048080757939896155, + "newLuminance": 0.000039668396440669355, + "oldPassed": false, + "newPassed": false + }, + { + "id": "vla-radio", + "seam": "xz", + "oldL1": 0.01966909289539202, + "newL1": 0.02430044708323659, + "deltaL1": 0.0046313541878445705, + "oldLuminance": 0.00016423927598018708, + "newLuminance": 0.0003125896665436954, + "oldPassed": true, + "newPassed": true + }, + { + "id": "vla-radio", + "seam": "yz", + "oldL1": 0.019484338848797633, + "newL1": 0.024533821109419485, + "deltaL1": 0.0050494822606218515, + "oldLuminance": 0.0012829696777013151, + "newLuminance": 0.0005796496642948497, + "oldPassed": true, + "newPassed": true + }, + { + "id": "chandra-xray", + "seam": "xz", + "oldL1": 0.014827151353326433, + "newL1": 0.014827151353326433, + "deltaL1": 0, + "oldLuminance": 0.0030534510270157854, + "newLuminance": 0.0030534510270157854, + "oldPassed": true, + "newPassed": true + }, + { + "id": "chandra-xray", + "seam": "yz", + "oldL1": 0.013362636284053831, + "newL1": 0.013362636284053831, + "deltaL1": 0, + "oldLuminance": 0.0009057123734755019, + "newLuminance": 0.0009057123734755019, + "oldPassed": true, + "newPassed": true + } + ], + "payloads": [ + { + "id": "neutral", + "oldLayers": 542, + "newLayers": 391, + "oldTextureBytes": 16608883, + "newTextureBytes": 15607732 + }, + { + "id": "hubble-optical", + "oldLayers": 542, + "newLayers": 391, + "oldTextureBytes": 96994439, + "newTextureBytes": 93807947 + }, + { + "id": "webb-infrared", + "oldLayers": 542, + "newLayers": 391, + "oldTextureBytes": 70359876, + "newTextureBytes": 68084516 + }, + { + "id": "webb-components", + "oldLayers": 542, + "newLayers": 391, + "oldTextureBytes": 82530133, + "newTextureBytes": 80394535 + }, + { + "id": "spitzer-infrared", + "oldLayers": 542, + "newLayers": 391, + "oldTextureBytes": 39738055, + "newTextureBytes": 38912299 + }, + { + "id": "vla-radio", + "oldLayers": 542, + "newLayers": 391, + "oldTextureBytes": 38441484, + "newTextureBytes": 37107868 + }, + { + "id": "chandra-xray", + "oldLayers": 542, + "newLayers": 391, + "oldTextureBytes": 1158012, + "newTextureBytes": 1088117 + } + ], + "matchedViews": [ + { + "lens": "neutral", + "pose": "front", + "oldVsNewNormalizedL1": 0.0042863111939171195, + "oldVsNewRelativeLuminanceDifference": 0.007934368685691588 + }, + { + "lens": "neutral", + "pose": "oblique", + "oldVsNewNormalizedL1": 0.0069732144048081125, + "oldVsNewRelativeLuminanceDifference": 0.009067779892565405 + }, + { + "lens": "hubble-optical", + "pose": "front", + "oldVsNewNormalizedL1": 0.00544403417960676, + "oldVsNewRelativeLuminanceDifference": 0.006831807070630873 + }, + { + "lens": "hubble-optical", + "pose": "oblique", + "oldVsNewNormalizedL1": 0.008467885979563996, + "oldVsNewRelativeLuminanceDifference": 0.0077562834323448415 + } + ], + "actualBrowserErrors": { + "baseline": [], + "current": [], + "baselineFailedRequests": [], + "currentFailedRequests": [], + "baselineWrites": [], + "currentWrites": [] + }, + "retainedMounts": true, + "interpretation": "Real source-backed retained fields. Source pins/accepted package immutable. The planner proxy is not browser acceptance; every failed handoff remains a failure." +} diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/front.png b/labs/nebula/models/omega-centauri/evidence/2026-09-20/front.png new file mode 100644 index 0000000000..8c402ad1a9 Binary files /dev/null and b/labs/nebula/models/omega-centauri/evidence/2026-09-20/front.png differ diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/layer-bake.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/layer-bake.json new file mode 100644 index 0000000000..10f73d50b8 --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/layer-bake.json @@ -0,0 +1,1951 @@ +{ + "id": "7a4f8781a7d19fafa57f11e65eae6ee24975082d3fcae0c1644cbdd68a5ac549", + "outputDirectory": "output/pr390-audit/layer-optimization/omega-7a4f8781a7d19fafa57f11e65eae6ee24975082d3fcae0c1644cbdd68a5ac549", + "elapsedSeconds": 230.938560959, + "sampling": { + "sliceCounts": { + "x": 147, + "y": 143, + "z": 171 + }, + "imageWidth": 512, + "samplesPerSlab": 4, + "layerPlan": { + "schema": "cssearth-volume-layer-plan@1", + "referenceSliceCounts": { + "x": 264, + "y": 264, + "z": 512 + }, + "referenceSamplesPerSlab": 4, + "axes": { + "x": [ + { + "startCell": 0, + "endCell": 34 + }, + { + "startCell": 34, + "endCell": 41 + }, + { + "startCell": 41, + "endCell": 46 + }, + { + "startCell": 46, + "endCell": 49 + }, + { + "startCell": 49, + "endCell": 51 + }, + { + "startCell": 51, + "endCell": 54 + }, + { + "startCell": 54, + "endCell": 58 + }, + { + "startCell": 58, + "endCell": 61 + }, + { + "startCell": 61, + "endCell": 63 + }, + { + "startCell": 63, + "endCell": 66 + }, + { + "startCell": 66, + "endCell": 67 + }, + { + "startCell": 67, + "endCell": 68 + }, + { + "startCell": 68, + "endCell": 69 + }, + { + "startCell": 69, + "endCell": 71 + }, + { + "startCell": 71, + "endCell": 72 + }, + { + "startCell": 72, + "endCell": 73 + }, + { + "startCell": 73, + "endCell": 74 + }, + { + "startCell": 74, + "endCell": 77 + }, + { + "startCell": 77, + "endCell": 78 + }, + { + "startCell": 78, + "endCell": 79 + }, + { + "startCell": 79, + "endCell": 81 + }, + { + "startCell": 81, + "endCell": 82 + }, + { + "startCell": 82, + "endCell": 83 + }, + { + "startCell": 83, + "endCell": 84 + }, + { + "startCell": 84, + "endCell": 85 + }, + { + "startCell": 85, + "endCell": 86 + }, + { + "startCell": 86, + "endCell": 87 + }, + { + "startCell": 87, + "endCell": 88 + }, + { + "startCell": 88, + "endCell": 89 + }, + { + "startCell": 89, + "endCell": 90 + }, + { + "startCell": 90, + "endCell": 91 + }, + { + "startCell": 91, + "endCell": 92 + }, + { + "startCell": 92, + "endCell": 93 + }, + { + "startCell": 93, + "endCell": 94 + }, + { + "startCell": 94, + "endCell": 95 + }, + { + "startCell": 95, + "endCell": 96 + }, + { + "startCell": 96, + "endCell": 97 + }, + { + "startCell": 97, + "endCell": 98 + }, + { + "startCell": 98, + "endCell": 99 + }, + { + "startCell": 99, + "endCell": 100 + }, + { + "startCell": 100, + "endCell": 101 + }, + { + "startCell": 101, + "endCell": 102 + }, + { + "startCell": 102, + "endCell": 103 + }, + { + "startCell": 103, + "endCell": 104 + }, + { + "startCell": 104, + "endCell": 105 + }, + { + "startCell": 105, + "endCell": 106 + }, + { + "startCell": 106, + "endCell": 107 + }, + { + "startCell": 107, + "endCell": 108 + }, + { + "startCell": 108, + "endCell": 109 + }, + { + "startCell": 109, + "endCell": 110 + }, + { + "startCell": 110, + "endCell": 111 + }, + { + "startCell": 111, + "endCell": 112 + }, + { + "startCell": 112, + "endCell": 113 + }, + { + "startCell": 113, + "endCell": 114 + }, + { + "startCell": 114, + "endCell": 115 + }, + { + "startCell": 115, + "endCell": 116 + }, + { + "startCell": 116, + "endCell": 117 + }, + { + "startCell": 117, + "endCell": 118 + }, + { + "startCell": 118, + "endCell": 119 + }, + { + "startCell": 119, + "endCell": 120 + }, + { + "startCell": 120, + "endCell": 121 + }, + { + "startCell": 121, + "endCell": 122 + }, + { + "startCell": 122, + "endCell": 123 + }, + { + "startCell": 123, + "endCell": 124 + }, + { + "startCell": 124, + "endCell": 125 + }, + { + "startCell": 125, + "endCell": 126 + }, + { + "startCell": 126, + "endCell": 127 + }, + { + "startCell": 127, + "endCell": 128 + }, + { + "startCell": 128, + "endCell": 129 + }, + { + "startCell": 129, + "endCell": 130 + }, + { + "startCell": 130, + "endCell": 131 + }, + { + "startCell": 131, + "endCell": 132 + }, + { + "startCell": 132, + "endCell": 133 + }, + { + "startCell": 133, + "endCell": 134 + }, + { + "startCell": 134, + "endCell": 135 + }, + { + "startCell": 135, + "endCell": 136 + }, + { + "startCell": 136, + "endCell": 137 + }, + { + "startCell": 137, + "endCell": 138 + }, + { + "startCell": 138, + "endCell": 139 + }, + { + "startCell": 139, + "endCell": 140 + }, + { + "startCell": 140, + "endCell": 141 + }, + { + "startCell": 141, + "endCell": 142 + }, + { + "startCell": 142, + "endCell": 143 + }, + { + "startCell": 143, + "endCell": 144 + }, + { + "startCell": 144, + "endCell": 145 + }, + { + "startCell": 145, + "endCell": 146 + }, + { + "startCell": 146, + "endCell": 147 + }, + { + "startCell": 147, + "endCell": 148 + }, + { + "startCell": 148, + "endCell": 149 + }, + { + "startCell": 149, + "endCell": 150 + }, + { + "startCell": 150, + "endCell": 151 + }, + { + "startCell": 151, + "endCell": 152 + }, + { + "startCell": 152, + "endCell": 153 + }, + { + "startCell": 153, + "endCell": 154 + }, + { + "startCell": 154, + "endCell": 155 + }, + { + "startCell": 155, + "endCell": 156 + }, + { + "startCell": 156, + "endCell": 157 + }, + { + "startCell": 157, + "endCell": 158 + }, + { + "startCell": 158, + "endCell": 159 + }, + { + "startCell": 159, + "endCell": 160 + }, + { + "startCell": 160, + "endCell": 161 + }, + { + "startCell": 161, + "endCell": 162 + }, + { + "startCell": 162, + "endCell": 163 + }, + { + "startCell": 163, + "endCell": 164 + }, + { + "startCell": 164, + "endCell": 165 + }, + { + "startCell": 165, + "endCell": 166 + }, + { + "startCell": 166, + "endCell": 167 + }, + { + "startCell": 167, + "endCell": 168 + }, + { + "startCell": 168, + "endCell": 169 + }, + { + "startCell": 169, + "endCell": 170 + }, + { + "startCell": 170, + "endCell": 171 + }, + { + "startCell": 171, + "endCell": 172 + }, + { + "startCell": 172, + "endCell": 173 + }, + { + "startCell": 173, + "endCell": 174 + }, + { + "startCell": 174, + "endCell": 175 + }, + { + "startCell": 175, + "endCell": 176 + }, + { + "startCell": 176, + "endCell": 177 + }, + { + "startCell": 177, + "endCell": 178 + }, + { + "startCell": 178, + "endCell": 179 + }, + { + "startCell": 179, + "endCell": 180 + }, + { + "startCell": 180, + "endCell": 181 + }, + { + "startCell": 181, + "endCell": 182 + }, + { + "startCell": 182, + "endCell": 183 + }, + { + "startCell": 183, + "endCell": 184 + }, + { + "startCell": 184, + "endCell": 187 + }, + { + "startCell": 187, + "endCell": 189 + }, + { + "startCell": 189, + "endCell": 190 + }, + { + "startCell": 190, + "endCell": 191 + }, + { + "startCell": 191, + "endCell": 192 + }, + { + "startCell": 192, + "endCell": 195 + }, + { + "startCell": 195, + "endCell": 196 + }, + { + "startCell": 196, + "endCell": 197 + }, + { + "startCell": 197, + "endCell": 198 + }, + { + "startCell": 198, + "endCell": 199 + }, + { + "startCell": 199, + "endCell": 201 + }, + { + "startCell": 201, + "endCell": 204 + }, + { + "startCell": 204, + "endCell": 206 + }, + { + "startCell": 206, + "endCell": 207 + }, + { + "startCell": 207, + "endCell": 208 + }, + { + "startCell": 208, + "endCell": 210 + }, + { + "startCell": 210, + "endCell": 213 + }, + { + "startCell": 213, + "endCell": 216 + }, + { + "startCell": 216, + "endCell": 217 + }, + { + "startCell": 217, + "endCell": 219 + }, + { + "startCell": 219, + "endCell": 222 + }, + { + "startCell": 222, + "endCell": 225 + }, + { + "startCell": 225, + "endCell": 264 + } + ], + "y": [ + { + "startCell": 0, + "endCell": 39 + }, + { + "startCell": 39, + "endCell": 46 + }, + { + "startCell": 46, + "endCell": 48 + }, + { + "startCell": 48, + "endCell": 49 + }, + { + "startCell": 49, + "endCell": 51 + }, + { + "startCell": 51, + "endCell": 52 + }, + { + "startCell": 52, + "endCell": 53 + }, + { + "startCell": 53, + "endCell": 54 + }, + { + "startCell": 54, + "endCell": 55 + }, + { + "startCell": 55, + "endCell": 56 + }, + { + "startCell": 56, + "endCell": 57 + }, + { + "startCell": 57, + "endCell": 60 + }, + { + "startCell": 60, + "endCell": 63 + }, + { + "startCell": 63, + "endCell": 66 + }, + { + "startCell": 66, + "endCell": 69 + }, + { + "startCell": 69, + "endCell": 70 + }, + { + "startCell": 70, + "endCell": 73 + }, + { + "startCell": 73, + "endCell": 74 + }, + { + "startCell": 74, + "endCell": 75 + }, + { + "startCell": 75, + "endCell": 76 + }, + { + "startCell": 76, + "endCell": 77 + }, + { + "startCell": 77, + "endCell": 78 + }, + { + "startCell": 78, + "endCell": 79 + }, + { + "startCell": 79, + "endCell": 80 + }, + { + "startCell": 80, + "endCell": 81 + }, + { + "startCell": 81, + "endCell": 82 + }, + { + "startCell": 82, + "endCell": 83 + }, + { + "startCell": 83, + "endCell": 84 + }, + { + "startCell": 84, + "endCell": 87 + }, + { + "startCell": 87, + "endCell": 88 + }, + { + "startCell": 88, + "endCell": 89 + }, + { + "startCell": 89, + "endCell": 90 + }, + { + "startCell": 90, + "endCell": 91 + }, + { + "startCell": 91, + "endCell": 92 + }, + { + "startCell": 92, + "endCell": 93 + }, + { + "startCell": 93, + "endCell": 94 + }, + { + "startCell": 94, + "endCell": 95 + }, + { + "startCell": 95, + "endCell": 96 + }, + { + "startCell": 96, + "endCell": 97 + }, + { + "startCell": 97, + "endCell": 98 + }, + { + "startCell": 98, + "endCell": 99 + }, + { + "startCell": 99, + "endCell": 100 + }, + { + "startCell": 100, + "endCell": 101 + }, + { + "startCell": 101, + "endCell": 102 + }, + { + "startCell": 102, + "endCell": 103 + }, + { + "startCell": 103, + "endCell": 104 + }, + { + "startCell": 104, + "endCell": 105 + }, + { + "startCell": 105, + "endCell": 106 + }, + { + "startCell": 106, + "endCell": 107 + }, + { + "startCell": 107, + "endCell": 108 + }, + { + "startCell": 108, + "endCell": 109 + }, + { + "startCell": 109, + "endCell": 110 + }, + { + "startCell": 110, + "endCell": 111 + }, + { + "startCell": 111, + "endCell": 112 + }, + { + "startCell": 112, + "endCell": 113 + }, + { + "startCell": 113, + "endCell": 114 + }, + { + "startCell": 114, + "endCell": 115 + }, + { + "startCell": 115, + "endCell": 116 + }, + { + "startCell": 116, + "endCell": 117 + }, + { + "startCell": 117, + "endCell": 118 + }, + { + "startCell": 118, + "endCell": 119 + }, + { + "startCell": 119, + "endCell": 120 + }, + { + "startCell": 120, + "endCell": 121 + }, + { + "startCell": 121, + "endCell": 122 + }, + { + "startCell": 122, + "endCell": 123 + }, + { + "startCell": 123, + "endCell": 124 + }, + { + "startCell": 124, + "endCell": 125 + }, + { + "startCell": 125, + "endCell": 126 + }, + { + "startCell": 126, + "endCell": 127 + }, + { + "startCell": 127, + "endCell": 128 + }, + { + "startCell": 128, + "endCell": 129 + }, + { + "startCell": 129, + "endCell": 130 + }, + { + "startCell": 130, + "endCell": 131 + }, + { + "startCell": 131, + "endCell": 132 + }, + { + "startCell": 132, + "endCell": 133 + }, + { + "startCell": 133, + "endCell": 134 + }, + { + "startCell": 134, + "endCell": 135 + }, + { + "startCell": 135, + "endCell": 136 + }, + { + "startCell": 136, + "endCell": 137 + }, + { + "startCell": 137, + "endCell": 138 + }, + { + "startCell": 138, + "endCell": 139 + }, + { + "startCell": 139, + "endCell": 140 + }, + { + "startCell": 140, + "endCell": 141 + }, + { + "startCell": 141, + "endCell": 142 + }, + { + "startCell": 142, + "endCell": 143 + }, + { + "startCell": 143, + "endCell": 144 + }, + { + "startCell": 144, + "endCell": 145 + }, + { + "startCell": 145, + "endCell": 146 + }, + { + "startCell": 146, + "endCell": 147 + }, + { + "startCell": 147, + "endCell": 148 + }, + { + "startCell": 148, + "endCell": 149 + }, + { + "startCell": 149, + "endCell": 150 + }, + { + "startCell": 150, + "endCell": 151 + }, + { + "startCell": 151, + "endCell": 152 + }, + { + "startCell": 152, + "endCell": 153 + }, + { + "startCell": 153, + "endCell": 154 + }, + { + "startCell": 154, + "endCell": 155 + }, + { + "startCell": 155, + "endCell": 156 + }, + { + "startCell": 156, + "endCell": 157 + }, + { + "startCell": 157, + "endCell": 158 + }, + { + "startCell": 158, + "endCell": 159 + }, + { + "startCell": 159, + "endCell": 160 + }, + { + "startCell": 160, + "endCell": 161 + }, + { + "startCell": 161, + "endCell": 162 + }, + { + "startCell": 162, + "endCell": 163 + }, + { + "startCell": 163, + "endCell": 164 + }, + { + "startCell": 164, + "endCell": 165 + }, + { + "startCell": 165, + "endCell": 166 + }, + { + "startCell": 166, + "endCell": 167 + }, + { + "startCell": 167, + "endCell": 168 + }, + { + "startCell": 168, + "endCell": 169 + }, + { + "startCell": 169, + "endCell": 170 + }, + { + "startCell": 170, + "endCell": 171 + }, + { + "startCell": 171, + "endCell": 172 + }, + { + "startCell": 172, + "endCell": 173 + }, + { + "startCell": 173, + "endCell": 174 + }, + { + "startCell": 174, + "endCell": 175 + }, + { + "startCell": 175, + "endCell": 176 + }, + { + "startCell": 176, + "endCell": 177 + }, + { + "startCell": 177, + "endCell": 178 + }, + { + "startCell": 178, + "endCell": 179 + }, + { + "startCell": 179, + "endCell": 180 + }, + { + "startCell": 180, + "endCell": 182 + }, + { + "startCell": 182, + "endCell": 183 + }, + { + "startCell": 183, + "endCell": 184 + }, + { + "startCell": 184, + "endCell": 185 + }, + { + "startCell": 185, + "endCell": 187 + }, + { + "startCell": 187, + "endCell": 190 + }, + { + "startCell": 190, + "endCell": 191 + }, + { + "startCell": 191, + "endCell": 194 + }, + { + "startCell": 194, + "endCell": 197 + }, + { + "startCell": 197, + "endCell": 200 + }, + { + "startCell": 200, + "endCell": 203 + }, + { + "startCell": 203, + "endCell": 204 + }, + { + "startCell": 204, + "endCell": 207 + }, + { + "startCell": 207, + "endCell": 210 + }, + { + "startCell": 210, + "endCell": 213 + }, + { + "startCell": 213, + "endCell": 216 + }, + { + "startCell": 216, + "endCell": 219 + }, + { + "startCell": 219, + "endCell": 222 + }, + { + "startCell": 222, + "endCell": 225 + }, + { + "startCell": 225, + "endCell": 234 + }, + { + "startCell": 234, + "endCell": 264 + } + ], + "z": [ + { + "startCell": 0, + "endCell": 74 + }, + { + "startCell": 74, + "endCell": 95 + }, + { + "startCell": 95, + "endCell": 112 + }, + { + "startCell": 112, + "endCell": 117 + }, + { + "startCell": 117, + "endCell": 126 + }, + { + "startCell": 126, + "endCell": 134 + }, + { + "startCell": 134, + "endCell": 145 + }, + { + "startCell": 145, + "endCell": 156 + }, + { + "startCell": 156, + "endCell": 162 + }, + { + "startCell": 162, + "endCell": 169 + }, + { + "startCell": 169, + "endCell": 172 + }, + { + "startCell": 172, + "endCell": 177 + }, + { + "startCell": 177, + "endCell": 180 + }, + { + "startCell": 180, + "endCell": 181 + }, + { + "startCell": 181, + "endCell": 184 + }, + { + "startCell": 184, + "endCell": 187 + }, + { + "startCell": 187, + "endCell": 192 + }, + { + "startCell": 192, + "endCell": 195 + }, + { + "startCell": 195, + "endCell": 196 + }, + { + "startCell": 196, + "endCell": 197 + }, + { + "startCell": 197, + "endCell": 200 + }, + { + "startCell": 200, + "endCell": 203 + }, + { + "startCell": 203, + "endCell": 206 + }, + { + "startCell": 206, + "endCell": 209 + }, + { + "startCell": 209, + "endCell": 212 + }, + { + "startCell": 212, + "endCell": 213 + }, + { + "startCell": 213, + "endCell": 214 + }, + { + "startCell": 214, + "endCell": 216 + }, + { + "startCell": 216, + "endCell": 217 + }, + { + "startCell": 217, + "endCell": 218 + }, + { + "startCell": 218, + "endCell": 220 + }, + { + "startCell": 220, + "endCell": 221 + }, + { + "startCell": 221, + "endCell": 222 + }, + { + "startCell": 222, + "endCell": 223 + }, + { + "startCell": 223, + "endCell": 224 + }, + { + "startCell": 224, + "endCell": 225 + }, + { + "startCell": 225, + "endCell": 226 + }, + { + "startCell": 226, + "endCell": 227 + }, + { + "startCell": 227, + "endCell": 228 + }, + { + "startCell": 228, + "endCell": 229 + }, + { + "startCell": 229, + "endCell": 230 + }, + { + "startCell": 230, + "endCell": 231 + }, + { + "startCell": 231, + "endCell": 232 + }, + { + "startCell": 232, + "endCell": 233 + }, + { + "startCell": 233, + "endCell": 234 + }, + { + "startCell": 234, + "endCell": 235 + }, + { + "startCell": 235, + "endCell": 236 + }, + { + "startCell": 236, + "endCell": 237 + }, + { + "startCell": 237, + "endCell": 238 + }, + { + "startCell": 238, + "endCell": 239 + }, + { + "startCell": 239, + "endCell": 240 + }, + { + "startCell": 240, + "endCell": 241 + }, + { + "startCell": 241, + "endCell": 242 + }, + { + "startCell": 242, + "endCell": 243 + }, + { + "startCell": 243, + "endCell": 244 + }, + { + "startCell": 244, + "endCell": 245 + }, + { + "startCell": 245, + "endCell": 246 + }, + { + "startCell": 246, + "endCell": 247 + }, + { + "startCell": 247, + "endCell": 248 + }, + { + "startCell": 248, + "endCell": 249 + }, + { + "startCell": 249, + "endCell": 250 + }, + { + "startCell": 250, + "endCell": 251 + }, + { + "startCell": 251, + "endCell": 252 + }, + { + "startCell": 252, + "endCell": 253 + }, + { + "startCell": 253, + "endCell": 254 + }, + { + "startCell": 254, + "endCell": 255 + }, + { + "startCell": 255, + "endCell": 256 + }, + { + "startCell": 256, + "endCell": 257 + }, + { + "startCell": 257, + "endCell": 258 + }, + { + "startCell": 258, + "endCell": 259 + }, + { + "startCell": 259, + "endCell": 260 + }, + { + "startCell": 260, + "endCell": 261 + }, + { + "startCell": 261, + "endCell": 262 + }, + { + "startCell": 262, + "endCell": 263 + }, + { + "startCell": 263, + "endCell": 264 + }, + { + "startCell": 264, + "endCell": 265 + }, + { + "startCell": 265, + "endCell": 266 + }, + { + "startCell": 266, + "endCell": 267 + }, + { + "startCell": 267, + "endCell": 268 + }, + { + "startCell": 268, + "endCell": 269 + }, + { + "startCell": 269, + "endCell": 270 + }, + { + "startCell": 270, + "endCell": 271 + }, + { + "startCell": 271, + "endCell": 272 + }, + { + "startCell": 272, + "endCell": 273 + }, + { + "startCell": 273, + "endCell": 274 + }, + { + "startCell": 274, + "endCell": 275 + }, + { + "startCell": 275, + "endCell": 276 + }, + { + "startCell": 276, + "endCell": 277 + }, + { + "startCell": 277, + "endCell": 278 + }, + { + "startCell": 278, + "endCell": 279 + }, + { + "startCell": 279, + "endCell": 280 + }, + { + "startCell": 280, + "endCell": 281 + }, + { + "startCell": 281, + "endCell": 282 + }, + { + "startCell": 282, + "endCell": 283 + }, + { + "startCell": 283, + "endCell": 284 + }, + { + "startCell": 284, + "endCell": 285 + }, + { + "startCell": 285, + "endCell": 286 + }, + { + "startCell": 286, + "endCell": 287 + }, + { + "startCell": 287, + "endCell": 288 + }, + { + "startCell": 288, + "endCell": 289 + }, + { + "startCell": 289, + "endCell": 290 + }, + { + "startCell": 290, + "endCell": 291 + }, + { + "startCell": 291, + "endCell": 292 + }, + { + "startCell": 292, + "endCell": 293 + }, + { + "startCell": 293, + "endCell": 294 + }, + { + "startCell": 294, + "endCell": 295 + }, + { + "startCell": 295, + "endCell": 296 + }, + { + "startCell": 296, + "endCell": 297 + }, + { + "startCell": 297, + "endCell": 298 + }, + { + "startCell": 298, + "endCell": 299 + }, + { + "startCell": 299, + "endCell": 300 + }, + { + "startCell": 300, + "endCell": 301 + }, + { + "startCell": 301, + "endCell": 302 + }, + { + "startCell": 302, + "endCell": 303 + }, + { + "startCell": 303, + "endCell": 304 + }, + { + "startCell": 304, + "endCell": 305 + }, + { + "startCell": 305, + "endCell": 306 + }, + { + "startCell": 306, + "endCell": 307 + }, + { + "startCell": 307, + "endCell": 308 + }, + { + "startCell": 308, + "endCell": 309 + }, + { + "startCell": 309, + "endCell": 310 + }, + { + "startCell": 310, + "endCell": 311 + }, + { + "startCell": 311, + "endCell": 312 + }, + { + "startCell": 312, + "endCell": 313 + }, + { + "startCell": 313, + "endCell": 314 + }, + { + "startCell": 314, + "endCell": 315 + }, + { + "startCell": 315, + "endCell": 316 + }, + { + "startCell": 316, + "endCell": 317 + }, + { + "startCell": 317, + "endCell": 318 + }, + { + "startCell": 318, + "endCell": 319 + }, + { + "startCell": 319, + "endCell": 320 + }, + { + "startCell": 320, + "endCell": 321 + }, + { + "startCell": 321, + "endCell": 323 + }, + { + "startCell": 323, + "endCell": 324 + }, + { + "startCell": 324, + "endCell": 325 + }, + { + "startCell": 325, + "endCell": 326 + }, + { + "startCell": 326, + "endCell": 327 + }, + { + "startCell": 327, + "endCell": 330 + }, + { + "startCell": 330, + "endCell": 331 + }, + { + "startCell": 331, + "endCell": 334 + }, + { + "startCell": 334, + "endCell": 335 + }, + { + "startCell": 335, + "endCell": 338 + }, + { + "startCell": 338, + "endCell": 339 + }, + { + "startCell": 339, + "endCell": 340 + }, + { + "startCell": 340, + "endCell": 343 + }, + { + "startCell": 343, + "endCell": 345 + }, + { + "startCell": 345, + "endCell": 348 + }, + { + "startCell": 348, + "endCell": 351 + }, + { + "startCell": 351, + "endCell": 354 + }, + { + "startCell": 354, + "endCell": 357 + }, + { + "startCell": 357, + "endCell": 358 + }, + { + "startCell": 358, + "endCell": 360 + }, + { + "startCell": 360, + "endCell": 363 + }, + { + "startCell": 363, + "endCell": 366 + }, + { + "startCell": 366, + "endCell": 369 + }, + { + "startCell": 369, + "endCell": 373 + }, + { + "startCell": 373, + "endCell": 374 + }, + { + "startCell": 374, + "endCell": 375 + }, + { + "startCell": 375, + "endCell": 376 + }, + { + "startCell": 376, + "endCell": 380 + }, + { + "startCell": 380, + "endCell": 385 + }, + { + "startCell": 385, + "endCell": 390 + }, + { + "startCell": 390, + "endCell": 401 + }, + { + "startCell": 401, + "endCell": 409 + }, + { + "startCell": 409, + "endCell": 411 + }, + { + "startCell": 411, + "endCell": 420 + }, + { + "startCell": 420, + "endCell": 447 + }, + { + "startCell": 447, + "endCell": 450 + }, + { + "startCell": 450, + "endCell": 455 + }, + { + "startCell": 455, + "endCell": 458 + }, + { + "startCell": 458, + "endCell": 512 + } + ] + } + }, + "layerOptimization": { + "schema": "cssearth-layer-optimization@1", + "method": "gradient-weighted-depth-displacement@1", + "maximumLayers": 500, + "referenceLayers": 1040, + "plannedLayers": 461, + "probeWidth": 64, + "probeSubpixels": 2, + "targetNormalizedL1": 0.01, + "estimatedNormalizedL1": { + "x": 0.0098247993518533, + "y": 0.00981228328179792, + "z": 0.009852407570529206 + }, + "status": "target-met" + } + }, + "banks": [ + { + "id": "neutral", + "counts": [ + { + "axis": "x", + "retained": 146 + }, + { + "axis": "y", + "retained": 142 + }, + { + "axis": "z", + "retained": 171 + } + ], + "resources": 459, + "bytes": 5954296 + }, + { + "id": "eso1119b", + "counts": [ + { + "axis": "x", + "retained": 146 + }, + { + "axis": "y", + "retained": 142 + }, + { + "axis": "z", + "retained": 171 + } + ], + "resources": 459, + "bytes": 13866551 + }, + { + "id": "eso0844a", + "counts": [ + { + "axis": "x", + "retained": 146 + }, + { + "axis": "y", + "retained": 142 + }, + { + "axis": "z", + "retained": 171 + } + ], + "resources": 459, + "bytes": 13158283 + } + ], + "status": "inspection-only-unaccepted" +} \ No newline at end of file diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/layer-handoffs.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/layer-handoffs.json new file mode 100644 index 0000000000..4aac2528fd --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/layer-handoffs.json @@ -0,0 +1,176 @@ +{ + "oldId": "5d934218dcc59475e632d503bea59dfeb3bb156431d8d88d3616830808b23df9", + "optimizedId": "7a4f8781a7d19fafa57f11e65eae6ee24975082d3fcae0c1644cbdd68a5ac549", + "thresholds": { + "relativeLuminanceDifference": 0.05, + "normalizedL1": 0.04 + }, + "measurements": [ + { + "version": "old", + "lens": "neutral", + "seam": "xz", + "relativeLuminanceDifference": 0.007448274204638095, + "normalizedL1": 0.10579373570430688, + "passed": false + }, + { + "version": "old", + "lens": "neutral", + "seam": "yz", + "relativeLuminanceDifference": 0.0013473004012343357, + "normalizedL1": 0.09407192435762682, + "passed": false + }, + { + "version": "old", + "lens": "neutral", + "seam": "xy", + "relativeLuminanceDifference": 0.5939720780803218, + "normalizedL1": 0.4445885734295744, + "passed": false + }, + { + "version": "old", + "lens": "eso1119b", + "seam": "xz", + "relativeLuminanceDifference": 0.007659996564966913, + "normalizedL1": 0.10335238699683513, + "passed": false + }, + { + "version": "old", + "lens": "eso1119b", + "seam": "yz", + "relativeLuminanceDifference": 0.0013421471217446319, + "normalizedL1": 0.09204724768477665, + "passed": false + }, + { + "version": "old", + "lens": "eso1119b", + "seam": "xy", + "relativeLuminanceDifference": 0.013268410687652613, + "normalizedL1": 0.10212193390601276, + "passed": false + }, + { + "version": "old", + "lens": "eso0844a", + "seam": "xz", + "relativeLuminanceDifference": 0.007485076722130978, + "normalizedL1": 0.10509154123884833, + "passed": false + }, + { + "version": "old", + "lens": "eso0844a", + "seam": "yz", + "relativeLuminanceDifference": 0.0013441126162484919, + "normalizedL1": 0.0933923526990095, + "passed": false + }, + { + "version": "old", + "lens": "eso0844a", + "seam": "xy", + "relativeLuminanceDifference": 0.013233523895923052, + "normalizedL1": 0.1035187536996954, + "passed": false + }, + { + "version": "optimized", + "lens": "neutral", + "seam": "xz", + "relativeLuminanceDifference": 0.004804672942986058, + "normalizedL1": 0.12498652413707272, + "passed": false + }, + { + "version": "optimized", + "lens": "neutral", + "seam": "yz", + "relativeLuminanceDifference": 0.003411535415403307, + "normalizedL1": 0.1146546907233652, + "passed": false + }, + { + "version": "optimized", + "lens": "neutral", + "seam": "xy", + "relativeLuminanceDifference": 0.05648728604634782, + "normalizedL1": 0.13380665807723602, + "passed": false + }, + { + "version": "optimized", + "lens": "eso1119b", + "seam": "xz", + "relativeLuminanceDifference": 0.005002309945527142, + "normalizedL1": 0.12007917840015177, + "passed": false + }, + { + "version": "optimized", + "lens": "eso1119b", + "seam": "yz", + "relativeLuminanceDifference": 0.0033750817084131296, + "normalizedL1": 0.11017354402412256, + "passed": false + }, + { + "version": "optimized", + "lens": "eso1119b", + "seam": "xy", + "relativeLuminanceDifference": 0.0128238570542583, + "normalizedL1": 0.1240519478966761, + "passed": false + }, + { + "version": "optimized", + "lens": "eso0844a", + "seam": "xz", + "relativeLuminanceDifference": 0.004756726423958046, + "normalizedL1": 0.1238774224552733, + "passed": false + }, + { + "version": "optimized", + "lens": "eso0844a", + "seam": "yz", + "relativeLuminanceDifference": 0.0034671649169563516, + "normalizedL1": 0.11369655642048106, + "passed": false + }, + { + "version": "optimized", + "lens": "eso0844a", + "seam": "xy", + "relativeLuminanceDifference": 0.012856416048208702, + "normalizedL1": 0.12853615472121113, + "passed": false + } + ], + "frontChanges": [ + { + "lens": "neutral", + "relativeLuminanceDifference": 0.011858627486820459, + "normalizedL1": 0.006356681438366735, + "passed": true + }, + { + "lens": "eso1119b", + "relativeLuminanceDifference": 0.011988540643949658, + "normalizedL1": 0.0064763183755192225, + "passed": true + }, + { + "lens": "eso0844a", + "relativeLuminanceDifference": 0.012053502422455805, + "normalizedL1": 0.0064513515253360205, + "passed": true + } + ], + "errors": [], + "failed": [] +} \ No newline at end of file diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/legacy-handoffs.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/legacy-handoffs.json new file mode 100644 index 0000000000..6bc18a3dd5 --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/legacy-handoffs.json @@ -0,0 +1,38 @@ +{ + "id": "412d070141ce5119bd773d7a1eec65f12f78fa36ced3f930aa4fc9491fa7bdca", + "errors": [], + "thresholds": { + "relativeLuminanceDifference": 0.05, + "normalizedL1": 0.04 + }, + "measurements": [ + { + "pixelated": false, + "seam": "xz", + "relativeLuminanceDifference": 0.007448274204638095, + "normalizedL1": 0.10579373570430688, + "passed": false + }, + { + "pixelated": false, + "seam": "yz", + "relativeLuminanceDifference": 0.0013473004012343357, + "normalizedL1": 0.09407192435762682, + "passed": false + }, + { + "pixelated": true, + "seam": "xz", + "relativeLuminanceDifference": 0.0008566774711162329, + "normalizedL1": 0.09625850191616052, + "passed": false + }, + { + "pixelated": true, + "seam": "yz", + "relativeLuminanceDifference": 0.00038089515411631034, + "normalizedL1": 0.08279774555926805, + "passed": false + } + ] +} \ No newline at end of file diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/numerical-alignment.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/numerical-alignment.json new file mode 100644 index 0000000000..190c15b7f5 --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/numerical-alignment.json @@ -0,0 +1,971 @@ +{ + "elapsedSeconds": 4.09, + "method": "Fixed full 800x700 canvas and all-pixel mask. RGB L1; unchanged source-total normalization before/after. Bilinear similarity, no gain fit. Bounded coordinate search at stride4; final RGB L1 evaluated over every pixel. Translation seeds: full +/-24px grid at4px intervals, stride8 objective, best3 seeds plus zero refined at stride4. Bounds +/-24px, scale .98..1.02, rotation +/-5deg; best sampled/local solution, not guaranteed global optimum.", + "syntheticControl": { + "appliedShift": [ + 3, + -2 + ], + "before": 0.18041813155996742, + "recovered": { + "parameters": [ + -3, + 2, + 1, + 0 + ], + "coarseL1": 0, + "normalizedL1": 0.000018555444647663342 + } + }, + "results": [ + { + "version": "old", + "lens": "neutral", + "seam": "xz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 350.0064266846449, + 355.77001760745884 + ], + "sigmaMajor": 95.03931091269595, + "sigmaMinor": 85.08985207205704, + "angleDegrees": -49.13066179906404, + "mass": 5286396 + }, + "b": { + "centroid": [ + 365.96897015545807, + 355.46853287210484 + ], + "sigmaMajor": 93.85082727018796, + "sigmaMinor": 84.03475232316816, + "angleDegrees": -49.96585334983239, + "mass": 5326066 + }, + "centroidDifference": [ + 15.96254347081316, + -0.3014847353539949 + ], + "majorScaleRatio": 0.9874948205001218, + "minorScaleRatio": 0.9876001694303642, + "angleDifferenceDegrees": -0.835191550768343, + "centroidCorrectionL1": 0.2360383458126251, + "before": 0.10579373570430688, + "translation": { + "parameters": [ + -0.25, + -0.25, + 1, + 0 + ], + "coarseL1": 0.10039465863927553, + "normalizedL1": 0.10049603711184078 + }, + "similarity": { + "parameters": [ + -0.25, + -0.25, + 1, + 0 + ], + "coarseL1": 0.10039465863927553, + "normalizedL1": 0.10049603711184078 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00100; not a statistical confidence interval", + "ranges": [ + [ + -0.25, + -0.25 + ], + [ + -0.25, + -0.25 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "old", + "lens": "neutral", + "seam": "yz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 397.6263259381392, + 401.8625538624582 + ], + "sigmaMajor": 93.46189701109002, + "sigmaMinor": 89.45292106956612, + "angleDegrees": -6.470208775133606, + "mass": 5582274 + }, + "b": { + "centroid": [ + 398.0670329250462, + 385.759743974307 + ], + "sigmaMajor": 93.17063280546337, + "sigmaMinor": 88.00766392314706, + "angleDegrees": -2.3133329166680996, + "mass": 5574753 + }, + "centroidDifference": [ + 0.44070698690700283, + -16.10280988815117 + ], + "majorScaleRatio": 0.9968836048171364, + "minorScaleRatio": 0.9838433767266795, + "angleDifferenceDegrees": 4.156875858465526, + "centroidCorrectionL1": 0.2159553706922375, + "before": 0.09407192435762682, + "translation": { + "parameters": [ + 0, + -0.25, + 1, + 0 + ], + "coarseL1": 0.0903434776196129, + "normalizedL1": 0.09131007749645134 + }, + "similarity": { + "parameters": [ + 0, + -0.25, + 1, + 0 + ], + "coarseL1": 0.0903434776196129, + "normalizedL1": 0.09131007749645134 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00100; not a statistical confidence interval", + "ranges": [ + [ + 0, + 0 + ], + [ + -0.25, + 0.25 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "old", + "lens": "eso1119b", + "seam": "xz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 349.6579603922409, + 355.9975415625327 + ], + "sigmaMajor": 92.83735052601119, + "sigmaMinor": 82.95231080126369, + "angleDegrees": -47.18861973337692, + "mass": 5179924.617399923 + }, + "b": { + "centroid": [ + 365.9382902285517, + 355.681207741813 + ], + "sigmaMajor": 91.64621130634593, + "sigmaMinor": 81.86899224156288, + "angleDegrees": -47.8909024819492, + "mass": 5219909.103199873 + }, + "centroidDifference": [ + 16.280329836310784, + -0.3163338207197057 + ], + "majorScaleRatio": 0.9871696120912937, + "minorScaleRatio": 0.9869404655610352, + "angleDifferenceDegrees": -0.7022827485722587, + "centroidCorrectionL1": 0.22106274205576107, + "before": 0.10335238699683513, + "translation": { + "parameters": [ + -0.25, + -0.25, + 1, + 0 + ], + "coarseL1": 0.09817370148743199, + "normalizedL1": 0.0982866508433419 + }, + "similarity": { + "parameters": [ + -0.25, + -0.25, + 1, + 0 + ], + "coarseL1": 0.09817370148743199, + "normalizedL1": 0.0982866508433419 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00100; not a statistical confidence interval", + "ranges": [ + [ + -0.25, + -0.25 + ], + [ + -0.25, + -0.25 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "old", + "lens": "eso1119b", + "seam": "yz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 397.45965795753074, + 402.3557215217105 + ], + "sigmaMajor": 91.34570467038505, + "sigmaMinor": 87.7182351448285, + "angleDegrees": -6.68938330459356, + "mass": 5477879.9439999135 + }, + "b": { + "centroid": [ + 397.89556064471844, + 385.9369599603437 + ], + "sigmaMajor": 91.03717999217143, + "sigmaMinor": 86.27358360005815, + "angleDegrees": -2.222860490476753, + "mass": 5470527.823199811 + }, + "centroidDifference": [ + 0.4359026871877063, + -16.418761561366807 + ], + "majorScaleRatio": 0.9966224500722075, + "minorScaleRatio": 0.9835307727933065, + "angleDifferenceDegrees": 4.466522814116786, + "centroidCorrectionL1": 0.20138040610872904, + "before": 0.09204724768477665, + "translation": { + "parameters": [ + 0, + -0.25, + 1, + 0 + ], + "coarseL1": 0.08868853908693972, + "normalizedL1": 0.0896051809063681 + }, + "similarity": { + "parameters": [ + 0, + -0.25, + 1, + 0 + ], + "coarseL1": 0.08868853908693972, + "normalizedL1": 0.0896051809063681 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00100; not a statistical confidence interval", + "ranges": [ + [ + 0, + 0 + ], + [ + -0.25, + 0.25 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "old", + "lens": "eso0844a", + "seam": "xz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 349.61037451321914, + 355.54182945265217 + ], + "sigmaMajor": 94.68134119726498, + "sigmaMinor": 84.61778784028618, + "angleDegrees": -49.43266501919921, + "mass": 5178017.786799854 + }, + "b": { + "centroid": [ + 365.92153688301556, + 355.23212867373866 + ], + "sigmaMajor": 93.4789893229741, + "sigmaMinor": 83.59166417112729, + "angleDegrees": -50.17179399392732, + "mass": 5217067.940599813 + }, + "centroidDifference": [ + 16.31116236979642, + -0.3097007789135091 + ], + "majorScaleRatio": 0.9873010684144637, + "minorScaleRatio": 0.9878734283257833, + "angleDifferenceDegrees": -0.7391289747280894, + "centroidCorrectionL1": 0.22806954301194038, + "before": 0.10509154123884833, + "translation": { + "parameters": [ + -0.25, + -0.25, + 1, + 0 + ], + "coarseL1": 0.09977830850583706, + "normalizedL1": 0.09989175625476641 + }, + "similarity": { + "parameters": [ + -0.25, + -0.25, + 1, + 0 + ], + "coarseL1": 0.09977830850583706, + "normalizedL1": 0.09989175625476641 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00100; not a statistical confidence interval", + "ranges": [ + [ + -0.25, + -0.25 + ], + [ + -0.25, + -0.25 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "old", + "lens": "eso0844a", + "seam": "yz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 397.30549349144434, + 401.8976439882904 + ], + "sigmaMajor": 93.04669263646544, + "sigmaMinor": 88.92915431085648, + "angleDegrees": -7.063430785311585, + "mass": 5475537.176799839 + }, + "b": { + "centroid": [ + 397.7515575402513, + 385.4760918111895 + ], + "sigmaMajor": 92.74870129014046, + "sigmaMinor": 87.42422249163049, + "angleDegrees": -3.1271862542095747, + "mass": 5468177.438199765 + }, + "centroidDifference": [ + 0.44606404880698847, + -16.421552177100864 + ], + "majorScaleRatio": 0.996797399908783, + "minorScaleRatio": 0.9830771828329165, + "angleDifferenceDegrees": 3.9362445311020338, + "centroidCorrectionL1": 0.20801594722105282, + "before": 0.0933923526990095, + "translation": { + "parameters": [ + 0, + -0.25, + 1, + 0 + ], + "coarseL1": 0.08987258031063923, + "normalizedL1": 0.09085101652838905 + }, + "similarity": { + "parameters": [ + 0, + -0.25, + 1, + 0 + ], + "coarseL1": 0.08987258031063923, + "normalizedL1": 0.09085101652838905 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00100; not a statistical confidence interval", + "ranges": [ + [ + 0, + 0 + ], + [ + -0.25, + 0.25 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "optimized", + "lens": "neutral", + "seam": "xz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 349.20568841566853, + 355.8665634667417 + ], + "sigmaMajor": 95.86688695680532, + "sigmaMinor": 86.1219703785479, + "angleDegrees": -46.32806453745209, + "mass": 5362407 + }, + "b": { + "centroid": [ + 366.3211416002387, + 355.84109150648 + ], + "sigmaMajor": 94.89264066554335, + "sigmaMinor": 85.31350767773863, + "angleDegrees": -47.566546227363844, + "mass": 5388296 + }, + "centroidDifference": [ + 17.115453184570185, + -0.0254719602617115 + ], + "majorScaleRatio": 0.9898375098828345, + "minorScaleRatio": 0.9906125847184443, + "angleDifferenceDegrees": -1.2384816899117368, + "centroidCorrectionL1": 0.24168684072871796, + "before": 0.12498652413707272, + "translation": { + "parameters": [ + -0.375, + -0.25, + 1, + 0 + ], + "coarseL1": 0.11905000328198519, + "normalizedL1": 0.11946323417175603 + }, + "similarity": { + "parameters": [ + -0.375, + -0.25, + 1, + 0 + ], + "coarseL1": 0.11905000328198519, + "normalizedL1": 0.11946323417175603 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00119; not a statistical confidence interval", + "ranges": [ + [ + -0.375, + -0.125 + ], + [ + -0.25, + -0.25 + ], + [ + 0.999, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "optimized", + "lens": "neutral", + "seam": "yz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 397.593091066362, + 402.96972849996547 + ], + "sigmaMajor": 94.12165459748606, + "sigmaMinor": 90.80739516665696, + "angleDegrees": -7.997224192515963, + "mass": 5657863 + }, + "b": { + "centroid": [ + 397.87827266566774, + 385.54498284225355 + ], + "sigmaMajor": 93.80367743434813, + "sigmaMinor": 89.5135194248101, + "angleDegrees": -4.50644955800141, + "mass": 5638561 + }, + "centroidDifference": [ + 0.2851815993057585, + -17.424745657711924 + ], + "majorScaleRatio": 0.9966216364927097, + "minorScaleRatio": 0.9857514276290797, + "angleDifferenceDegrees": 3.490774634514537, + "centroidCorrectionL1": 0.2175045113566766, + "before": 0.1146546907233652, + "translation": { + "parameters": [ + 0, + 0.25, + 1, + 0 + ], + "coarseL1": 0.11068049330845652, + "normalizedL1": 0.11165856557792095 + }, + "similarity": { + "parameters": [ + 0, + 0.25, + 1, + 0 + ], + "coarseL1": 0.11068049330845652, + "normalizedL1": 0.11165856557792095 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00111; not a statistical confidence interval", + "ranges": [ + [ + 0, + 0 + ], + [ + -0.25, + 0.25 + ], + [ + 0.999, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "optimized", + "lens": "eso1119b", + "seam": "xz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 348.8404264555682, + 356.10333499582697 + ], + "sigmaMajor": 93.75723106576999, + "sigmaMinor": 84.00601905091592, + "angleDegrees": -44.27316541086564, + "mass": 5255504.852999933 + }, + "b": { + "centroid": [ + 366.30404691009835, + 356.05381611125966 + ], + "sigmaMajor": 92.76745790081176, + "sigmaMinor": 83.20223999951726, + "angleDegrees": -45.40976432409586, + "mass": 5281926.687399859 + }, + "centroidDifference": [ + 17.463620454530144, + -0.04951888456730558 + ], + "majorScaleRatio": 0.9894432338315974, + "minorScaleRatio": 0.9904318873756951, + "angleDifferenceDegrees": -1.1365989132302161, + "centroidCorrectionL1": 0.2271038495502499, + "before": 0.12007917840015177, + "translation": { + "parameters": [ + -0.375, + -0.25, + 1, + 0 + ], + "coarseL1": 0.1143281767983957, + "normalizedL1": 0.11472831153466405 + }, + "similarity": { + "parameters": [ + -0.375, + -0.25, + 1, + 0 + ], + "coarseL1": 0.1143281767983957, + "normalizedL1": 0.11472831153466405 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00114; not a statistical confidence interval", + "ranges": [ + [ + -0.375, + -0.125 + ], + [ + -0.5, + -0.25 + ], + [ + 0.999, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "optimized", + "lens": "eso1119b", + "seam": "yz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 397.4228859654032, + 403.47034023025765 + ], + "sigmaMajor": 92.06082180564914, + "sigmaMinor": 89.1278788451523, + "angleDegrees": -8.631044334871223, + "mass": 5552954.807999948 + }, + "b": { + "centroid": [ + 397.7072989000036, + 385.7109977699769 + ], + "sigmaMajor": 91.72455513916269, + "sigmaMinor": 87.84865242187685, + "angleDegrees": -4.666154201828294, + "mass": 5534213.131799823 + }, + "centroidDifference": [ + 0.2844129346003683, + -17.75934246028072 + ], + "majorScaleRatio": 0.9963473423342195, + "minorScaleRatio": 0.9856472919601517, + "angleDifferenceDegrees": 3.9648901330429567, + "centroidCorrectionL1": 0.20529843801663494, + "before": 0.11017354402412256, + "translation": { + "parameters": [ + 0, + 0.25, + 1, + 0 + ], + "coarseL1": 0.10635553793655905, + "normalizedL1": 0.10727774901039394 + }, + "similarity": { + "parameters": [ + 0, + 0.25, + 1, + 0 + ], + "coarseL1": 0.10635553793655905, + "normalizedL1": 0.10727774901039394 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00106; not a statistical confidence interval", + "ranges": [ + [ + -0.25, + 0 + ], + [ + -0.25, + 0.5 + ], + [ + 0.999, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "optimized", + "lens": "eso0844a", + "seam": "xz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 348.79878913082865, + 355.64151066550767 + ], + "sigmaMajor": 95.52900388040025, + "sigmaMinor": 85.68414938489464, + "angleDegrees": -46.607260649380784, + "mass": 5253982.726199868 + }, + "b": { + "centroid": [ + 366.28982358738483, + 355.611838394766 + ], + "sigmaMajor": 94.5379945326683, + "sigmaMinor": 84.911656929135, + "angleDegrees": -47.7641435349224, + "mass": 5279093.931799817 + }, + "centroidDifference": [ + 17.49103445655618, + -0.02967227074168477 + ], + "majorScaleRatio": 0.9896260893814756, + "minorScaleRatio": 0.9909844182231466, + "angleDifferenceDegrees": -1.15688288554162, + "centroidCorrectionL1": 0.23421718262299918, + "before": 0.1238774224552733, + "translation": { + "parameters": [ + -0.375, + -0.25, + 1, + 0 + ], + "coarseL1": 0.1179593119169893, + "normalizedL1": 0.11840639066505237 + }, + "similarity": { + "parameters": [ + -0.375, + -0.25, + 1, + 0 + ], + "coarseL1": 0.1179593119169893, + "normalizedL1": 0.11840639066505237 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00118; not a statistical confidence interval", + "ranges": [ + [ + -0.375, + -0.125 + ], + [ + -0.5, + -0.25 + ], + [ + 0.999, + 1 + ], + [ + 0, + 0 + ] + ] + } + }, + { + "version": "optimized", + "lens": "eso0844a", + "seam": "yz", + "dimensions": [ + 800, + 700 + ], + "a": { + "centroid": [ + 397.2740654720268, + 403.0263849456587 + ], + "sigmaMajor": 93.72698785562304, + "sigmaMinor": 90.32004154546686, + "angleDegrees": -8.668017335961613, + "mass": 5551236.546599844 + }, + "b": { + "centroid": [ + 397.56666618733203, + 385.2579220114578 + ], + "sigmaMajor": 93.40694523774904, + "sigmaMinor": 88.96565536222752, + "angleDegrees": -5.419780461398684, + "mass": 5531989.493999747 + }, + "centroidDifference": [ + 0.292600715305241, + -17.768462934200898 + ], + "majorScaleRatio": 0.9965853739120798, + "minorScaleRatio": 0.9850045885712138, + "angleDifferenceDegrees": 3.248236874562906, + "centroidCorrectionL1": 0.2118471151705653, + "before": 0.11369655642048106, + "translation": { + "parameters": [ + 0, + 0.25, + 1, + 0 + ], + "coarseL1": 0.10979998550202132, + "normalizedL1": 0.1107583061021469 + }, + "similarity": { + "parameters": [ + 0, + 0.25, + 1, + 0 + ], + "coarseL1": 0.10979998550202132, + "normalizedL1": 0.1107583061021469 + }, + "uncertainty": { + "criterion": "conditional one-parameter cost <= optimum + 0.00110; not a statistical confidence interval", + "ranges": [ + [ + -0.25, + 0 + ], + [ + -0.25, + 0.5 + ], + [ + 0.999, + 1 + ], + [ + 0, + 0 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/oblique.png b/labs/nebula/models/omega-centauri/evidence/2026-09-20/oblique.png new file mode 100644 index 0000000000..6bc9f33ee4 Binary files /dev/null and b/labs/nebula/models/omega-centauri/evidence/2026-09-20/oblique.png differ diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/shape-moments.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/shape-moments.json new file mode 100644 index 0000000000..1aa6d727ae --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/shape-moments.json @@ -0,0 +1,271 @@ +{ + "note": "Luminosity-weighted second moments within retained smooth-envelope domain, not an observed isophotal axis ratio. Finite residuals outside this domain excluded; no browser compositing included.", + "results": [ + { + "grid": 96, + "bounds": { + "min": [ + -1650, + -1650, + -1445.7971390624998 + ], + "max": [ + 1650, + 1650, + 1445.7971390625007 + ] + }, + "prior": { + "center": [ + 1.560481538095193e-14, + -3.459767245096241e-15, + 2.3452126415096068e-14 + ], + "coordinateSigma": [ + 377.7350747251341, + 353.9585461091982, + 348.3259827365284 + ], + "principalSigma": [ + 378.57419469745133, + 373.12019227940203, + 326.7481147815035 + ], + "axisRatios": [ + 1, + 0.985593306425949, + 0.8631019212565025 + ], + "covariance": [ + [ + 142683.78667760265, + 3371.564463469337, + 2789.866912734906 + ], + [ + 3371.564463469337, + 125286.65236373738, + -15901.466353376338 + ], + [ + 2789.8669127349062, + -15901.46635337634, + 121330.99024936826 + ] + ] + }, + "envelope": { + "center": [ + 4.215612188306252, + -15.773196932554809, + 1.3678104890428269 + ], + "coordinateSigma": [ + 475.7979245365697, + 452.2548906928312, + 426.59283941627734 + ], + "principalSigma": [ + 477.94296305848906, + 469.3989965223332, + 405.13541923267104 + ], + "axisRatios": [ + 1, + 0.9821234599177261, + 0.8476647854381987 + ], + "covariance": [ + [ + 226383.6649933073, + 6329.240716223733, + 4288.49503992903 + ], + [ + 6329.240716223732, + 204534.48615558472, + -25979.367594674786 + ], + [ + 4288.495039929031, + -25979.36759467478, + 181981.45064124177 + ] + ] + }, + "full": { + "center": [ + 3.616111786215908, + -15.909294456611955, + -2.9470002101622432 + ], + "coordinateSigma": [ + 516.4717446767993, + 494.99507860693444, + 445.1480537164255 + ], + "principalSigma": [ + 519.7210945646997, + 503.3514750031591, + 431.79538800075034 + ], + "axisRatios": [ + 1, + 0.9685030687945211, + 0.8308213626818576 + ], + "covariance": [ + [ + 266743.06304949697, + 8870.224150909537, + 5515.008712836372 + ], + [ + 8870.224150909544, + 245020.1278450852, + -24936.234145604052 + ], + [ + 5515.00871283637, + -24936.234145604052, + 198156.78972752168 + ] + ] + }, + "envelopeLightFraction": 0.831805412682356 + }, + { + "grid": 144, + "bounds": { + "min": [ + -1650, + -1650, + -1445.7971390624998 + ], + "max": [ + 1650, + 1650, + 1445.7971390625007 + ] + }, + "prior": { + "center": [ + -1.0151363512695027e-14, + -1.1295333611857842e-14, + 8.495717172413022e-14 + ], + "coordinateSigma": [ + 377.73208386631586, + 353.95558098718703, + 348.3233577621448 + ], + "principalSigma": [ + 378.57119637029183, + 373.1172713079454, + 326.74545626089537 + ], + "axisRatios": [ + 1, + 0.9855933966592328, + 0.8631017346108283 + ], + "covariance": [ + [ + 142681.52718198948, + 3371.5211479747, + 2789.830771669299 + ], + [ + 3371.5211479747, + 125284.55331197711, + -15901.260233418061 + ], + [ + 2789.8307716693, + -15901.260233418065, + 121329.16156269511 + ] + ] + }, + "envelope": { + "center": [ + 4.205158445769136, + -15.795395375786287, + 1.3686883372312424 + ], + "coordinateSigma": [ + 475.80796862043405, + 452.3012411177898, + 426.59886607537175 + ], + "principalSigma": [ + 477.94468914209943, + 469.4394736931407, + 405.15636847488753 + ], + "axisRatios": [ + 1, + 0.982204603080274, + 0.8477055560594985 + ], + "covariance": [ + [ + 226393.22300270395, + 6311.296069270738, + 4289.195136480313 + ], + [ + 6311.296069270736, + 204576.412716693, + -25980.945410323246 + ], + [ + 4289.195136480313, + -25980.945410323246, + 181986.59253679294 + ] + ] + }, + "full": { + "center": [ + 6.868789125621971, + -12.58320475479186, + -1.9591667680681792 + ], + "coordinateSigma": [ + 521.304156851149, + 498.4532188336728, + 448.4064223227182 + ], + "principalSigma": [ + 521.810586326594, + 509.39762780082117, + 435.3271455866139 + ], + "axisRatios": [ + 1, + 0.9762117541287217, + 0.8342627708096145 + ], + "covariance": [ + [ + 271758.0239502873, + 3335.2962413424134, + 5210.7485504650795 + ], + [ + 3335.2962413424143, + 248455.61136564933, + -25486.045064795053 + ], + [ + 5210.748550465077, + -25486.045064795057, + 201068.3195802599 + ] + ] + }, + "envelopeLightFraction": 0.8283077726791853 + } + ] +} diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/side-x.png b/labs/nebula/models/omega-centauri/evidence/2026-09-20/side-x.png new file mode 100644 index 0000000000..7eadd856e0 Binary files /dev/null and b/labs/nebula/models/omega-centauri/evidence/2026-09-20/side-x.png differ diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/side-y.png b/labs/nebula/models/omega-centauri/evidence/2026-09-20/side-y.png new file mode 100644 index 0000000000..4a314d90db Binary files /dev/null and b/labs/nebula/models/omega-centauri/evidence/2026-09-20/side-y.png differ diff --git a/labs/nebula/models/omega-centauri/evidence/2026-09-20/validation.json b/labs/nebula/models/omega-centauri/evidence/2026-09-20/validation.json new file mode 100644 index 0000000000..6d2bc9f7ee --- /dev/null +++ b/labs/nebula/models/omega-centauri/evidence/2026-09-20/validation.json @@ -0,0 +1,429 @@ +{ + "testedBase": "ef1e8b067f8f7d23d4bf13ea065f02f1dec7f4ad", + "testedState": "Working tree with the source hashes below, not the base commit alone. Publication only updates documentation/evidence and excludes the unfinished app object and its source-catalogue entries.", + "reuse": "Published authored implementations exactly match the reviewed/tested source checkpoint. Documentation, images and retaining reports do not change their behavior. No native or compact Omega application delivery is claimed.", + "sourcePins": [ + { + "path": ".github/workflows/universe.yml", + "bytes": 36908, + "sha256": "6fab0b9cb34fecf7056fb2626abff3df0644c7400f476a69bac08662791402a6" + }, + { + "path": "labs/nebula/models/omega-centauri/candidates.json", + "bytes": 170, + "sha256": "be78206e67c31d36698c69818a383e922c48603cb157bbd31e8bcf824bb24240" + }, + { + "path": "labs/nebula/models/omega-centauri/compiler.json", + "bytes": 1361, + "sha256": "37c12a3be28a8dfbebb8931cd5f528673b63018c34aea8a4a07b23b26b6a1f3f" + }, + { + "path": "labs/nebula/models/omega-centauri/native-registration.json", + "bytes": 3895, + "sha256": "ef6e7213e2e95bb6f5ab7f1c9e080dce8ebc0e0d65f9897b239541feefab0b96" + }, + { + "path": "labs/nebula/models/omega-centauri/observation-structures.json", + "bytes": 397, + "sha256": "dc8dd69f0a7f1c15d8b6376e43147e3e2cd2c52ab802d7fc5651d23c28ae8c0e" + }, + { + "path": "labs/nebula/models/omega-centauri/observations.json", + "bytes": 3842, + "sha256": "5954f0098ffe25ad48ff22b581f6d47cbc67e7d902e5d1f5ac19822c0612b9c2" + }, + { + "path": "labs/nebula/models/omega-centauri/photometric-mge.json", + "bytes": 2508, + "sha256": "4e28dac4271eeafd77f77582cfd69105ca02677e6bbe6c88e583f412c7b27914" + }, + { + "path": "labs/nebula/models/omega-centauri/physical-evidence.json", + "bytes": 36711, + "sha256": "6e88b6abe042cb66a104931cf1039fb3e6d685dd308b303226bdb6e530ac5b51" + }, + { + "path": "labs/nebula/models/omega-centauri/verify-registration.mts", + "bytes": 6801, + "sha256": "1c3d9fd284944dedf2751204a193a5c05dc1cda00813e60a9e0c2ed1f0ded18b" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler-export.ts", + "bytes": 4190, + "sha256": "842bbf1dca3107a790a792cd5f4a93713f7a739a80e522f58d976953b3082c1c" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.test.ts", + "bytes": 5215, + "sha256": "e68540664c6863bb72a0516c04ca78e1171357cb85320102c87c051f0e171859" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.test.ts", + "bytes": 3549, + "sha256": "06bdb5db40ad175e8beda298d845460ff3a6bced3fccbfb6999cc1b1852b24f9" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/application/delivery/nebula-frame.test.ts", + "bytes": 6412, + "sha256": "1cc99841a584798d1cc860037211e99f4b05069abeda2806ad371dacc891be0e" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/viewer/compiler-renderer.ts", + "bytes": 1664, + "sha256": "a257b20d6272c9c1f7f6a4168e99cf97a74d18c4419c1e96babe93a5e238c852" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/viewer/shape-cloud-camera.test.ts", + "bytes": 9398, + "sha256": "f4fa9ada51112c39df61620d78250bd88ffee3ec87db789b1c3dadbfa54ab1ff" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/viewer/shape-cloud-renderer.ts", + "bytes": 1825, + "sha256": "a3d3d6397dcae176019c26a6ac81831ff981979b6f1dd54bfaa479191d73eb70" + }, + { + "path": "labs/nebula/packages/lab/src/adapters/viewer/volume-renderer.ts", + "bytes": 4657, + "sha256": "1ea073d746c166a2ba288e70f9ed28ca2659568b141a4d915d9f896d274d8bfb" + }, + { + "path": "labs/nebula/packages/lab/src/cli/commands/compile-candidates.ts", + "bytes": 9831, + "sha256": "5a17c30851c48282fa868a63103fd886dfe8c6e094055ccf11661371299269cb" + }, + { + "path": "labs/nebula/packages/lab/src/features/compiler/compiler-panel.tsx", + "bytes": 16860, + "sha256": "46503a20b65c49d6b8e95d2d87108bef82c1f8193b1a744a920b7e88d0c99233" + }, + { + "path": "labs/nebula/packages/lab/src/features/compiler/compiler-published.test.ts", + "bytes": 15744, + "sha256": "935df76c344d0ac162b8ebc09ccb628e6080ff515eab253ee24b6849d1c6acfc" + }, + { + "path": "labs/nebula/packages/lab/src/features/compiler/compiler-published.ts", + "bytes": 11622, + "sha256": "a393451facf57d091604e7f257580a4d5a546af5f13b6417509814676cfccebd" + }, + { + "path": "labs/nebula/packages/lab/src/features/compiler/model.ts", + "bytes": 9060, + "sha256": "53985ebe1a3ebe6e22a1044329dfac4f5c21515550b9b3332bc3dc899eb0fa40" + }, + { + "path": "labs/nebula/packages/lab/src/features/shape-cloud/shape-cloud-photo-pose.test.ts", + "bytes": 3652, + "sha256": "22fde1c27c62a73c0a4ff5ab386911feab7537c92a335233f4760e27dc707aeb" + }, + { + "path": "labs/nebula/packages/lab/src/features/shape-cloud/shape-cloud-photo-pose.ts", + "bytes": 2041, + "sha256": "18c23ab70cb082b88b7c17465c8c780be775df1cc44b7bf17d265b98f6f3a5a3" + }, + { + "path": "labs/nebula/packages/lab/src/features/shape-cloud/shape-cloud.css", + "bytes": 6350, + "sha256": "54407d03391fcbc71cc5f98a3f09f741e1e76ee3518e4f7d96eae401adc51321" + }, + { + "path": "labs/nebula/packages/lab/src/resources/model-catalogue.test.ts", + "bytes": 3569, + "sha256": "1966cacc164166ce3375713508ca08d2806712c0b5ae7b76b465966d0fd4bfb8" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/compiler/bake.test.ts", + "bytes": 5795, + "sha256": "78e91cab5b70cbfcea8a4bc3f49593436b653dad898710cc1f96c94358571e4b" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/compiler/compile.ts", + "bytes": 21267, + "sha256": "7b484fcb57e5752c91325d70fb2cb55e31419f8846345fad2289d646050b9fb9" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/compiler/compiler-defaults.test.ts", + "bytes": 3888, + "sha256": "f356421a5db71883e9e18fa2cd233752a69d3ad26211d64b1b2ecd9ec39afe00" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/compiler/photometric-prior.test.ts", + "bytes": 7965, + "sha256": "bfc52b540126d441e19db4c0f12f9fddbf0300f45b83ff32bd55357d6b394db1" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/compiler/photometric-prior.ts", + "bytes": 7847, + "sha256": "1c8fd7c75a48670a009553f84c7cedd167cf3f51d8119b688006d8e62ec03f46" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/compiler/refresh-stars.ts", + "bytes": 8252, + "sha256": "640c95efa09083f1a51f63afd4b938deec2663742f7ded90b42c8128421e3345" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/compiler/retained-material-bank.test.ts", + "bytes": 8530, + "sha256": "16c48b1151fdf6f69774cc3279c69dbd5afba08481bc122c1ef8b8be020cb4a0" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/observations/fixtures/omega-centauri-native-stars.json", + "bytes": 9021, + "sha256": "5c5e98214276619d95853fdead319f8eaec87b8cc086c24a3838818eec693037" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/observations/registration.test.ts", + "bytes": 7994, + "sha256": "252e8fb86c41007106abe9f1e3184d95f5291d7ce6f1d3dd84a08b5e9df06598" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/sampled-prior/compile.ts", + "bytes": 22136, + "sha256": "86279d10312c87d3368742a372125ee1131dc1b5b7e2a11318ce8a2f1d784fd7" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/sampled-prior/component-banks.test.ts", + "bytes": 6568, + "sha256": "304b44a663e059ac0bdff63148b96abb6a0db22f53702ea1435cf2deb0671d6c" + }, + { + "path": "labs/nebula/packages/lab/src/server/workflows/sampled-prior/layout.test.ts", + "bytes": 6904, + "sha256": "fc96c9bcb2a2427c6166fb38566b8a1b197f431a9f674b8c173f49d4308d37dc" + }, + { + "path": "labs/nebula/packages/lab/src/state/subjects.json", + "bytes": 22793, + "sha256": "2d6f6c42cafe75881a19f57fcdf24780495d12e2e68f881b2d26c797e7659284" + }, + { + "path": "labs/nebula/packages/reconstruction/package.json", + "bytes": 6818, + "sha256": "5fa80cc19bd82e22d7499982ec8006e9d6696f2a618a398c6a60b00ee15af33d" + }, + { + "path": "labs/nebula/packages/reconstruction/src/methods/inference/fit.ts", + "bytes": 19436, + "sha256": "67c2c671c6a3cc8f73f26ad99e142058f478477ed944e785fb68de0b6a4f6fb3" + }, + { + "path": "labs/nebula/packages/reconstruction/src/methods/inference/photometric-mge.test.ts", + "bytes": 5573, + "sha256": "a5819a1149c665c94083b3155abafa6f9a9c1050cd2c03a5312241c59f2ea600" + }, + { + "path": "labs/nebula/packages/reconstruction/src/methods/inference/photometric-mge.ts", + "bytes": 671, + "sha256": "13109dd3f1d28dd15c3d733f737753c15d0c85e3e2ae4e3e345226f6f9cfe430" + }, + { + "path": "labs/nebula/packages/reconstruction/src/methods/inference/simulation-guided.ts", + "bytes": 11533, + "sha256": "e9d509a5a0fe46621ffd3bd98c0f50188eaa49c49657a444a5de5394d18ea955" + }, + { + "path": "labs/nebula/packages/volume-bake/src/compact-inputs/compiler.ts", + "bytes": 8729, + "sha256": "a9c3ebe7c2e88a8b3c624be2c0fef4f00f0b3d6b011809646486e1a6f7c3085a" + }, + { + "path": "labs/nebula/packages/volume-bake/src/compact-inputs/sampled.ts", + "bytes": 11992, + "sha256": "1fcd2d1db257d0f7d7e45e04c9660373f5f019e9329d62e8a6f27d6e6834ea73" + }, + { + "path": "labs/nebula/packages/volume-bake/src/compiler/bake.ts", + "bytes": 18347, + "sha256": "61419c3023157f4666cfd23a9edafbf749c84c79bfefdcd165506c55f224c719" + }, + { + "path": "labs/nebula/packages/volume-bake/src/compiler/compiler-sampling.test.ts", + "bytes": 5318, + "sha256": "85b518a3644ca5dbf7a49a70aef754e76949fce610ecfe7ff6c0a9753dc8afff" + }, + { + "path": "labs/nebula/packages/volume-bake/src/compiler/component-layout.ts", + "bytes": 16703, + "sha256": "7466f8813cf5a2684e9633624bd6d811bb6de9e49ba9a1a3921d4b6e6450512d" + }, + { + "path": "labs/nebula/packages/volume-bake/src/compiler/retained-material.ts", + "bytes": 10547, + "sha256": "59756ab35b9fcc3e249977a36521d99ee38c9020666b3866d40e6464d0d5852c" + }, + { + "path": "labs/nebula/packages/volume-bake/src/slices/emission-layout.test.ts", + "bytes": 6642, + "sha256": "e38597b85ea59a2fef154660f9df07dfcc755dc5d23d61d3633324b4497b0696" + }, + { + "path": "labs/nebula/packages/volume-bake/src/slices/emission.ts", + "bytes": 21178, + "sha256": "febe3fc0821a0ca82a4c04d19c0771744cec20fa078bb75a82de3fef043869d7" + }, + { + "path": "labs/nebula/packages/volume-bake/src/slices/material.ts", + "bytes": 10360, + "sha256": "dcb0c1b4524eb77ed9547a369ce5a24ede9e298af1ed507e3cfb1e504f5aff96" + }, + { + "path": "labs/nebula/packages/volume-core/package.json", + "bytes": 4015, + "sha256": "5c82ed209bf29c8f3eefe61dd8cb0244d57d647a67fb94db10249dc09090a94e" + }, + { + "path": "labs/nebula/packages/volume-core/src/contracts/compiler-bake.ts", + "bytes": 12561, + "sha256": "2488b91bd967064028a552fd58593e3d26eddc77327e9377a4e0a0b5e1bdd3f6" + }, + { + "path": "labs/nebula/packages/volume-core/src/contracts/emission.ts", + "bytes": 4057, + "sha256": "712c11507af42b9f111f17ec0ceee9023a8eed29fac1700577bb88fe5cc47140" + }, + { + "path": "labs/nebula/packages/volume-core/src/contracts/volume-slices.ts", + "bytes": 6642, + "sha256": "5965a3ac2d6acef6d13ea625df2456960b9197fd4dcfccf7ea8b5b2ec452fda3" + }, + { + "path": "labs/nebula/packages/volume-core/src/coordinates/compiler-frame-layers.test.ts", + "bytes": 3892, + "sha256": "ac57880e7491ae0441b3b0bc67fe1c0a013fbea1177270bb10fe8d10426f9e4d" + }, + { + "path": "labs/nebula/packages/volume-core/src/coordinates/compiler-frame.ts", + "bytes": 3834, + "sha256": "e340a3eb8f6a374556aa4277cb3ee2064a1ebedd906a012e94f7921d2f4b4d3b" + }, + { + "path": "labs/nebula/packages/volume-core/src/fields/photometric-emission.ts", + "bytes": 5761, + "sha256": "af6e9cab101e246f3f840a122a5e4d08a7fce0e49600881a9486db46720ff9fb" + }, + { + "path": "labs/nebula/packages/volume-core/src/fields/photometric-mge.ts", + "bytes": 6744, + "sha256": "2865d5349871c0e9c3d18d677062e1c700afa55bc7b1b18ad385b4c748d02618" + }, + { + "path": "labs/nebula/packages/volume-core/src/fields/retained-emission.ts", + "bytes": 2784, + "sha256": "0b621e41516dbeb8b37da031dd6f07251ff0bf3498233653cbee81dc491d4f84" + }, + { + "path": "labs/nebula/packages/volume-core/src/fields/simulation-envelope.ts", + "bytes": 13256, + "sha256": "07c8b4c90ebc3cc46084cd607b2ea4ebfd95879cc2645ddc1988f85839a2733e" + }, + { + "path": "labs/nebula/packages/volume-core/src/materials/material.test.ts", + "bytes": 13125, + "sha256": "5b188f9f8c2d55567261747e3b534521dcfb6997010fe78ef6533ad75fc5e525" + }, + { + "path": "labs/nebula/packages/volume-core/src/materials/slab-material.ts", + "bytes": 13459, + "sha256": "f5aebe26a52df5e7fde3fbf404e2505d30f990cfaa4e0a2ecbfcdac0cdfbcda1" + }, + { + "path": "labs/nebula/packages/volume-core/src/sampling/layer-optimization.test.ts", + "bytes": 5946, + "sha256": "53286e81a79a6e4fc6863ad33bfe172240260c72c691c786c7701643e4c926d1" + }, + { + "path": "labs/nebula/packages/volume-core/src/sampling/layer-optimization.ts", + "bytes": 13031, + "sha256": "98c9ac63b39b4f1e8ff2fab6b3d6beb5423033fa4a5a9fe5048b54c862b4918b" + }, + { + "path": "packages/catalog/src/nebulae.test.ts", + "bytes": 3486, + "sha256": "3a38bb21caaeda12ff487d77fc58e376e14439b9cc7ceaf33d6a39104aa314af" + }, + { + "path": "packages/catalog/src/nebulae.ts", + "bytes": 4861, + "sha256": "5b6f5c2da9ba90a73a05e7080606d7ba213c9317976aa15043c00ec26ed70d99" + }, + { + "path": "site/prepared-focus-card.mts", + "bytes": 7880, + "sha256": "2041c07acc18088cda61b68d5ae0e02f318a1f1a799a49fe0d1bb009c8b8570c" + }, + { + "path": "site/prepared-focus-object.mts", + "bytes": 2334, + "sha256": "4ca6d397fe6bb700c6a221d059c72e5b03de30a5237debcbf51f3490a25ccfd0" + }, + { + "path": "site/test/galactic-focus.test.mts", + "bytes": 2309, + "sha256": "cab90564f2ab50aa0b5f40a45573570c57d2220bfe930e0e2b73cdeaa351b184" + }, + { + "path": "site/test/prepared-focus-card.test.mts", + "bytes": 9363, + "sha256": "8de40ffaa5d1dfb52287c551ab26e9db6a943cd04690321cc098976d5efbd3cd" + }, + { + "path": "src/renderers/css/universe/catalog-marker.test.ts", + "bytes": 2488, + "sha256": "743539f43896c9c5737ca6fbb7b0db934da1cbc8f75375710f5ea1d8438ace91" + }, + { + "path": "src/renderers/css/universe/catalog-marker.ts", + "bytes": 2390, + "sha256": "c2159ff0ed567d74ff614dd7e3b39b702af1c586a4ae73be73a18814846ff119" + }, + { + "path": "tools/nebula/application/nebula-frame.ts", + "bytes": 5029, + "sha256": "382e115799a417d2e09d1b43067dd31fadf2a32dc643b0e840195f39b14d8528" + }, + { + "path": "tools/nebula/application/objects.ts", + "bytes": 22751, + "sha256": "3f2b3939e80769a7285b8677271939954ecbeb36f689d5e08731100c8807796c" + }, + { + "path": "tools/prepare-navigation-destinations.mts", + "bytes": 4439, + "sha256": "d406c51f5b761134b39446f0d1935a22e5c8829913d520132385465974777671" + } + ], + "fullLabSuite": { + "command": "node labs/nebula/run.mts test", + "tests": 681, + "passed": 659, + "skipped": 17, + "failed": 5, + "failures": [ + "# Subtest: delivery restores missing impostors, rejects drift and rebuilds when their generator changes\nnot ok 32 - delivery restores missing impostors, rejects drift and rebuilds when their generator changes\n ---\n duration_ms: 289.361875\n type: 'test'\n location: '/private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-objects.test.mjs:14775:1'\n failureType: 'testCodeFailure'\n error: |-\n Cannot find module '@cssearth/volume-bake/package.json'\n Require stack:\n - /var/folders/hr/wf3y2_yx3xxdgk_j_0lfgt6r0000gn/T/nebula-impostor-delivery-WCZmfC/package.json\n code: 'MODULE_NOT_FOUND'\n stack: |-\n Function._resolveFilename (node:internal/modules/cjs/loader:1430:15)\n Function.resolve (node:internal/modules/helpers:157:19)\n packageImplementationPins (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-objects.test.mjs:3862:35)\n prepareNebulaObject (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-objects.test.mjs:8461:29)\n async TestContext. (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-objects.test.mjs:14779:20)\n async Test.run (node:internal/test_runner/test:1054:7)\n async Test.processPendingSubtests (node:internal/test_runner/test:744:7)\n ...", + "# Subtest: the curated lab retains the selected LMC images, SMC comparisons and verified density banks\nnot ok 179 - the curated lab retains the selected LMC images, SMC comparisons and verified density banks\n ---\n duration_ms: 7.521917\n type: 'test'\n location: '/private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/resources/model-catalogue.test.mjs:32:1'\n failureType: 'testCodeFailure'\n error: \"ENOENT: no such file or directory, open '/private/tmp/cssearth-pr390/labs/nebula/models/lmc/candidates/prepared/vista-infrared.webp'\"\n code: 'ENOENT'\n stack: |-\n async open (node:internal/fs/promises:639:25)\n async readFile (node:internal/fs/promises:1252:14)\n async TestContext. (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/resources/model-catalogue.test.mjs:54:19)\n async Test.run (node:internal/test_runner/test:1054:7)\n async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3)\n ...", + "# Subtest: tiny offline bake uses shared density support and writes pinned XYZ resources and cloud inspection\nnot ok 248 - tiny offline bake uses shared density support and writes pinned XYZ resources and cloud inspection\n ---\n duration_ms: 1265.759375\n type: 'test'\n location: '/private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workers/density-reconstruction.test.mjs:2743:1'\n failureType: 'testCodeFailure'\n error: \"ENOENT: no such file or directory, open '/private/tmp/cssearth-pr390/labs/nebula/models/lmc/full-density/prepared/slices/x/00.webp'\"\n code: 'ENOENT'\n stack: |-\n async open (node:internal/fs/promises:639:25)\n async readFile (node:internal/fs/promises:1252:14)\n async recolorCloudSlices (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workers/density-reconstruction.test.mjs:725:31)\n async prepareReconstruction (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workers/density-reconstruction.test.mjs:2537:19)\n async TestContext. (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workers/density-reconstruction.test.mjs:2783:20)\n async Test.run (node:internal/test_runner/test:1054:7)\n async Test.processPendingSubtests (node:internal/test_runner/test:744:7)\n ...", + "# Subtest: all 943 prepared stars come from pinned measured V rows and preserve independent sky rays and native footprint\nnot ok 523 - all 943 prepared stars come from pinned measured V rows and preserve independent sky rays and native footprint\n ---\n duration_ms: 12.315666\n type: 'test'\n location: '/private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4766:1'\n failureType: 'testCodeFailure'\n error: \"ENOENT: no such file or directory, open 'labs/nebula/models/lmc/clouds-observation/source/target.png'\"\n code: 'ENOENT'\n stack: |-\n async open (node:internal/fs/promises:639:25)\n async readFile (node:internal/fs/promises:1252:14)\n async pinned (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4570:17)\n async file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4587:111\n async Promise.all (index 7)\n async loadStarCloudModel (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4587:38)\n ...", + "# Subtest: joint CDF preserves solid-angle weighting and rejects missing cloud/density and true support gaps\nnot ok 524 - joint CDF preserves solid-angle weighting and rejects missing cloud/density and true support gaps\n ---\n duration_ms: 0.514292\n type: 'test'\n location: '/private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4830:1'\n failureType: 'testCodeFailure'\n error: \"ENOENT: no such file or directory, open 'labs/nebula/models/lmc/clouds-observation/source/target.png'\"\n code: 'ENOENT'\n stack: |-\n async open (node:internal/fs/promises:639:25)\n async readFile (node:internal/fs/promises:1252:14)\n async pinned (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4570:17)\n async file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4587:111\n async Promise.all (index 7)\n async loadStarCloudModel (file:///private/tmp/cssearth-pr390/.local/nebula-lab/compiled/labs/nebula/packages/lab/src/server/workflows/stars/lmc-stars.test.mjs:4587:38)\n ...\n# (node:10482) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 3)\n# (Use `node --trace-warnings ...` to show where the warning was created)" + ], + "comparisonToMain": "Not independently reproduced on current main; not claimed identical to main." + }, + "clean": [ + "Core/bake/Lab typechecks and all 203 strict Lab test-source files", + "Nebula package boundaries", + "Nebula Lab Vite production build", + "52 focused planner/integration regressions and 17 component-registration regressions", + "Budget, default-planning, interval-reflection, material-offset, secondary-lens and empty-partition mutation checks fail as intended", + "Historical no-plan manifest and PNG golden digest unchanged" + ], + "independentReview": "Grok subscription review packets cover planner, integration, grouped sampling, component registration and final cleanup. All completed with sentinels and source snapshots; code findings closed, rendered-quality failures remain open.", + "visualQualification": "FAILED: Omega X/Z and Y/Z normalized-L1 handoffs exceed 0.04; no threshold was raised.", + "omitted": [ + "Main-page Omega render and browser conformance", + "Cold Omega compact application replay", + "Omega R2 publication and clean asset restoration", + "Acceptance of the optimized Omega or Crab banks" + ], + "screenshots": "Four newly captured views illustrate the actual retained viewer. They are not before/after pixel comparisons; no Pixelmatch score is claimed." +} diff --git a/labs/nebula/models/omega-centauri/king-abel-derivation.mts b/labs/nebula/models/omega-centauri/king-abel-derivation.mts new file mode 100644 index 0000000000..da18b6bc1c --- /dev/null +++ b/labs/nebula/models/omega-centauri/king-abel-derivation.mts @@ -0,0 +1,129 @@ +// Derive a spherically symmetric 3D emissivity profile for Omega Centauri (NGC 5139) by +// Abel-inverting a single-mass King (1962) projected surface-density profile whose two shape +// parameters are fixed from measured/published-model structural radii (Baumgardt & Hilker 2018). +// +// This is a data-preparation script, not lab reconstruction code: it produces a small evidence +// table (radius, 3D emissivity) that a future baking capability would consume. All approximations +// used are stated explicitly and carried into physical-evidence.json. + +const rc = 4.54; // pc, measured 3D King core radius (Baumgardt & Hilker 2018 / Baumgardt et al. 2021) +const rh3D = 10.42; // pc, measured 3D half-mass radius (same source) + +// Approximation A (authored): treat the empirical King (1962) projected-profile core radius as +// equal to the measured 3D core radius. This is the standard simplification used when only 3D +// structural radii (not a separate photometric King fit) are available. +// +// Approximation B (published-model): projected half-light radius ~= 0.75 x 3D half-mass radius, +// a well known approximate relation for a broad family of dynamical models (Wolf et al. 2010; +// Spitzer 1987 discusses the same order-unity ratio). +const projectedHalfLightTarget = 0.75 * rh3D; // pc + +function sigmaShape(Rpc: number, q: number): number { + // King (1962) empirical surface-density shape (unnormalized): [ (1+x^2)^-1/2 - (1+q^2)^-1/2 ]^2 + const x = Rpc / rc; + if (x >= q) return 0; + const g = 1 / Math.sqrt(1 + q * q); + const f = 1 / Math.sqrt(1 + x * x) - g; + return f > 0 ? f * f : 0; +} + +function dSigmaShape_dR(Rpc: number, q: number): number { + const x = Rpc / rc; + if (x >= q) return 0; + const g = 1 / Math.sqrt(1 + q * q); + const inv = 1 / Math.sqrt(1 + x * x); + const f = inv - g; + if (f <= 0) return 0; + const dfdx = -x * inv * inv * inv; // d/dx (1+x^2)^-1/2 + const dfdR = dfdx / rc; + return 2 * f * dfdR; +} + +function projectedHalfLightRadius(q: number): number { + const rt = q * rc; + const N = 4000, dR = rt / N; + let cum = 0; + const cumArr = new Float64Array(N + 1); + for (let i = 0; i <= N; i++) { + const R = i * dR; + cumArr[i] = cum; + // trapezoid increment for next step (Simpson-lite via midpoint refinement) + const Rm = R + dR / 2; + const mid = Rm <= rt ? sigmaShape(Rm, q) * Rm : 0; + cum += mid * dR; // midpoint rule increment for integral of Sigma(R) * 2piR dR (2pi cancels in ratio) + } + const total = cum; + const target = total / 2; + for (let i = 0; i < N; i++) { + if (cumArr[i] <= target && cumArr[i + 1] >= target) { + const t = (target - cumArr[i]) / (cumArr[i + 1] - cumArr[i] || 1); + return (i + t) * dR; + } + } + return rt; +} + +// Solve for q = rt/rc via bisection so the projected half-light radius matches the target. +let lo = 1.05, hi = 60; +for (let iter = 0; iter < 80; iter++) { + const mid = (lo + hi) / 2; + const rHalf = projectedHalfLightRadius(mid); + if (rHalf < projectedHalfLightTarget) lo = mid; else hi = mid; +} +const q = (lo + hi) / 2; +const rt = q * rc; +const achievedHalf = projectedHalfLightRadius(q); +console.error(JSON.stringify({ q, concentrationLog10: Math.log10(q), rt_pc: rt, achievedProjectedHalfLight_pc: achievedHalf, targetProjectedHalfLight_pc: projectedHalfLightTarget })); + +// Abel inversion via the r^2+u^2 substitution: rho(r) = -(1/pi) * integral_0^sqrt(rt^2-r^2) Sigma'(R(u)) du +function rho(r: number): number { + if (r >= rt) return 0; + const uMax = Math.sqrt(rt * rt - r * r); + const N = 20000, du = uMax / N; + let acc = 0; + for (let i = 0; i < N; i++) { + const u = (i + 0.5) * du; + const R = Math.sqrt(r * r + u * u); + acc += (dSigmaShape_dR(R, q) / R) * du; + } + return -acc / Math.PI; +} + +function rhoN(r: number, N: number): number { + if (r >= rt) return 0; + const uMax = Math.sqrt(rt * rt - r * r), du = uMax / N; let acc = 0; + for (let i = 0; i < N; i++) { const u = (i + 0.5) * du; const R = Math.sqrt(r * r + u * u); acc += (dSigmaShape_dR(R, q) / R) * du; } + return -acc / Math.PI; +} +for (const N of [2000, 8000, 32000, 128000]) { + console.error('convergence N=', N, 'rho(0.01)=', rhoN(0.01, N), 'rho(0.5)=', rhoN(0.5, N), 'rho(1.16)=', rhoN(1.16, N), 'rho(2)=', rhoN(2, N), 'rho(4.54)=', rhoN(4.54, N), 'rho(10)=', rhoN(10, N)); +} + +const NR = 200; +const table = []; +let peak = 0; +for (let i = 0; i <= NR; i++) { + const r = (i / NR) * rt; + const v = Math.max(0, rho(r)); + peak = Math.max(peak, v); + table.push(v); +} +const normalized = table.map(v => v / peak); + +const output = { + schema: 'omega-centauri-king-abel-profile@1', + description: 'Spherically symmetric 3D relative emissivity vs radius, Abel-inverted from a single-mass King (1962) projected surface-density shape.', + parameters: { + coreRadiusPc: rc, halfMassRadiusPc3D: rh3D, projectedHalfLightTargetPc: projectedHalfLightTarget, + solvedConcentrationRtOverRc: q, solvedConcentrationLog10: Math.log10(q), tidalRadiusPc: rt, + achievedProjectedHalfLightPc: achievedHalf + }, + approximations: [ + 'A: projected (2D) King core radius set equal to the measured 3D core radius (authored simplification; no independent photometric King fit was located for this recipe).', + 'B: projected half-light radius = 0.75 x 3D half-mass radius (Wolf et al. 2010-type relation; published-model, not object-specific).' + ], + radialSamples: NR + 1, + radiusPc: Array.from({ length: NR + 1 }, (_, i) => (i / NR) * rt), + relativeEmissivity: normalized +}; +console.log(JSON.stringify(output)); diff --git a/labs/nebula/models/omega-centauri/king-abel-profile.json b/labs/nebula/models/omega-centauri/king-abel-profile.json new file mode 100644 index 0000000000..22222c661c --- /dev/null +++ b/labs/nebula/models/omega-centauri/king-abel-profile.json @@ -0,0 +1,430 @@ +{ + "schema": "cssearth-omega-centauri-king-abel-profile@1", + "evidenceId": "abel-inverted-emissivity", + "description": "Spherically symmetric 3D relative emissivity vs radius, Abel-inverted from a single-mass King (1962) projected surface-density shape.", + "derivation": "Single-mass King (1962) projected surface-density law, Sigma(R) = k[(1+(R/rc)^2)^-1/2 - (1+(rt/rc)^2)^-1/2]^2, deprojected via the standard Abel-inversion identity rho(r) = -(1/pi) * integral_r^rt (dSigma/dR) / sqrt(R^2-r^2) dR, evaluated numerically with a 20000-point midpoint quadrature per radius (verified convergent to 6+ significant figures against 2000/8000/32000/128000-point runs).", + "parameters": { + "coreRadiusPc": 4.54, + "halfMassRadiusPc3D": 10.42, + "projectedHalfLightTargetPc": 7.8149999999999995, + "solvedConcentrationRtOverRc": 10.221389884084143, + "solvedConcentrationLog10": 1.0095099543062203, + "tidalRadiusPc": 46.40511007374201, + "achievedProjectedHalfLightPc": 7.814999999999999 + }, + "approximations": [ + "A: projected (2D) King core radius set equal to the measured 3D core radius (authored simplification; no independent photometric King fit was located for this recipe).", + "B: projected half-light radius = 0.75 x 3D half-mass radius (Wolf et al. 2010-type relation; published-model, not object-specific)." + ], + "radialSamples": 201, + "units": { + "radiusPc": "parsec from cluster center", + "relativeEmissivity": "peak-normalized to 1 at r=0; unitless display light, not calibrated luminosity or density" + }, + "radiusPc": [ + 0, + 0.232026, + 0.464051, + 0.696077, + 0.928102, + 1.160128, + 1.392153, + 1.624179, + 1.856204, + 2.08823, + 2.320256, + 2.552281, + 2.784307, + 3.016332, + 3.248358, + 3.480383, + 3.712409, + 3.944434, + 4.17646, + 4.408485, + 4.640511, + 4.872537, + 5.104562, + 5.336588, + 5.568613, + 5.800639, + 6.032664, + 6.26469, + 6.496715, + 6.728741, + 6.960767, + 7.192792, + 7.424818, + 7.656843, + 7.888869, + 8.120894, + 8.35292, + 8.584945, + 8.816971, + 9.048996, + 9.281022, + 9.513048, + 9.745073, + 9.977099, + 10.209124, + 10.44115, + 10.673175, + 10.905201, + 11.137226, + 11.369252, + 11.601278, + 11.833303, + 12.065329, + 12.297354, + 12.52938, + 12.761405, + 12.993431, + 13.225456, + 13.457482, + 13.689507, + 13.921533, + 14.153559, + 14.385584, + 14.61761, + 14.849635, + 15.081661, + 15.313686, + 15.545712, + 15.777737, + 16.009763, + 16.241789, + 16.473814, + 16.70584, + 16.937865, + 17.169891, + 17.401916, + 17.633942, + 17.865967, + 18.097993, + 18.330018, + 18.562044, + 18.79407, + 19.026095, + 19.258121, + 19.490146, + 19.722172, + 19.954197, + 20.186223, + 20.418248, + 20.650274, + 20.8823, + 21.114325, + 21.346351, + 21.578376, + 21.810402, + 22.042427, + 22.274453, + 22.506478, + 22.738504, + 22.970529, + 23.202555, + 23.434581, + 23.666606, + 23.898632, + 24.130657, + 24.362683, + 24.594708, + 24.826734, + 25.058759, + 25.290785, + 25.522811, + 25.754836, + 25.986862, + 26.218887, + 26.450913, + 26.682938, + 26.914964, + 27.146989, + 27.379015, + 27.61104, + 27.843066, + 28.075092, + 28.307117, + 28.539143, + 28.771168, + 29.003194, + 29.235219, + 29.467245, + 29.69927, + 29.931296, + 30.163322, + 30.395347, + 30.627373, + 30.859398, + 31.091424, + 31.323449, + 31.555475, + 31.7875, + 32.019526, + 32.251552, + 32.483577, + 32.715603, + 32.947628, + 33.179654, + 33.411679, + 33.643705, + 33.87573, + 34.107756, + 34.339781, + 34.571807, + 34.803833, + 35.035858, + 35.267884, + 35.499909, + 35.731935, + 35.96396, + 36.195986, + 36.428011, + 36.660037, + 36.892063, + 37.124088, + 37.356114, + 37.588139, + 37.820165, + 38.05219, + 38.284216, + 38.516241, + 38.748267, + 38.980292, + 39.212318, + 39.444344, + 39.676369, + 39.908395, + 40.14042, + 40.372446, + 40.604471, + 40.836497, + 41.068522, + 41.300548, + 41.532574, + 41.764599, + 41.996625, + 42.22865, + 42.460676, + 42.692701, + 42.924727, + 43.156752, + 43.388778, + 43.620803, + 43.852829, + 44.084855, + 44.31688, + 44.548906, + 44.780931, + 45.012957, + 45.244982, + 45.477008, + 45.709033, + 45.941059, + 46.173085, + 46.40511 + ], + "relativeEmissivity": [ + 1, + 0.995912, + 0.983808, + 0.964158, + 0.937698, + 0.905366, + 0.868236, + 0.827436, + 0.784084, + 0.73923, + 0.693814, + 0.648643, + 0.604381, + 0.561547, + 0.520527, + 0.481589, + 0.444898, + 0.410537, + 0.378521, + 0.348816, + 0.321349, + 0.296021, + 0.272717, + 0.251313, + 0.231678, + 0.213683, + 0.197201, + 0.182111, + 0.168296, + 0.155649, + 0.144069, + 0.133462, + 0.123741, + 0.114828, + 0.106651, + 0.099143, + 0.092246, + 0.085903, + 0.080067, + 0.074691, + 0.069736, + 0.065164, + 0.060942, + 0.05704, + 0.053431, + 0.050089, + 0.046992, + 0.044119, + 0.041452, + 0.038974, + 0.03667, + 0.034526, + 0.032528, + 0.030666, + 0.028929, + 0.027307, + 0.025791, + 0.024373, + 0.023047, + 0.021804, + 0.02064, + 0.019548, + 0.018523, + 0.01756, + 0.016656, + 0.015805, + 0.015005, + 0.014251, + 0.013541, + 0.012872, + 0.01224, + 0.011644, + 0.011082, + 0.01055, + 0.010047, + 0.009572, + 0.009122, + 0.008696, + 0.008293, + 0.007911, + 0.007548, + 0.007204, + 0.006878, + 0.006568, + 0.006274, + 0.005994, + 0.005728, + 0.005476, + 0.005235, + 0.005006, + 0.004788, + 0.004581, + 0.004383, + 0.004195, + 0.004015, + 0.003844, + 0.00368, + 0.003524, + 0.003375, + 0.003233, + 0.003097, + 0.002967, + 0.002843, + 0.002724, + 0.002611, + 0.002502, + 0.002399, + 0.002299, + 0.002204, + 0.002113, + 0.002026, + 0.001942, + 0.001862, + 0.001786, + 0.001712, + 0.001642, + 0.001574, + 0.001509, + 0.001447, + 0.001387, + 0.00133, + 0.001275, + 0.001222, + 0.001172, + 0.001123, + 0.001077, + 0.001032, + 0.000989, + 0.000947, + 0.000908, + 0.000869, + 0.000833, + 0.000797, + 0.000763, + 0.000731, + 0.000699, + 0.000669, + 0.00064, + 0.000612, + 0.000586, + 0.00056, + 0.000535, + 0.000511, + 0.000488, + 0.000466, + 0.000445, + 0.000425, + 0.000405, + 0.000386, + 0.000368, + 0.000351, + 0.000334, + 0.000318, + 0.000302, + 0.000287, + 0.000273, + 0.000259, + 0.000246, + 0.000233, + 0.000221, + 0.000209, + 0.000198, + 0.000187, + 0.000177, + 0.000167, + 0.000157, + 0.000148, + 0.000139, + 0.00013, + 0.000122, + 0.000115, + 0.000107, + 0.0001, + 9.3e-05, + 8.7e-05, + 8e-05, + 7.4e-05, + 6.9e-05, + 6.3e-05, + 5.8e-05, + 5.3e-05, + 4.8e-05, + 4.4e-05, + 4e-05, + 3.6e-05, + 3.2e-05, + 2.8e-05, + 2.5e-05, + 2.2e-05, + 1.9e-05, + 1.6e-05, + 1.4e-05, + 1.1e-05, + 9e-06, + 7e-06, + 5e-06, + 4e-06, + 2e-06, + 1e-06, + 0.0, + 0 + ] +} \ No newline at end of file diff --git a/labs/nebula/models/omega-centauri/mge-method.md b/labs/nebula/models/omega-centauri/mge-method.md new file mode 100644 index 0000000000..a69ce3f711 --- /dev/null +++ b/labs/nebula/models/omega-centauri/mge-method.md @@ -0,0 +1,80 @@ +# Omega Centauri MGE prior + +[photometric-mge.json](photometric-mge.json) transcribes the eight projected Gaussian +components from [D’Souza & Rix (2013), Table 1](https://wwwmpa.mpa-garching.mpg.de/mpa/publications/preprints/pp2013/MPA3537.pdf). +The recipe pins both the complete source PDF bytes and [physical-evidence.json](physical-evidence.json). +The numerical extract is retained; the PDF remains a downloadable source, not a +committed artifact. [Shape evidence](shape-evidence.md) explains the selected and +competing measurements. + +## Transcription and units + +- Preserve the tabulated central amplitudes and projected axis ratios exactly. + Multiply every major-axis sigma in arcmin by60 to obtain `sigmaArcsec`. +- The table amplitudes are central projected surface brightness, confirmed by + [Watkins et al. (2013), Table 1](https://academic.oup.com/mnras/article/436/3/2598/1258888). + Do not apply another1/q correction. The sampler divides all amplitudes by their + sum; their relative weights remain fixed. +- Use angular coordinates in arcseconds throughout the depth sampler. For physical + interpretation, multiply by `distancePc × π/(180×3600)` to obtain parsecs. The + recipe's5426±47pc distance changes scale, not the observed angular shape or the + original paper's dynamical fit, which assumed5500±200pc. +- Use the observation recipe's ICRS center for every lens and the prior. This explicitly + re-centers the older radial model; it is not a new center measurement. + +## Oblate deprojection + +Let `q′` denote the projected minor/major ratio, `i` the inclination (0° face-on), +`σ` the major-axis width and `Σ₀` its relative projected central amplitude. Each +axisymmetric Gaussian has: + +```text +q² = (q′² − cos² i) / sin² i +ρ₀ = Σ₀ q′ / (√(2π) σ q) +ρ(R, z) = ρ₀ exp[−(R² + z²/q²) / (2σ²)] +``` + +Sum the eight components. Reject any inclination for which `q′² ≤ cos² i`; +never clamp an impossible intrinsic ratio. The most flattened component requires +`i > 43.603810°`. The selected50° follows the published model convention. + +The sky frame is **x west, y north, z away from Earth**. With major-axis PA measured +east of north and authored tilt sign `s=+1`, the unit symmetry axis is: + +```text +a = (sin i cos PA, sin i sin PA, s cos i) +zIntrinsic = dot(a, position) +R² = dot(position, position) − zIntrinsic² +``` + +The projected major axis is `(-sin PA, cos PA, 0)`. Reversing the line-of-sight tilt +produces the same projected ellipse; the image does not identify which pole is +nearer. The recipe records that choice instead of presenting it as a measurement. + +## Conditional image light and finite support + +The shared sampler truncates each component at ellipsoidal radius6σ. This authored +numerical bound is not a measured tidal radius. Geometry and relative density are +common to all image lenses. Preserve the images' integrated starlight and attach +image material to finite 3D emitters conditioned on this prior. + +The current candidate separates a smooth envelope from positive image residuals. +The envelope uses the MGE density at every depth, with a slowly varying gain fitted +at an 8-pixel Gaussian smoothing scale and authored fraction 0.95. Its floor is zero; +512 depth samples retain the central 99.6% of the image-weighted profile. Coarse +smoothed lens chromaticity colors only this envelope. Up to 4096 residual features +receive one conditional depth each and retain finite XYZ material; no full source +photograph is repeated through depth. These numerical settings are authored display +choices, not additional measurements of the cluster. + +The unchanged 512-pixel fit grid and minimum projected sigma of 0.9 fit pixels cannot +recover native stellar widths or all crowded core texture. Compact replay retains +the density, gain grid, coarse lens colors and finite supports explicitly. Actual +bake and byte-identical replay acceptance remain separate from analytic fit checks. + +The result remains relative display emission under a smooth axisymmetric hypothesis. +It does not supply measured member-star depths, population-specific mass segregation, +a calibrated luminosity field, an N-body simulation or a solution to central +counter-rotation. Source JSON and hash checks establish transcription and identity; +registration, actual baking, side-view inspection and promotion require separate +recorded results. diff --git a/labs/nebula/models/omega-centauri/native-registration.json b/labs/nebula/models/omega-centauri/native-registration.json new file mode 100644 index 0000000000..3d1eadf816 --- /dev/null +++ b/labs/nebula/models/omega-centauri/native-registration.json @@ -0,0 +1,141 @@ +{ + "schema": "cssearth-nebula-intake-registration-evidence@1", + "objectId": "omega-centauri", + "checkedAt": "2026-09-20", + "recipeSha256": "5954f0098ffe25ad48ff22b581f6d47cbc67e7d902e5d1f5ac19822c0612b9c2", + "implementationSha256": "bcd06a8e7432a0998cd97d6b52af5876a2edc06d5824ba9f6421fb1331cd799e", + "method": "Exact native AVM WCS; automatic reciprocal field-star constellations, unchanged RANSAC affine and spatial holdout gates. Full native source pixels, bounded 8000-pixel detection only.", + "source": { + "id": "eso0844a", + "sha256": "384d1cfc31e6a2b78e5c7018f9eaecfe49a1014630bcb1bd8dceb563d69e6429", + "width": 8040, + "height": 7560, + "avmSha256": "a440afd39241f5b40cb280e1a3ab511769265a55f8679baa75613f553940e1a5", + "wcs": { + "projection": "TAN", + "coordinateFrame": "ICRS", + "referenceDimension": [ + 1280, + 1204 + ], + "referencePixel": [ + 620.447024342, + 636.048276073 + ], + "referenceValueDeg": [ + 201.697148, + -47.479684 + ], + "scaleDeg": [ + -0.00041507559, + 0.00041507559 + ], + "rotationDeg": -0.00724264734 + } + }, + "reference": { + "id": "eso1119b", + "sha256": "8df2e2ad462b9dc5b7437320fb2c6fd247c11746b4b2ffd3da95846b9083cad6", + "width": 14540, + "height": 14540, + "avmSha256": "6bcf0b5435aca887af71e8aff3107a654256fc4aaded598bb1db5419176cdeed", + "wcs": { + "projection": "TAN", + "coordinateFrame": "ICRS", + "referenceDimension": [ + 1280, + 1280 + ], + "referencePixel": [ + 633.141898442, + 623.135269606 + ], + "referenceValueDeg": [ + 201.696944, + -47.479539 + ], + "scaleDeg": [ + -0.00066245096, + 0.00066245096 + ], + "rotationDeg": 0.00051173061 + } + }, + "frame": { + "width": 1024, + "height": 1024, + "fieldArcminutes": [ + 55, + 55 + ], + "centerIcrsDegrees": [ + 201.696958, + -47.479539 + ], + "northUp": true + }, + "matrix": [ + 0.07383525828742865, + 0.000005393267322909706, + -0.0000035586654012105534, + 0.07383019788173614, + 224.53043293244812, + 248.99021978406566 + ], + "pass": true, + "evidence": { + "status": "verified", + "matchedStars": 1899, + "trainingStars": 1266, + "trainingCandidates": 1266, + "rejectedTrainingStars": 0, + "heldOutStars": 633, + "rmsPixels": 0.030153681836255743, + "maxResidualPixels": 0.11949594972974975, + "spatialQuadrants": 4, + "coverageFraction": [ + 0.9982448067846028, + 0.99705661691466 + ], + "relativeScale": 1.000008976828227, + "centreShiftPixels": 0.4139475457539317, + "coverageDomain": { + "kind": "common-observed-footprint", + "sourcePixelPolygon": [ + [ + 8040.000000000001, + 0 + ], + [ + 8040, + 7560 + ], + [ + 0, + 7560 + ], + [ + 0, + 0 + ] + ] + }, + "residualArcseconds": 0.09717495123012104, + "interpretation": "Relative field-star alignment to the configured reference image; absolute sky scale and orientation remain publisher metadata. No stellar membership or physical depth." + }, + "controls": { + "recentredPublisherReferencePixel": { + "pass": false, + "centreShiftPixels": 18.618235441877836 + }, + "corruptedHeldOutIdentity": { + "pass": false, + "maxResidualPixels": 3.013336415623728 + } + }, + "fullReceipt": { + "path": "output/omega-centauri-registration/native-registration-full.json", + "sha256": "b6287c7a5d548903a47f7ac1c8687d1d359f395214c6fdf8a42576b88b9f07aa" + }, + "limits": "Relative alignment only; publisher absolute astrometry is not independently catalogue calibrated. WFI includes publisher-declared DSS gap fill. No depth, membership or photometric calibration is established." +} diff --git a/labs/nebula/models/omega-centauri/observation-structures.json b/labs/nebula/models/omega-centauri/observation-structures.json new file mode 100644 index 0000000000..7e205539d1 --- /dev/null +++ b/labs/nebula/models/omega-centauri/observation-structures.json @@ -0,0 +1,7 @@ +{ + "schema": "cssearth-observation-structure-recipe@1", + "observationRecipe": "labs/nebula/models/omega-centauri/observations.json", + "observationCatalogue": ".local/nebula-lab/observations/omega-centauri/observations.json", + "workingWidth": 768, + "wavelets": { "scales": 6, "significanceSigma": 2, "compactMaxScale": 1, "elongatedAxisRatio": 2.5, "minRegionPixels": 5, "connectivity": 8 } +} diff --git a/labs/nebula/models/omega-centauri/observations.json b/labs/nebula/models/omega-centauri/observations.json new file mode 100644 index 0000000000..9edd20d4f7 --- /dev/null +++ b/labs/nebula/models/omega-centauri/observations.json @@ -0,0 +1,79 @@ +{ + "schema": "cssearth-nebula-observation-recipe@1", + "id": "omega-centauri", + "referenceId": "eso1119b", + "frame": { + "width": 1024, + "height": 1024, + "fieldArcminutes": [55, 55], + "centerIcrsDegrees": [201.696958, -47.479539], + "northUp": true + }, + "nativeRemoval": { + "model": { + "path": ".local/open-star-removal/noxGeneratorColor.pb", + "sha256": "d54bdca728d1d6db0b3eef41d4187d327909d1ec5cd2a71485bfa9d7924ba546" + }, + "scriptSha256": "5db7c54230ba2032abb361cc2d59ef0e2e42114f27ef2036474c877058a6b752" + }, + "images": [ + { + "id": "eso1119b", + "label": "ESO VST/OmegaCAM · optical G/R/I", + "localCache": ".local/nebula-lab/source-originals/eso1119b.tif", + "url": "https://cdn.eso.org/images/original/eso1119b.tif", + "page": "https://www.eso.org/public/images/eso1119b/", + "sha256": "8df2e2ad462b9dc5b7437320fb2c6fd247c11746b4b2ffd3da95846b9083cad6", + "width": 14540, + "height": 14540, + "fieldArcminutes": [50.88, 50.88], + "centerIcrsDegrees": [201.69695833333333, -47.47953888888889], + "northRightDegrees": -0.00051173061, + "bands": "Optical G (480nm) / R (625nm) / I (770nm)", + "credit": "ESO/INAF-VST/OmegaCAM. Acknowledgement: A. Grado, L. Limatola/INAF-Capodimonte Observatory", + "termsUrl": "https://www.eso.org/public/outreach/copyright/", + "registrationMode": "field-stars", + "registrationDetection": { "sourceMaximum": 8000, "referenceMaximum": 8000, "maximumStars": 12000 }, + "stellarTreatment": "preserve", + "wcs": { + "projection": "TAN", + "coordinateFrame": "ICRS", + "referenceDimension": [1280, 1280], + "referencePixel": [633.141898442, 623.135269606], + "referenceValueDeg": [201.696944, -47.479539], + "scaleDeg": [-0.00066245096, 0.00066245096], + "rotationDeg": 0.00051173061 + }, + "metadataNote": "Exact embedded AVM WCS from the hash-pinned native TIFF, including its 1280-pixel reference grid and noncentral reference pixel. The AVM sky reference is not the raster centre. Native 14540x14540; the ignored derivative is an 8192px WebP. Relative alignment is tested against WFI; absolute astrometry remains publisher metadata." + }, + { + "id": "eso0844a", + "label": "ESO 2.2m MPG/WFI · optical B/V/I", + "localCache": ".local/nebula-lab/source-originals/eso0844a.tif", + "url": "https://cdn.eso.org/images/original/eso0844a.tif", + "page": "https://www.eso.org/public/images/eso0844a/", + "sha256": "384d1cfc31e6a2b78e5c7018f9eaecfe49a1014630bcb1bd8dceb563d69e6429", + "width": 8040, + "height": 7560, + "fieldArcminutes": [31.88, 29.99], + "centerIcrsDegrees": [201.69716666666667, -47.479683333333334], + "northRightDegrees": 0.00724264734, + "bands": "Optical B (451nm) / V (539nm) / I (783nm)", + "credit": "ESO", + "termsUrl": "https://www.eso.org/public/outreach/copyright/", + "registrationMode": "field-stars", + "registrationDetection": { "sourceMaximum": 8000, "referenceMaximum": 8000, "maximumStars": 12000 }, + "stellarTreatment": "preserve", + "wcs": { + "projection": "TAN", + "coordinateFrame": "ICRS", + "referenceDimension": [1280, 1204], + "referencePixel": [620.447024342, 636.048276073], + "referenceValueDeg": [201.697148, -47.479684], + "scaleDeg": [-0.00041507559, 0.00041507559], + "rotationDeg": -0.00724264734 + }, + "metadataNote": "Exact embedded AVM WCS from the hash-pinned native TIFF, including its 1280x1204 reference grid and noncentral reference pixel. Independent telescope/instrument/epoch from VST/OmegaCAM. Publisher notes Digitized Sky Survey data fills some gaps in this mosaic; DSS-filled regions are not independently attributed star detections." + } + ] +} diff --git a/labs/nebula/models/omega-centauri/photometric-mge.json b/labs/nebula/models/omega-centauri/photometric-mge.json new file mode 100644 index 0000000000..22a4e749c4 --- /dev/null +++ b/labs/nebula/models/omega-centauri/photometric-mge.json @@ -0,0 +1,76 @@ +{ + "schema": "cssearth-photometric-mge@1", + "id": "omega-centauri", + "centerIcrsDegrees": [ + 201.696958, + -47.479539 + ], + "distancePc": 5426, + "positionAngleEastOfNorthDegrees": 100, + "inclinationDegrees": 50, + "lineOfSightTiltSign": 1, + "cutoffSigma": 6, + "gaussians": [ + { + "centralAmplitude": 1290.195, + "sigmaArcsec": 28.5342, + "projectedAxisRatio": 1 + }, + { + "centralAmplitude": 4662.587, + "sigmaArcsec": 115.88586, + "projectedAxisRatio": 0.9991714 + }, + { + "centralAmplitude": 2637.784, + "sigmaArcsec": 150.8031, + "projectedAxisRatio": 0.7799464 + }, + { + "centralAmplitude": 759.8591, + "sigmaArcsec": 212.20356, + "projectedAxisRatio": 0.724126 + }, + { + "centralAmplitude": 976.0853, + "sigmaArcsec": 324.22368, + "projectedAxisRatio": 0.8556435 + }, + { + "centralAmplitude": 195.4156, + "sigmaArcsec": 538.98336, + "projectedAxisRatio": 0.9392021 + }, + { + "centralAmplitude": 38.40327, + "sigmaArcsec": 836.175, + "projectedAxisRatio": 0.9555874 + }, + { + "centralAmplitude": 8.387379, + "sigmaArcsec": 1258.9254, + "projectedAxisRatio": 1 + } + ], + "evidence": { + "path": "labs/nebula/models/omega-centauri/physical-evidence.json", + "sha256": "6e88b6abe042cb66a104931cf1039fb3e6d685dd308b303226bdb6e530ac5b51" + }, + "source": { + "url": "https://wwwmpa.mpa-garching.mpg.de/mpa/publications/preprints/pp2013/MPA3537.pdf", + "sha256": "5701eed16944eb96e0d3e8dea258f909e99a1fa4a5a0305581e878909e70db92", + "locator": "D\u2019Souza & Rix2013, Table1, manuscript page12 (PDF page12), eight projected MGE components; arcmin dispersions multiplied by60." + }, + "interpretation": "Published oblate MGE conditioned integrated starlight, interpreted as relative display light. Inclination50 degrees and PA100 degrees follow the selected literature model; the near/far tilt sign and six-sigma cutoff are authored. Gaussian widths retain their published angular scale at adopted distance5426pc and the common observation center. This is not measured star-by-star depth, calibrated luminosity, an N-body simulation or a completed bake/registration acceptance.", + "envelope": { + "scalePixels": 8, + "fraction": 0.95, + "floor": 0, + "depthSamples": 512, + "depthTrim": 0.002, + "chromaHalfSaturationQuantile": 0.5, + "chromaSkyQuantile": 0.1, + "chromaCoverageTaper": 0.5 + }, + "residualMaximumComponents": 4096 +} diff --git a/labs/nebula/models/omega-centauri/physical-evidence.json b/labs/nebula/models/omega-centauri/physical-evidence.json new file mode 100644 index 0000000000..b7cb1cb954 --- /dev/null +++ b/labs/nebula/models/omega-centauri/physical-evidence.json @@ -0,0 +1,697 @@ +{ + "schema": "cssearth-nebula-physical-evidence@1", + "subjectId": "omega-centauri", + "asOf": "2026-09-20", + "status": "Published photometric and dynamical constraints for a conditional oblate integrated-starlight model. The historical King approximation is rejected; runtime acceptance belongs to the delivered object evidence.", + "parameterClasses": { + "observed": "measured observable or metadata", + "published-model": "conditional literature inference, including a value we derived from measured inputs via a standard, non-object-specific mathematical relation", + "authored": "our transport, display, or approximation choice" + }, + "coordinateRule": "Common tangent frame: x west, y north, z away from Earth; centered on the SIMBAD/publisher-agreed cluster center.", + "sources": [ + { + "id": "baumgardt-hilker-2018", + "title": "A catalogue of masses, structural parameters, and velocity dispersion profiles of 112 Milky Way globular clusters", + "url": "https://doi.org/10.1093/mnras/sty1057", + "locator": "NGC 5139 row: core radius, half-mass radius, total mass, M/L, central velocity dispersion", + "access": "Cited from the task brief and cross-referenced against the author's public globular-cluster parameter tables (https://people.smp.uq.edu.au/HolgerBaumgardt/globular/); the paper PDF itself was not downloaded in this session, so its exact table values are not independently re-derived here." + }, + { + "id": "baumgardt-2021-distances", + "title": "Baumgardt et al. (2021) globular cluster distances", + "url": "https://people.smp.uq.edu.au/HolgerBaumgardt/globular/", + "locator": "NGC 5139 distance entry", + "access": "Cited from the task brief; not independently re-fetched in this session." + }, + { + "id": "simbad-ngc5139", + "title": "SIMBAD astronomical database, NGC 5139", + "url": "https://simbad.cds.unistra.fr/simbad/sim-id?Ident=NGC+5139", + "locator": "J2000 ICRS coordinates, reference 2010AJ....140.1830G", + "access": "Fetched live in this session; RA 13:26:47.28, Dec -47:28:46.1." + }, + { + "id": "eso1119b-publisher", + "title": "ESO/INAF-VST OmegaCAM image eso1119b", + "url": "https://www.eso.org/public/images/eso1119b/", + "locator": "Field of view, pixel scale, pointing center, orientation", + "access": "Fetched live in this session; pointing center RA 13:26:47.27, Dec -47:28:46.34; 50.88 x 50.88 arcmin; north 0.0 degrees left of vertical; already acquired/hash-pinned per labs/nebula/sources/reference-images.json (id eso1119b)." + }, + { + "id": "white-shawl-1987", + "title": "White & Shawl 1987, ellipticities of Galactic globular clusters", + "url": "https://ui.adsabs.harvard.edu/abs/1987ApJ...317..246W", + "locator": "Omega Centauri flattening measurement", + "access": "Cited from the task brief and corroborated by secondary literature search in this session; the paper PDF was not downloaded, and published ellipticity for Omega Cen varies with radius across the literature (roughly 0.08 in the core to ~0.17-0.19 in the outskirts)." + }, + { + "id": "king-1962", + "title": "King 1962, The structure of star clusters I: an empirical density law", + "url": "https://ui.adsabs.harvard.edu/abs/1962AJ.....67..471K", + "locator": "Empirical projected surface-density formula used as the profile family", + "access": "Standard, widely reproduced closed-form formula; used from memory, not refetched." + }, + { + "id": "wolf-2010", + "title": "Wolf et al. 2010, accurate masses for dispersion-supported galaxies", + "url": "https://doi.org/10.1111/j.1365-2966.2009.15708.x", + "locator": "Approximate relation between projected half-light radius and 3D half-mass radius for a broad family of density profiles", + "access": "Cited from general knowledge of the standard result, not refetched; used here only to fix one shape parameter, see evidence id projected-half-light-approx." + }, + { + "id": "van-de-ven-2006-structure", + "title": "van de Ven, van den Bosch, Verolme & de Zeeuw (2006), The dynamical distance and intrinsic structure of the globular cluster omega Centauri", + "url": "https://doi.org/10.1051/0004-6361:20053061", + "locator": "A&A 445, 513-543; arXiv:astro-ph/0509228. Axisymmetric Schwarzschild orbit-superposition dynamical model combining line-of-sight velocities and internal proper motions.", + "access": "Full arXiv PDF downloaded and sections 2.3.3, 2.3.4 and 7.1 inspected on 2026-09-20; photometric major-axis PA100 degrees and coordinate convention confirmed.", + "download": { + "url": "https://arxiv.org/pdf/astro-ph/0509228", + "bytes": 1253405, + "sha256": "091115f8b04cf247f0d8ca04e7a6a5840fab8daa24f427168b6451fb37c13dd6" + } + }, + { + "id": "reijns-2006-radial-velocities", + "title": "Reijns, Seitzer, Arnold, Freeman, Ingerson, van den Bosch, van de Ven & de Zeeuw (2006), Radial velocities in the globular cluster omega Centauri", + "url": "https://arxiv.org/abs/astro-ph/0509227", + "locator": "A&A 445, 503-511. 2756 radial velocities for 1966 stars (1589 members), ARGUS/CTIO 4m.", + "access": "Abstract fetched live in this session." + }, + { + "id": "haberle-2024-omegacat2", + "title": "Haberle, Neumayer, Bellini, Libralato et al. (2024), oMEGACat II: Photometry and proper motions for 1.4 million stars in Omega Centauri and its rotation in the plane of the sky", + "url": "https://arxiv.org/html/2404.03722v2", + "locator": "Accepted v2, section 8.2: kinematic PA104 +/-1 degree and inclination43.9 +/-1.3 degrees.", + "access": "Full accepted-v2 HTML retrieved on 2026-09-20; section8.2 inspected.", + "download": { + "bytes": 740755, + "sha256": "9e46c2738830485c2f0eec0f7bde39654434a02a03a1d445010f2c37531b73c9" + } + }, + { + "id": "bianchini-2013-flattening", + "title": "Bianchini, Varri, Bertin & Zocchi (2013), The flattening of globular clusters: internal rotation or velocity anisotropy?", + "url": "https://arxiv.org/abs/1302.0717", + "locator": "Axisymmetric rotating-anisotropic dynamical models applied to omega Centauri and 47 Tucanae.", + "access": "Abstract fetched live in this session." + }, + { + "id": "pechetti-2024-muse-core", + "title": "Pechetti, Kamann, Krajnovic, Seth, van de Ven, Neumayer, Dreizler, Weilbacher, Martens & Wragg (2024), omega Centauri: a MUSE discovery of a counter-rotating core", + "url": "https://doi.org/10.1093/mnras/stae294", + "locator": "MNRAS 528, 4941-4957; arXiv:2401.15149.", + "access": "Abstract and title confirmed via live search in this session; not independently fetched in full." + }, + { + "id": "trager-king-djorgovski-1995", + "title": "Trager, King & Djorgovski (1995), Catalogue of Galactic globular-cluster surface-brightness profiles", + "url": "https://ui.adsabs.harvard.edu/abs/1995AJ....109..218T", + "locator": "AJ 109, 218. Compiled surface-brightness profiles and King-model concentrations for 125 Milky Way globular clusters, including NGC 5139.", + "access": "Confirmed to exist and to cover this method via live search in this session; the specific NGC 5139 numeric table row (central surface brightness, concentration c, core radius) was not retrieved from the primary table itself." + }, + { + "id": "mclaughlin-vandermarel-2005", + "title": "McLaughlin & van der Marel (2005), Resolved massive star clusters in the Milky Way and its satellites: brightness profiles and a catalogue of fundamental parameters", + "url": "https://arxiv.org/abs/astro-ph/0605132", + "locator": "CDS J/ApJS/161/304 Table10, NGC5139 rows229-231; Table11 derived structural radii.", + "access": "Complete CDS ReadMe, table10.dat and table11.dat downloaded on 2026-09-20. NGC5139 rows decoded using the archive byte-column definitions. Wilson and King(1966) fits use54 points; they are not the empirical King(1962) law.", + "tables": [ + { + "url": "https://cdsarc.cds.unistra.fr/ftp/J/ApJS/161/304/ReadMe", + "bytes": 27936, + "sha256": "48b6e46ffeceb668e3cb108a1ffd8723df2382e0a07a6174260e199354e757b5" + }, + { + "url": "https://cdsarc.cds.unistra.fr/ftp/J/ApJS/161/304/table10.dat", + "bytes": 75735, + "sha256": "536b829f310535759f572dd781f2c9d7cec602999d53f07c2bce9b0638f9abf1" + }, + { + "url": "https://cdsarc.cds.unistra.fr/ftp/J/ApJS/161/304/table11.dat", + "bytes": 84456, + "sha256": "8707d3e19c864e058138bd7d0132ec06c97521a06ac4051132b3f7c149260a2d" + } + ] + }, + { + "id": "noyola-gebhardt-bergmann-2008", + "title": "Noyola, Gebhardt & Bergmann (2008), Gemini and Hubble Space Telescope evidence for an intermediate-mass black hole in omega Centauri", + "url": "https://arxiv.org/abs/0801.2782", + "locator": "ApJ 676, 1008. HST ACS integrated-light surface-brightness profile of the cluster center.", + "access": "Confirmed via live search in this session; central cusp slope value taken from search summary of the paper, not from a direct fetch of the paper text." + }, + { + "id": "baumgardt-vasiliev-2021-paper", + "title": "Baumgardt & Vasiliev (2021), Accurate distances to Galactic globular clusters through a combination of Gaia EDR3, HST, and literature data", + "url": "https://doi.org/10.1093/mnras/stab1474", + "locator": "Primary article distance table, NGC5139 row, combined-distance column:5.426 +0.047/-0.047 kpc.", + "access": "Primary article table inspected directly on 2026-09-20 at https://academic.oup.com/mnras/article/505/4/5957/6283731; exact distance and both uncertainty bounds confirmed." + }, + { + "id": "merritt-1997", + "title": "Merritt, Meylan & Mayor (1997), The stellar dynamics of omega Centauri", + "url": "https://ui.adsabs.harvard.edu/abs/1997AJ....114.1074M", + "locator": "AJ 114, 1074. Early line-of-sight rotation-curve measurement.", + "access": "Confirmed via live search in this session; peak rotation value taken from search summary, not from a direct fetch of the paper text." + }, + { + "id": "dsouza-rix-2013-mge", + "title": "D’Souza & Rix (2013), Mass estimates from stellar proper motions: the mass of omega Centauri", + "url": "https://doi.org/10.1093/mnras/sts426", + "locator": "Section4.3 and Table1, manuscript page12: eight Gaussian fit to Ferraro2006 number-density and Geyer1983 flattening profiles.", + "access": "Complete author-hosted PDF downloaded and table transcribed on2026-09-20; all eight rows cross-checked against Watkins2013 Table1. Coefficient error bars/covariance are not supplied in the table.", + "download": { + "url": "https://wwwmpa.mpa-garching.mpg.de/mpa/publications/preprints/pp2013/MPA3537.pdf", + "bytes": 480080, + "sha256": "5701eed16944eb96e0d3e8dea258f909e99a1fa4a5a0305581e878909e70db92" + } + }, + { + "id": "watkins-2013-mge-reuse", + "title": "Watkins, van de Ven, den Brok & van den Bosch (2013), Discrete dynamical models of omega Centauri", + "url": "https://academic.oup.com/mnras/article/436/3/2598/1258888", + "locator": "Section4.1 and Table1; central brightness in solar luminosities/pc2, sigma along the major axis in arcmin, projected flattening.", + "access": "Primary article table inspected on2026-09-20. Exact same eight MGE rows; caption resolves amplitude semantics. PA-80 degrees equals100 degrees for the undirected major axis; their signed rotation coefficients are not used here." + } + ], + "evidence": [ + { + "id": "distance", + "classification": "observed", + "sourceIds": [ + "baumgardt-vasiliev-2021-paper" + ], + "quantity": "heliocentric distance", + "value": { + "distancePc": 5426, + "uncertaintyPc": 47 + }, + "unit": "pc", + "scope": "Whole cluster", + "limitations": "Adopted angular-to-physical scale from the combined Gaia EDR3, HST and literature distance. Earlier rounded5430 +/-50pc is retained in historical King evidence; changing distance does not refit the published MGE angular shape or establish a dynamical mass." + }, + { + "id": "total-mass", + "classification": "published-model", + "sourceIds": [ + "baumgardt-hilker-2018" + ], + "quantity": "total dynamical mass", + "value": { + "massSolar": 3940000.0 + }, + "unit": "solar masses", + "scope": "Whole cluster", + "limitations": "N-body/dynamical-model mass, not directly used by the light-emissivity profile in this recipe; recorded for completeness and for the mass-segregation limitation below." + }, + { + "id": "half-mass-radius", + "classification": "published-model", + "sourceIds": [ + "baumgardt-hilker-2018" + ], + "quantity": "3D half-mass radius", + "value": { + "radiusPc": 10.42 + }, + "unit": "pc", + "scope": "Whole cluster, dynamical model fit", + "limitations": "A 3D dynamical mass radius, not a projected light radius. The historical King-Abel conversion to a light radius is rejected for the selected MGE; mass segregation prevents treating the two as interchangeable." + }, + { + "id": "core-radius", + "classification": "published-model", + "sourceIds": [ + "baumgardt-hilker-2018" + ], + "quantity": "3D King core radius", + "value": { + "radiusPc": 4.54 + }, + "unit": "pc", + "scope": "Whole cluster, dynamical model fit", + "limitations": "Historical King-Abel experiment set this 3D dynamical core radius equal to a projected King radius. That substitution is rejected for the selected MGE recipe; this value is retained as historical context only." + }, + { + "id": "mass-to-light", + "classification": "observed", + "sourceIds": [ + "baumgardt-hilker-2018" + ], + "quantity": "V-band mass-to-light ratio", + "value": { + "mOverLvSolar": 2.8, + "uncertainty": 0.1 + }, + "unit": "Msun/Lsun (V)", + "scope": "Whole cluster", + "limitations": "Recorded for completeness; not used to scale the recipe's relative emissivity, which is unitless display light, not calibrated luminosity." + }, + { + "id": "central-velocity-dispersion", + "classification": "observed", + "sourceIds": [ + "baumgardt-hilker-2018" + ], + "quantity": "central velocity dispersion", + "value": { + "sigmaKmS": 18.1 + }, + "unit": "km/s", + "scope": "Cluster center", + "limitations": "Kinematic evidence, not used in this image/light recipe; recorded because it is part of the measured structural package and could support a future kinematic cross-check." + }, + { + "id": "ellipticity", + "classification": "observed", + "sourceIds": [ + "white-shawl-1987" + ], + "quantity": "projected flattening 1 - b/a", + "value": { + "ellipticityApprox": 0.17 + }, + "unit": "dimensionless", + "scope": "Whole cluster; varies with radius across the literature (roughly 0.08 core to ~0.19 outskirts)", + "limitations": "Historical summary, not a constant flattening consumed by the selected recipe. The MGE uses all eight published projected Gaussian axis ratios to represent radial variation; it does not assume spherical symmetry." + }, + { + "id": "cluster-center-agreement", + "classification": "observed", + "sourceIds": [ + "simbad-ngc5139", + "eso1119b-publisher" + ], + "quantity": "publisher pointing center vs. independent catalogue position", + "value": { + "simbadRaDec": [ + "13:26:47.28", + "-47:28:46.1" + ], + "publisherRaDec": [ + "13:26:47.27", + "-47:28:46.34" + ], + "separationArcsec": 0.24, + "nativePixelScaleArcsecPerPx": 0.21 + }, + "unit": "arcsec", + "scope": "Whole-image registration check", + "limitations": "The stated0.24arcsec separation is approximately1.14 native pixels at0.21arcsec/pixel, so it is a center sanity check, not sub-pixel evidence or an independent field-star registration. The MGE center is explicitly re-anchored to observations.json; native registration belongs to its separately measured transform." + }, + { + "id": "king-profile-family", + "classification": "published-model", + "sourceIds": [ + "king-1962" + ], + "quantity": "single-mass empirical projected surface-density law", + "value": { + "formula": "Sigma(R) proportional to [ (1+(R/rc)^2)^-1/2 - (1+(rt/rc)^2)^-1/2 ]^2 for R <= rt" + }, + "unit": "n/a", + "scope": "Adopted profile family for the projected light distribution", + "limitations": "Historical King-Abel experiment only; not consumed by photometric-mge.json. Standard single-mass isotropic empirical law; Omega Centauri has multiple stellar populations and measurable rotation/flattening that a single-mass spherical King law does not capture.", + "selection": "rejected-historical" + }, + { + "id": "projected-half-light-approx", + "classification": "published-model", + "sourceIds": [ + "wolf-2010" + ], + "quantity": "projected half-light radius as a fraction of the 3D half-mass radius", + "value": { + "factor": 0.75 + }, + "unit": "dimensionless", + "scope": "Used once, to convert the measured 3D half-mass radius into a target projected half-light radius for solving the King concentration", + "limitations": "Historical King-Abel experiment only; not consumed by photometric-mge.json. This factor is an approximate, broadly-applicable result for centrally concentrated dispersion-supported systems, not a value measured for Omega Centauri specifically.", + "selection": "rejected-historical" + }, + { + "id": "abel-inverted-emissivity", + "classification": "published-model", + "sourceIds": [ + "king-1962", + "wolf-2010" + ], + "quantity": "spherically symmetric 3D relative emissivity vs. radius, derived by Abel-inverting the fitted King projected profile", + "value": { + "path": "labs/nebula/models/omega-centauri/king-abel-profile.json" + }, + "unit": "relative (peak-normalized)", + "scope": "0 to the solved tidal radius (46.4 pc)", + "limitations": "Historical King-Abel experiment only; not consumed by photometric-mge.json. Deterministic consequence of assumed spherical symmetry plus the King profile family and its two fixed shape parameters (approximations A and B recorded in king-abel-profile.json). It is not a released, independently measured 3D point table; it is our own Abel-inversion computation from measured/published-model inputs. The single strongest physical limitation is sphericity itself: Omega Centauri's true ellipticity (~0.08-0.19, entry 'ellipticity') means the real 3D structure is oblate/triaxial, not spherical, and this profile cannot represent that flattening.", + "selection": "rejected-historical" + }, + { + "id": "no-3d-baking-baseline", + "classification": "authored", + "sourceIds": [ + "king-1962" + ], + "quantity": "historical implementation blocker for the original King-Abel experiment", + "value": { + "status": "historical-blocker" + }, + "unit": "n/a", + "scope": "Lab tooling", + "limitations": "The original experiment had no external fixed-density simulation baseline. The selected analytic photometric MGE is a separate published-model prior; this historical entry does not establish that the new recipe has been baked, visually accepted or promoted." + }, + { + "id": "inclination-van-de-ven-2006", + "classification": "published-model", + "sourceIds": [ + "van-de-ven-2006-structure" + ], + "quantity": "inclination of the cluster's symmetry axis to the line of sight", + "value": { + "inclinationDeg": 50, + "uncertaintyDeg": 4, + "meanIntrinsicAxialRatio": 0.78, + "axialRatioUncertainty": 0.03 + }, + "unit": "degrees", + "scope": "Whole cluster; axisymmetric Schwarzschild orbit-superposition model fit to line-of-sight velocities plus internal proper motions", + "limitations": "Axisymmetric dynamical inference, not direct geometry. The source reports50 +/-4 degrees and dynamical distance4.8 +/-0.3kpc. D’Souza2013 subsequently adopts50 +/-3 degrees for its MGE analysis; that is the selected model convention, not an independently combined uncertainty. The recipe uses the newer observed distance only to set physical scale." + }, + { + "id": "inclination-haberle-2024", + "classification": "published-model", + "sourceIds": [ + "haberle-2024-omegacat2" + ], + "quantity": "inclination, independent modern check", + "value": { + "inclinationDeg": 43.9, + "uncertaintyDeg": 1.3 + }, + "unit": "degrees", + "scope": "Inner few arcminutes, from combined HST+MUSE proper motions (plane-of-sky rotation)", + "limitations": "Accepted-v2 axisymmetric kinematic inference, not direct depth. The1.3-degree interval crosses the selected MGE admissibility boundary43.603810 degrees; this newer fit cannot be substituted as an unconstrained inclination distribution into the older eight-Gaussian profile. Retained as a competing result, not erased or averaged with the selected50-degree convention." + }, + { + "id": "rotation-amplitude-reijns-2006", + "classification": "observed", + "sourceIds": [ + "reijns-2006-radial-velocities" + ], + "quantity": "line-of-sight rotation amplitude", + "value": { + "amplitudeKmS": 6, + "radiusRangeArcmin": [ + 6, + 10 + ] + }, + "unit": "km/s", + "scope": "Radial-velocity survey, 1589 member stars", + "limitations": "Directly observed rotation signal (not a model output), but only along the line of sight; does not by itself give a 3D rotation axis or amplitude. Velocity dispersion drops from about 15 km/s in the inner few arcmin to about 6 km/s at 25 arcmin, so the rotation amplitude is a sizeable fraction of the local dispersion in the outer cluster." + }, + { + "id": "rotation-amplitude-merritt-1997", + "classification": "observed", + "sourceIds": [ + "merritt-1997" + ], + "quantity": "earlier line-of-sight rotation amplitude estimate", + "value": { + "amplitudeKmS": 7.9, + "radiusPc": 11 + }, + "unit": "km/s", + "scope": "Earlier radial-velocity dataset, independent of Reijns et al. (2006)", + "limitations": "Recorded from a search-engine summary of the paper, not a direct fetch of the paper text in this session, so treat the exact 7.9 km/s figure as approximate pending primary verification. Given alongside rotation-amplitude-reijns-2006 to show two independent studies agree the amplitude is of order 6-8 km/s, not to imply a precise consensus number." + }, + { + "id": "rotation-flattening-relation", + "classification": "published-model", + "sourceIds": [ + "bianchini-2013-flattening" + ], + "quantity": "whether rotation alone explains the photometric flattening", + "value": { + "conclusion": "not fully; a purely rotationally-flattened oblate isotropic model under-/over-predicts the observed ellipticity profile at some radii, and matching it needs added radial velocity anisotropy" + }, + "unit": "n/a", + "scope": "Whole cluster, axisymmetric rotating-anisotropic dynamical models", + "limitations": "This is model-dependent evidence, not a raw measurement. Its direct consequence for this ledger: an oblate model built only from a measured ellipticity, position angle and inclination (isotropic King/Wilson made oblate) is known to be an approximation even under the axisymmetric assumption; velocity anisotropy, not just rotation, contributes to the real shape." + }, + { + "id": "counter-rotating-core", + "classification": "observed", + "sourceIds": [ + "pechetti-2024-muse-core" + ], + "quantity": "kinematically distinct core", + "value": { + "counterRotatesInner": true, + "innerRadiusArcsec": 20, + "innerRadiusPc": 0.5 + }, + "unit": "n/a", + "scope": "Innermost ~20 arcsec (~0.5 pc), MUSE narrow+wide field integral-field spectroscopy", + "limitations": "Direct observational evidence that the cluster's inner few tenths of a parsec rotate opposite to the bulk cluster rotation. This is incompatible with a single rigid-body oblate rotation pattern extended all the way to the center; any oblate King/Wilson model built from bulk ellipticity/PA/inclination necessarily misses this innermost feature, which occupies a negligible fraction of the cluster's volume but is a real, measured departure from simple oblate rotation." + }, + { + "id": "kinematic-disk-component", + "classification": "published-model", + "sourceIds": [ + "van-de-ven-2006-structure" + ], + "quantity": "separate disk-like kinematic substructure", + "value": { + "radialRangeArcmin": [ + 1, + 3 + ], + "massFraction": 0.04 + }, + "unit": "dimensionless (mass fraction)", + "scope": "Axisymmetric dynamical model, intermediate radii", + "limitations": "A model-inferred substructure (about 4% of total mass) in the same dynamical fit that gives the headline inclination number above; recorded because it is additional evidence that the cluster's true structure is not a single smooth oblate body, even though it is a small mass fraction and localized to a specific radial range." + }, + { + "id": "king-wilson-fit-comparison", + "classification": "published-model", + "sourceIds": [ + "mclaughlin-vandermarel-2005" + ], + "quantity": "comparison of published King(1966), Wilson(1975) and power-law fits", + "value": { + "pointCount": 54, + "unreducedChiSquared": { + "king1966": 89.81, + "wilson1975": 24.28, + "powerLaw": 76.25 + }, + "wilson": { + "centralPotentialW0": 4.7, + "centralPotentialUncertainty": 0.1, + "scaleRadiusArcsec": 196.81, + "scaleRadiusUncertaintyPlusArcsec": 7.08, + "scaleRadiusUncertaintyMinusArcsec": 7.01, + "concentrationLogRtOverR0": 1.34, + "concentrationUncertainty": 0.03, + "centralSurfaceBrightnessMagArcsec2": 16.52, + "centralSurfaceBrightnessUncertainty": 0.05, + "paperDistancePc": 5300 + } + }, + "unit": "n/a", + "scope": "Whole-cluster projected surface-brightness photometry", + "limitations": "Actual CDS rows now retrieved. Wilson is a better fit within this comparison, not proof that every King-family or other profile is impossible. r0 is a model scale radius, not the projected half-power core radius. Wilson requires its own distribution-function/Poisson solution; do not insert these parameters into King1962. The selected MGE already supplies a published radially varying flattening and an analytic deprojection." + }, + { + "id": "central-cusp-noyola-2008", + "classification": "observed", + "sourceIds": [ + "noyola-gebhardt-bergmann-2008" + ], + "quantity": "central surface-brightness slope", + "value": { + "logarithmicSlope": -0.08 + }, + "unit": "dimensionless (d log I / d log r)", + "scope": "Innermost several arcsec, HST ACS integrated light", + "limitations": "Shows a shallow rising cusp rather than a flat King core at the very center; part of the still-debated intermediate-mass-black-hole literature for this cluster (not adjudicated here), and irrelevant at the parsec scales the bulk King-Abel profile in this ledger targets, but recorded because it shows the innermost profile shape is not simply flat." + }, + { + "id": "distance-confirmation-baumgardt-vasiliev-2021", + "classification": "observed", + "sourceIds": [ + "baumgardt-vasiliev-2021-paper" + ], + "quantity": "adopted heliocentric distance from combined observations", + "value": { + "distancePc": 5426, + "uncertaintyPc": 47 + }, + "unit": "pc", + "scope": "Whole cluster, Gaia EDR3 + HST + literature combination", + "limitations": "Primary table now inspected directly. This replaces the earlier rounded5430 +/-50pc input for the MGE recipe, while preserving the original King-Abel artifact unchanged." + }, + { + "id": "position-angle-not-sourced", + "classification": "authored", + "sourceIds": [ + "van-de-ven-2006-structure" + ], + "quantity": "status note: position angle of the major axis on the sky", + "value": { + "status": "historical-gap-resolved", + "resolvedBy": "photometric-major-axis-position-angle" + }, + "unit": "n/a", + "scope": "Whole cluster", + "limitations": "Initial search summaries did not establish PA. Full primary section2.3.3 now supplies photometric major-axis100 degrees; the separate104 +/-1 degree modern kinematic fit remains recorded. This preserved entry is not a current missing-source claim." + }, + { + "id": "triaxiality-not-sourced", + "classification": "authored", + "sourceIds": [], + "quantity": "status note: dedicated triaxial (three-axis) shape measurement", + "value": { + "status": "not found in this session" + }, + "unit": "n/a", + "scope": "Whole cluster", + "limitations": "No direct triaxial spatial fit was qualified for this recipe. Counter-rotation, kinematic substructure and differing fitted inclinations do not by themselves prove triaxiality. The oblate MGE is an explicit conditional approximation; it does not exclude more complex structure." + }, + { + "id": "photometric-mge-fit", + "classification": "published-model", + "sourceIds": [ + "dsouza-rix-2013-mge", + "watkins-2013-mge-reuse" + ], + "quantity": "eight-component projected Multi-Gaussian Expansion", + "value": { + "recipePath": "labs/nebula/models/omega-centauri/photometric-mge.json", + "gaussianCount": 8, + "sourceSigmaUnit": "arcmin", + "recipeSigmaUnit": "arcsec", + "sigmaConversionFactor": 60, + "paperDistancePc": 5500, + "paperDistanceUncertaintyPc": 200, + "coefficientUncertainty": null + }, + "unit": "central amplitude:Lsun/pc2; angular major-axis sigma:arcmin; projected axis ratio:dimensionless", + "scope": "Smooth projected stellar number-density/light and radial flattening profiles fitted in the cited paper; not individual star locations.", + "limitations": "Central projected amplitudes are transcribed as published, with no additional1/q correction. Use only relative amplitudes for conditional integrated image light. No coefficient uncertainties or covariance are supplied, and no errors are fabricated. Neither an absolute emissivity calibration nor a modern dynamical refit is performed." + }, + { + "id": "photometric-major-axis-position-angle", + "classification": "observed", + "sourceIds": [ + "van-de-ven-2006-structure" + ], + "quantity": "photometric major-axis position angle east of north", + "value": { + "positionAngleDegrees": 100, + "uncertaintyDegrees": null, + "radialRangeArcmin": [ + 5, + 15 + ] + }, + "unit": "degrees", + "scope": "Elliptical isophotes fitted to the smoothed DSS image at5-15arcmin.", + "limitations": "The cited section does not give a formal PA uncertainty. This is an undirected major axis modulo180 degrees, not a signed rotation axis or evidence that all radii have identical PA." + }, + { + "id": "mge-adopted-inclination", + "classification": "published-model", + "sourceIds": [ + "dsouza-rix-2013-mge", + "van-de-ven-2006-structure" + ], + "quantity": "adopted inclination for the published oblate MGE interpretation", + "value": { + "inclinationDegrees": 50, + "paperAdoptedUncertaintyDegrees": 3, + "inclinationDefinition": "zero face-on,90 edge-on", + "minimumAdmissibleInclinationDegrees": 43.60381018068668 + }, + "unit": "degrees", + "scope": "Selected smooth axisymmetric deprojection.", + "limitations": "D’Souza2013 adopts50 +/-3 degrees citing van de Ven2006, whose own reported interval is50 +/-4 degrees. These are model-dependent conventions, not a new precision estimate. The recipe uses the central50-degree value; all components require qProjected squared greater than cos(inclination) squared." + }, + { + "id": "modern-kinematic-position-angle", + "classification": "published-model", + "sourceIds": [ + "haberle-2024-omegacat2" + ], + "quantity": "modern fitted kinematic position angle", + "value": { + "positionAngleDegrees": 104, + "uncertaintyDegrees": 1 + }, + "unit": "degrees east of north", + "scope": "HST+MUSE rotation fit in accepted-v2 section8.2.", + "limitations": "The quoted1-degree uncertainty follows the fitting step size. A kinematic fit is not interchangeable with the older photometric-isophote orientation used by this recipe." + }, + { + "id": "mge-observation-frame-center", + "classification": "authored", + "sourceIds": [ + "eso1119b-publisher", + "dsouza-rix-2013-mge" + ], + "quantity": "adopted common tangent-frame center", + "value": { + "centerIcrsDegrees": [ + 201.696958, + -47.479539 + ], + "observationRecipe": "labs/nebula/models/omega-centauri/observations.json", + "paperKinematicCenterIcrsDegrees": [ + 201.69065, + -47.47855 + ] + }, + "unit": "degrees ICRS", + "scope": "One common center for the two image lenses and the conditional spatial prior.", + "limitations": "The published radial shape is explicitly re-centered on the observation-frame center; it is not an assertion that the older paper used this same center. Center metadata does not replace independent image registration." + }, + { + "id": "mge-oblate-deprojection", + "classification": "published-model", + "sourceIds": [ + "dsouza-rix-2013-mge", + "watkins-2013-mge-reuse" + ], + "quantity": "analytic oblate deprojection of the published projected Gaussians", + "value": { + "methodPath": "labs/nebula/models/omega-centauri/mge-method.md", + "intrinsicAxisRatio": "sqrt((qProjected^2-cos(i)^2)/sin(i)^2)", + "centralRelativeDensity": "Sigma0*qProjected/(sqrt(2*pi)*sigma*qIntrinsic)", + "density": "sum rho0*exp(-(R^2+zIntrinsic^2/qIntrinsic^2)/(2*sigma^2))", + "frame": "x west,y north,z away from Earth" + }, + "unit": "relative light per angular-depth unit in the sampler", + "scope": "Conditional continuous depth prior for finite integrated-light emitters.", + "limitations": "An analytic inference under axisymmetry, not a released XYZ catalogue or measured star-by-star depth. It does not recover population-specific mass segregation, central counter-rotation or triaxial structure. Angular widths stay fixed when physical distance is changed." + }, + { + "id": "mge-authored-transport", + "classification": "authored", + "sourceIds": [ + "dsouza-rix-2013-mge" + ], + "quantity": "finite-support and mirror choices for conditional image-light transport", + "value": { + "lineOfSightTiltSign": 1, + "cutoffSigma": 6, + "amplitudeNormalization": "divide all projected central amplitudes by their sum", + "stellarTreatment": "preserve integrated starlight" + }, + "unit": "dimensionless", + "scope": "Offline conditional depth/material construction; common geometry for every lens.", + "limitations": "The projected image cannot choose the near/far tilt; sign+1 is authored. Six-sigma truncation is a numerical support bound, not a measured tidal edge. The published profile conditions finite3D image emitters; it does not identify individual member stars or justify copying the same image through every depth. Source registration, actual bake, side-view acceptance and app promotion require their own evidence." + } + ] +} diff --git a/labs/nebula/models/omega-centauri/registration.json b/labs/nebula/models/omega-centauri/registration.json new file mode 100644 index 0000000000..3edf0d8d34 --- /dev/null +++ b/labs/nebula/models/omega-centauri/registration.json @@ -0,0 +1,26 @@ +{ + "schema": "cssearth-nebula-intake-registration-evidence@1", + "objectId": "omega-centauri", + "checkedAt": "2026-09-19", + "source": { + "id": "eso1119b", + "sha256": "8df2e2ad462b9dc5b7437320fb2c6fd247c11746b4b2ffd3da95846b9083cad6", + "width": 14540, + "height": 14540, + "fieldArcminutes": [50.88, 50.88], + "nativeArcsecPerPixel": 0.2099 + }, + "method": "Whole-field publisher-WCS-vs-catalogue center check. No star-by-star astrometric fit was run in this session.", + "check": { + "publisherPointingCenterRaDec": ["13:26:47.27", "-47:28:46.34"], + "simbadCatalogueRaDec": ["13:26:47.28", "-47:28:46.1"], + "separationArcsec": 0.24, + "verdict": "Publisher WCS center agrees with the independently catalogued cluster center (NGC 5139, SIMBAD, ref 2010AJ....140.1830G) to within 0.24 arcsec, sub-pixel at the native 0.21 arcsec/px scale." + }, + "orientation": "Publisher states north is 0.0 degrees left of vertical (north-up); east/west handedness not independently re-derived from pixel data in this session.", + "limitations": [ + "This is a whole-image pointing check, not a matched-star homography fit against an external astrometric catalogue (e.g. Gaia); no per-star registration residuals were computed.", + "The field is dominated by the crowded cluster itself, so a compact-source cross-match against a stellar catalogue (rather than field background galaxies) would be the appropriate next step before any pixel-level star-position use.", + "Sufficient for the evidence-ledger and profile work in this delivery; not sufficient by itself to satisfy the skill's full registration gate (METHOD.md step 2) for a pixel-level bake." + ] +} diff --git a/labs/nebula/models/omega-centauri/shape-evidence.md b/labs/nebula/models/omega-centauri/shape-evidence.md new file mode 100644 index 0000000000..5f48125132 --- /dev/null +++ b/labs/nebula/models/omega-centauri/shape-evidence.md @@ -0,0 +1,54 @@ +# Omega Centauri: projected shape and conditional depth + +The selected prior is the published eight-component oblate Multi-Gaussian Expansion +(MGE), recorded in [photometric-mge.json](photometric-mge.json). It describes a smooth +stellar light distribution with changing flattening across radius. Its 3D depth is +conditional on axisymmetry and inclination; individual stellar depths are not measured. +The [physical ledger](physical-evidence.json) records values, access status and limits; +[mge-method.md](mge-method.md) gives the conversion and coordinate conventions. + +## Selected constraints + +| Constraint | Adopted value | Source and limitation | +| --- | --- | --- | +| Projected profile | Eight Gaussian amplitudes, angular widths and projected axis ratios | [D’Souza & Rix 2013](https://doi.org/10.1093/mnras/sts426), Table 1; full author PDF inspected. Coefficient uncertainties/covariance are not supplied. | +| Photometric major axis | 100° east of north | [van de Ven et al. 2006](https://arxiv.org/pdf/astro-ph/0509228), §2.3.3: nearly constant between 5–15 arcmin. No formal error bar supplied there. | +| Inclination | 50° | D’Souza adopts 50±3°; the earlier van de Ven fit reports 50±4°. This is a selected model convention, not a combined uncertainty estimate. | +| Distance | 5426±47 pc | [Baumgardt & Vasiliev 2021](https://doi.org/10.1093/mnras/stab1474), combined-distance table, NGC 5139 row, inspected directly. Angular widths remain unchanged. | +| Center | ICRS (201.696958°, −47.479539°) | Re-anchor the published radial shape to the common observation frame; the older paper used a different kinematic center. | + +The full paper and table resolve the earlier position-angle and fitted-profile gaps. +[Watkins et al. 2013](https://academic.oup.com/mnras/article/436/3/2598/1258888), +Table 1, independently reproduces the same MGE and explicitly identifies its +amplitudes as central projected surface brightness. Its −80° major axis is equivalent +to 100°; the signed rotation parameters are unnecessary for this static light prior. + +## Competing constraints and historical trials + +- **Modern kinematics:** [Häberle et al. 2024, accepted v2](https://arxiv.org/html/2404.03722v2), + §8.2, gives PA104±1° and inclination43.9±1.3°. This is a different kinematic fit. + The old MGE requires inclination greater than43.603810°; the newer uncertainty + interval crosses that boundary. It cannot be inserted into this profile without + checking every component's deprojection. +- **Wilson fit:** the actual [McLaughlin & van der Marel CDS table](https://cdsarc.cds.unistra.fr/ftp/J/ApJS/161/304/table10.dat) + gives W0=4.70±0.10 and scale radius196.810 +7.080/−7.010 arcsec. Its chi²24.28 is + lower than the King(1966) fit's89.81 for the same54 points. This comparison does not + invalidate every other family; MGE supplies the radial flattening needed here. + Wilson's scale radius is not its projected core radius, and its parameters cannot + be substituted into an empirical King(1962) law. +- **Rejected King-Abel experiment:** [king-abel-profile.json](king-abel-profile.json) + remains unchanged as historical evidence. Its spherical shape, substitution of a + 3D dynamical core radius for a projected radius, and approximate conversion from + mass radius to light radius are not used by the selected MGE. +- **Unresolved structure:** rotation, central counter-rotation and population-dependent + dynamics complicate a smooth oblate interpretation. Those observations do not by + themselves prove triaxiality; no measured triaxial model is supplied here. + +## What the source recipe establishes + +It establishes a reproducible, source-backed conditional depth prior. The near/far +mirror choice and finite cutoff are authored. The images retain integrated starlight; +relative image emission does not become calibrated luminosity, resolved member stars +or a stellar mass map. A published shape does not establish image registration, +completed baking, credible side views or application acceptance. Those outcomes need +their own receipts and visual checks. diff --git a/labs/nebula/models/omega-centauri/verify-against-dss2-fits.mts b/labs/nebula/models/omega-centauri/verify-against-dss2-fits.mts new file mode 100644 index 0000000000..d303d1b600 --- /dev/null +++ b/labs/nebula/models/omega-centauri/verify-against-dss2-fits.mts @@ -0,0 +1,86 @@ +/** Register each press image against a real-WCS DSS2 FITS cutout, with both sides detected at the + * same ~1"/px working scale (the coarser survey's native sampling) so detectStars finds the same + * population of stars on both sides. Reuses the shared algorithm only; no new matching logic. */ +import { readFile, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { createHash } from 'node:crypto'; +import sharp from 'sharp'; +import { decodeFits } from '../../../../tools/nebula/application/fits.ts'; +import { detectStars, matchStars, verifyRegistration, publisherTransform, type SkyRaster, type SkyFrame } from '../../packages/reconstruction/src/registration/stellar.ts'; + +const root = process.cwd(); +const sha256 = (b: Buffer) => createHash('sha256').update(b).digest('hex'); +const load = async (p: string, expected: string) => { const b = await readFile(resolve(root, p)); if (sha256(b) !== expected) throw new Error(`Pin differs: ${p}`); return b; }; + +// DSS2 red-band FITS, exact-by-construction WCS: fov=0.91667deg=3300", width=3300 -> 1.0"/px. +const dss2Path = '.local/nebula-lab/source-originals/omega-centauri-dss2.fits'; +const dss2Bytes = await readFile(resolve(root, dss2Path)); +console.log('DSS2 sha256', sha256(dss2Bytes), 'bytes', dss2Bytes.length); +const fits = decodeFits(dss2Bytes); +console.log('DSS2 FITS', fits.width, fits.height); +let lo = Infinity, hi = -Infinity; +const sorted = Float32Array.from(fits.values).sort(); +lo = sorted[Math.floor(sorted.length * 0.01)]!; hi = sorted[Math.floor(sorted.length * 0.999)]!; +const gray = Buffer.alloc(fits.width * fits.height); +for (let i = 0; i < fits.values.length; i++) gray[i] = Math.max(0, Math.min(255, Math.round((fits.values[i]! - lo) / (hi - lo) * 255))); +const dss2Png = await sharp(gray, { raw: { width: fits.width, height: fits.height, channels: 1 } }).png().toBuffer(); +const dss2: SkyRaster = { + width: fits.width, height: fits.height, fieldArcminutes: [fits.width / 60, fits.height / 60], centerIcrsDegrees: [201.696958, -47.479539], northRightDegrees: 0, + wcs: { projection: 'TAN', coordinateFrame: 'ICRS', referenceDimension: [fits.width, fits.height], referencePixel: [fits.width / 2, fits.height / 2], + referenceValueDeg: [201.696958, -47.479539], scaleDeg: [-1 / 3600, 1 / 3600], rotationDeg: 0 } as any, +}; +console.log('Detecting DSS2 stars at 1.0"/px...'); +const dss2Stars = await detectStars(dss2Png, [fits.width, fits.height], fits.width, 6000); +console.log('DSS2 stars', dss2Stars.length); + +const candidates = [ + { id: 'eso1119b', path: '.local/nebula-lab/source-originals/eso1119b.tif', sha256: '8df2e2ad462b9dc5b7437320fb2c6fd247c11746b4b2ffd3da95846b9083cad6', + width: 14540, height: 14540, fieldArcminutes: [50.88, 50.88] as [number, number], centerIcrsDegrees: [201.69695833333333, -47.47953888888889] as [number, number], northRightDegrees: 0.00051173061 }, + { id: 'eso0844a', path: '.local/nebula-lab/source-originals/eso0844a.tif', sha256: '384d1cfc31e6a2b78e5c7018f9eaecfe49a1014630bcb1bd8dceb563d69e6429', + width: 8040, height: 7560, fieldArcminutes: [31.88, 29.99] as [number, number], centerIcrsDegrees: [201.69716666666667, -47.479683333333334] as [number, number], northRightDegrees: -0.00724264734 }, +]; + +// Matching-frame resolution is swept independently of detection resolution (both press images and +// DSS2 are detected at the same ~1.0"/px scale above; only the discovery/verification tolerance, +// which is fixed in frame pixels, changes with frame width). +const FRAME_WIDTHS = [3600, 1800, 900, 450, 225]; + +const report: { schema: string; pass: boolean; sources: unknown[] } = { schema: 'cssearth-image-alignment-report@1', pass: true, sources: [] }; +for (const c of candidates) { + console.log(`--- ${c.id} downsampled to ~1"/px ---`); + const bytes = await load(c.path, c.sha256); + const targetScale = 1; // arcsec/px, matching DSS2 native + const newWidth = Math.round(c.width * (c.fieldArcminutes[0] * 60 / c.width) / targetScale); + const resized = await sharp(bytes).resize({ width: newWidth }).removeAlpha().toColourspace('srgb').png().toBuffer({ resolveWithObject: true }); + const { data: resizedInfo } = { data: resized.data }; + const actualW = resized.info.width, actualH = resized.info.height; + const scaleXArcsec = c.fieldArcminutes[0] * 60 / actualW, scaleYArcsec = c.fieldArcminutes[1] * 60 / actualH; + console.log(c.id, 'downsampled to', actualW, 'x', actualH, 'arcsec/px', scaleXArcsec, scaleYArcsec); + const downsampled: SkyRaster = { + width: actualW, height: actualH, fieldArcminutes: c.fieldArcminutes, centerIcrsDegrees: c.centerIcrsDegrees, northRightDegrees: c.northRightDegrees, + wcs: { projection: 'TAN', coordinateFrame: 'ICRS', referenceDimension: [actualW, actualH], referencePixel: [actualW / 2, actualH / 2], + referenceValueDeg: c.centerIcrsDegrees, scaleDeg: [-scaleXArcsec / 3600, scaleYArcsec / 3600], rotationDeg: c.northRightDegrees } as any, + }; + const stars = await detectStars(resized.data, [actualW, actualH], actualW, 6000); + console.log(c.id, 'stars', stars.length); + let outcome: { pass: boolean; matrix: unknown; evidence: Record; frameWidth: number } | undefined; + for (const width of FRAME_WIDTHS) { + const frame: SkyFrame = { width, height: width, fieldArcminutes: [60, 60], centerIcrsDegrees: [201.696958, -47.479539], northUp: true }; + const dss2Init = publisherTransform(dss2, frame), init = publisherTransform(downsampled, frame); + const pairs = matchStars(stars, dss2Stars, init, dss2Init); + console.log(c.id, 'frameWidth', width, 'arcsecPerPx', 3600 / width, 'pairs', pairs.length); + if (pairs.length < 45) continue; + const result = verifyRegistration(pairs, downsampled, frame, init, { width: dss2.width, height: dss2.height, imageToFrame: dss2Init }); + console.log(JSON.stringify({ id: c.id, frameWidth: width, pass: result.pass, rmsPixels: result.evidence.rmsPixels, maxResidualPixels: result.evidence.maxResidualPixels, + residualArcseconds: result.evidence.residualArcseconds, matchedStars: result.evidence.matchedStars, trainingStars: result.evidence.trainingStars, + heldOutStars: result.evidence.heldOutStars, coverageFraction: result.evidence.coverageFraction }, null, 2)); + outcome = { pass: result.pass, matrix: result.matrix, evidence: result.evidence, frameWidth: width }; + if (result.pass) break; + } + if (!outcome) { outcome = { pass: false, matrix: null, evidence: { status: 'publisher', interpretation: 'No frame width in the swept range reached 45 matched pairs.' }, frameWidth: -1 }; console.log(c.id, 'IMPASSE: never reached 45 matched pairs'); } + if (!outcome.pass) report.pass = false; + report.sources.push({ id: c.id, pass: outcome.pass, sourcePath: c.path, sourceSha256: c.sha256, downsampledTo: [actualW, actualH], frameWidth: outcome.frameWidth, + geometry: { kind: 'matched-star-homography-vs-dss2-fits', matrix: outcome.matrix }, evidence: outcome.evidence }); +} +await writeFile(resolve(root, 'labs/nebula/models/omega-centauri/dss2-fits-registration-report.json'), JSON.stringify(report, null, 2) + '\n'); +console.log('OVERALL PASS', report.pass); diff --git a/labs/nebula/models/omega-centauri/verify-against-dss2.mts b/labs/nebula/models/omega-centauri/verify-against-dss2.mts new file mode 100644 index 0000000000..be27ce84ef --- /dev/null +++ b/labs/nebula/models/omega-centauri/verify-against-dss2.mts @@ -0,0 +1,79 @@ +/** Register each press-release Omega Centauri image against an exact-WCS hips2fits DSS2 cutout, + * separately. Bypasses prepare-observations.ts only because its dependency graph currently pulls + * in an unrelated JWST toolchain module that throws on import when bundled; reuses the exact + * shared detectStars/matchStars/verifyRegistration algorithm, invents no matching logic. */ +import { readFile, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { createHash } from 'node:crypto'; +import { detectStars, matchStars, verifyRegistration, publisherTransform, type SkyRaster, type SkyFrame } from '../../packages/reconstruction/src/registration/stellar.ts'; + +const root = process.cwd(); +const sha256 = (bytes: Buffer) => createHash('sha256').update(bytes).digest('hex'); +async function loadBytes(path: string, expected: string): Promise { + const bytes = await readFile(resolve(root, path)); + const got = sha256(bytes); + if (got !== expected) throw new Error(`Pin differs for ${path}: expected ${expected}, got ${got}`); + return bytes; +} + +// hips2fits reference: WCS exact by construction from the request parameters (fov=1.0deg, width=3600, ra/dec, rotation 0). +const dss2: SkyRaster & { path: string; sha256: string } = { + path: '.local/nebula-lab/source-originals/omega-centauri-dss2.jpg', sha256: 'e42fb97ed35ac675f4143d77d7aaba096948a96fceaad2e200b1f279a1cb7638', + width: 3600, height: 3600, fieldArcminutes: [60, 60], centerIcrsDegrees: [201.696958, -47.479539], northRightDegrees: 0, + wcs: { projection: 'TAN', coordinateFrame: 'ICRS', referenceDimension: [3600, 3600], referencePixel: [1800, 1800], + referenceValueDeg: [201.696958, -47.479539], scaleDeg: [-1 / 3600, 1 / 3600], rotationDeg: 0 } as any, +}; + +const candidates: (SkyRaster & { id: string; path: string; sha256: string })[] = [ + { id: 'eso1119b', path: '.local/nebula-lab/source-originals/eso1119b.tif', sha256: '8df2e2ad462b9dc5b7437320fb2c6fd247c11746b4b2ffd3da95846b9083cad6', + width: 14540, height: 14540, fieldArcminutes: [50.88, 50.88], centerIcrsDegrees: [201.69695833333333, -47.47953888888889], northRightDegrees: 0.00051173061, + wcs: { projection: 'TAN', coordinateFrame: 'ICRS', referenceDimension: [14540, 14540], referencePixel: [7270, 7270], + referenceValueDeg: [201.69695833333333, -47.47953888888889], scaleDeg: [-0.20995873452544705 / 3600, 0.20995873452544705 / 3600], rotationDeg: 0.00051173061 } as any }, + { id: 'eso0844a', path: '.local/nebula-lab/source-originals/eso0844a.tif', sha256: '384d1cfc31e6a2b78e5c7018f9eaecfe49a1014630bcb1bd8dceb563d69e6429', + width: 8040, height: 7560, fieldArcminutes: [31.88, 29.99], centerIcrsDegrees: [201.69716666666667, -47.479683333333334], northRightDegrees: -0.00724264734, + wcs: { projection: 'TAN', coordinateFrame: 'ICRS', referenceDimension: [8040, 7560], referencePixel: [4020, 3780], + referenceValueDeg: [201.69716666666667, -47.479683333333334], scaleDeg: [-0.23791044776119402 / 3600, 0.23801587301587301 / 3600], rotationDeg: -0.00724264734 } as any }, +]; + +const frame: SkyFrame = { width: 8192, height: 8192, fieldArcminutes: [60, 60], centerIcrsDegrees: [201.696958, -47.479539], northUp: true }; +console.log('frame arcsec/px', 60 * 60 / frame.width); + +console.log('Reading DSS2 reference...'); +const dss2Bytes = await loadBytes(dss2.path, dss2.sha256); +console.log('Detecting DSS2 stars...'); +const dss2Stars = await detectStars(dss2Bytes, [dss2.width, dss2.height], 3600, 8000); +console.log(`DSS2 stars: ${dss2Stars.length}`); +const dss2Init = publisherTransform(dss2, frame); + +const report: { schema: string; pass: boolean; catalogue: string; sources: unknown[] } = { + schema: 'cssearth-image-alignment-report@1', pass: true, catalogue: 'labs/nebula/models/omega-centauri/observations.json', sources: [], +}; + +for (const candidate of candidates) { + console.log(`--- ${candidate.id} vs DSS2 ---`); + const bytes = await loadBytes(candidate.path, candidate.sha256); + const stars = await detectStars(bytes, [candidate.width, candidate.height], 8000, 12000); + console.log(`${candidate.id} stars: ${stars.length}`); + const initial = publisherTransform(candidate, frame); + const pairs = matchStars(stars, dss2Stars, initial, dss2Init); + console.log(`${candidate.id} matched pairs (pre-verify): ${pairs.length}`); + let outcome: { pass: boolean; matrix: unknown; evidence: Record }; + if (pairs.length < 45) { + outcome = { pass: false, matrix: initial, evidence: { status: 'publisher', matchedStars: pairs.length, interpretation: 'Fewer than 45 matched pairs against the DSS2 reference.' } }; + console.log(`${candidate.id}: IMPASSE, only ${pairs.length} matched pairs (need 45).`); + } else { + const result = verifyRegistration(pairs, candidate, frame, initial, { width: dss2.width, height: dss2.height, imageToFrame: dss2Init }); + outcome = { pass: result.pass, matrix: result.matrix, evidence: result.evidence }; + console.log(JSON.stringify({ id: candidate.id, pass: result.pass, rmsPixels: result.evidence.rmsPixels, maxResidualPixels: result.evidence.maxResidualPixels, + residualArcseconds: result.evidence.residualArcseconds, matchedStars: result.evidence.matchedStars, trainingStars: result.evidence.trainingStars, + heldOutStars: result.evidence.heldOutStars, spatialQuadrants: result.evidence.spatialQuadrants, coverageFraction: result.evidence.coverageFraction }, null, 2)); + } + if (!outcome.pass) report.pass = false; + report.sources.push({ id: candidate.id, pass: outcome.pass, sourcePath: candidate.path, sourceSha256: candidate.sha256, + geometry: { kind: 'matched-star-homography', registration: outcome.pass ? { referenceWcs: dss2.wcs, referenceWidthPx: dss2.width, referenceHeightPx: dss2.height, imageToReferenceMatrix: outcome.matrix } : null }, + evidence: outcome.evidence }); +} + +await writeFile(resolve(root, 'labs/nebula/models/omega-centauri/dss2-registration-report.json'), JSON.stringify(report, null, 2) + '\n'); +console.log('Wrote dss2-registration-report.json'); +console.log('OVERALL PASS:', report.pass); diff --git a/labs/nebula/models/omega-centauri/verify-registration.mts b/labs/nebula/models/omega-centauri/verify-registration.mts new file mode 100644 index 0000000000..2b1d96f41d --- /dev/null +++ b/labs/nebula/models/omega-centauri/verify-registration.mts @@ -0,0 +1,77 @@ +/** Replay native registration from the actual processing recipe and embedded TIFF AVM metadata. */ +import { readFile, writeFile, mkdir } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { createHash } from 'node:crypto'; +import assert from 'node:assert/strict'; +import sharp from 'sharp'; +import { readObservationRecipe, observationSourceFile, type ObservationSource } from '../../packages/lab/src/features/observations/recipe.ts'; +import { detectStars, matchStars, verifyRegistration, publisherTransform } from '../../packages/reconstruction/src/registration/stellar.ts'; + +const root = process.cwd(), directory = 'labs/nebula/models/omega-centauri'; +const sha256 = (bytes: Uint8Array) => createHash('sha256').update(bytes).digest('hex'); +const recipeBytes = await readFile(resolve(root, directory, 'observations.json')); +const recipe = readObservationRecipe(JSON.parse(recipeBytes.toString())); +const reference = recipe.images.find(image => image.id === recipe.referenceId)!; +const source = recipe.images.find(image => image.id === 'eso0844a')!; +if (!source || reference.id !== 'eso1119b') throw new Error('Expected the two pinned ESO observations.'); + +function avmPair(xml: string, key: string): [number, number] { + const section = xml.match(new RegExp(`([\\s\\S]*?)`)); + if (!section) throw new Error(`Missing AVM ${key}.`); + const values = [...section[1]!.matchAll(/([^<]+)<\/rdf:li>/g)].map(match => Number(match[1])); + if (values.length !== 2 || !values.every(Number.isFinite)) throw new Error(`Invalid AVM ${key}.`); + return [values[0]!, values[1]!]; +} +async function loadNative(image: ObservationSource) { + const path = resolve(root, '.local/nebula-lab/observations', recipe.id, 'sources', observationSourceFile(image)); + const bytes = await readFile(path); + if (sha256(bytes) !== image.sha256) throw new Error(`${image.id}: source hash differs.`); + const metadata = await sharp(bytes).metadata(), xml = metadata.xmp?.toString(); + if (!xml || metadata.width !== image.width || metadata.height !== image.height) throw new Error(`${image.id}: missing native AVM or dimensions differ.`); + const rotation = xml.match(/avm:Spatial.Rotation="([^"]+)"/); + if (!rotation || !Number.isFinite(Number(rotation[1])) || !xml.includes('avm:Spatial.CoordinateFrame="ICRS"') || + !xml.includes('avm:Spatial.CoordsystemProjection="TAN"')) throw new Error(`${image.id}: unexpected native sky frame.`); + const wcs = { projection: 'TAN', coordinateFrame: 'ICRS', referenceDimension: avmPair(xml, 'ReferenceDimension'), + referencePixel: avmPair(xml, 'ReferencePixel'), referenceValueDeg: avmPair(xml, 'ReferenceValue'), + scaleDeg: avmPair(xml, 'Scale'), rotationDeg: Number(rotation[1]) }; + assert.deepEqual(image.wcs, wcs, `${image.id}: recipe must retain exact embedded AVM, including noncentral reference pixel.`); + const settings = image.registrationDetection; + if (!settings) throw new Error('Explicit native registration detection settings required.'); + console.log(`REGISTRATION_DETECT ${image.id}`); + const stars = await detectStars(bytes, [image.width, image.height], settings.sourceMaximum, settings.maximumStars); + return { stars, avmSha256: sha256(Buffer.from(xml)), wcs }; +} +const referenceNative = await loadNative(reference), sourceNative = await loadNative(source); +const referenceInitial = publisherTransform(reference, recipe.frame), sourceInitial = publisherTransform(source, recipe.frame); +const footprint = { width: reference.width, height: reference.height, imageToFrame: referenceInitial }; +const pairs = matchStars(sourceNative.stars, referenceNative.stars, sourceInitial, referenceInitial); +const result = verifyRegistration(pairs, source, recipe.frame, sourceInitial, footprint); +assert.equal(result.pass, true, 'The unchanged native registration gate must pass.'); +const centred = structuredClone(source); +assert.ok(centred.wcs); +centred.wcs.referencePixel = [centred.wcs.referenceDimension[0] / 2, centred.wcs.referenceDimension[1] / 2]; +const centredResult = verifyRegistration(pairs, centred, recipe.frame, publisherTransform(centred, recipe.frame), footprint); +assert.equal(centredResult.pass, false, 'Reinstating the lost AVM offset must fail.'); +const corrupted = structuredClone(pairs), heldOut = result.evidence.matches.find(match => match.heldOut)!; +corrupted.find(pair => pair.source[0] === heldOut.source[0] && pair.source[1] === heldOut.source[1])!.frame[0] += 3; +const corruptedResult = verifyRegistration(corrupted, source, recipe.frame, sourceInitial, footprint); +assert.equal(corruptedResult.pass, false, 'A wrong held-out identity must fail.'); +const output = resolve(root, 'output/omega-centauri-registration'); +await mkdir(output, { recursive: true }); +const fullReceipt = Buffer.from(JSON.stringify({ recipeSha256: sha256(recipeBytes), result }, null, 2) + '\n'); +await writeFile(resolve(output, 'native-registration-full.json'), fullReceipt); +const { matches: _matches, ...evidence } = result.evidence; +const receipt = { schema: 'cssearth-nebula-intake-registration-evidence@1', objectId: recipe.id, + checkedAt: new Date().toISOString().slice(0, 10), recipeSha256: sha256(recipeBytes), + implementationSha256: sha256(await readFile(resolve(root, 'labs/nebula/packages/reconstruction/src/registration/stellar.ts'))), + method: 'Exact native AVM WCS; automatic reciprocal field-star constellations, unchanged RANSAC affine and spatial holdout gates. Full native source pixels, bounded 8000-pixel detection only.', + source: { id: source.id, sha256: source.sha256, width: source.width, height: source.height, avmSha256: sourceNative.avmSha256, wcs: sourceNative.wcs }, + reference: { id: reference.id, sha256: reference.sha256, width: reference.width, height: reference.height, avmSha256: referenceNative.avmSha256, wcs: referenceNative.wcs }, + frame: recipe.frame, matrix: result.matrix, pass: result.pass, evidence, + controls: { recentredPublisherReferencePixel: { pass: centredResult.pass, centreShiftPixels: centredResult.evidence.centreShiftPixels }, + corruptedHeldOutIdentity: { pass: corruptedResult.pass, maxResidualPixels: corruptedResult.evidence.maxResidualPixels } }, + fullReceipt: { path: 'output/omega-centauri-registration/native-registration-full.json', sha256: sha256(fullReceipt) }, + limits: 'Relative alignment only; publisher absolute astrometry is not independently catalogue calibrated. WFI includes publisher-declared DSS gap fill. No depth, membership or photometric calibration is established.' }; +await writeFile(resolve(root, directory, 'native-registration.json'), JSON.stringify(receipt, null, 2) + '\n'); +console.log(JSON.stringify({ pass: result.pass, ...evidence }, null, 2)); +console.log('OMEGA_NATIVE_REGISTRATION_VERIFIED'); diff --git a/labs/nebula/packages/lab/browser/browser-difference-map.ts b/labs/nebula/packages/lab/browser/browser-difference-map.ts index 7054475b4b..2b0aec998b 100644 --- a/labs/nebula/packages/lab/browser/browser-difference-map.ts +++ b/labs/nebula/packages/lab/browser/browser-difference-map.ts @@ -66,9 +66,9 @@ try { document.querySelector('.reconstruction-controls')?.getAttribute('data-reconstruction-result') === value, id, { timeout: 120000 }); await page.locator('#reference-view').click(); await settle(page); - // The second round button, directly under Levels. + // The second of three round buttons, directly under Levels (Radial profile sits third, under Difference map). const order = await page.locator('.workspace-tool-buttons [data-workspace-tool]').evaluateAll(nodes => nodes.map(node => (node as HTMLElement).dataset.workspaceTool)); - assert.deepEqual(order, ['levels', 'difference'], `tool order ${order.join(',')}`); + assert.deepEqual(order, ['levels', 'difference', 'radial'], `tool order ${order.join(',')}`); const [levelsBox, differenceBox] = await Promise.all(['levels', 'difference'].map(tool => page.locator(`[data-workspace-tool="${tool}"]`).boundingBox())); assert.ok(levelsBox && differenceBox && differenceBox.y > levelsBox.y + levelsBox.height - 1 && Math.abs(differenceBox.x - levelsBox.x) < .5, 'not under Levels'); diff --git a/labs/nebula/packages/lab/browser/browser-lens-radial.ts b/labs/nebula/packages/lab/browser/browser-lens-radial.ts new file mode 100644 index 0000000000..5428e06168 --- /dev/null +++ b/labs/nebula/packages/lab/browser/browser-lens-radial.ts @@ -0,0 +1,69 @@ +/** + * The live Radial profile panel in the real Reconstruction sidebar, for two image lenses. + * + * Read-only: it selects lenses through the page's own image picker and opens the panel, so the measurement + * arrives through the same route a person browsing the lab hits. Args: [base-url] [output-directory]. + */ +import assert from 'node:assert/strict'; +import { mkdir, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { chromium, type Page } from 'playwright'; + +const base = process.argv[2] ?? 'http://127.0.0.1:4331'; +const output = resolve(process.argv[3] ?? '.local/nebula-lab/lens-radial'); +const lenses = ['horalek-widefield', 'vista-infrared']; +await mkdir(output, { recursive: true }); + +const errors: string[] = [], ignored: string[] = [], report: unknown[] = []; +const browser = await chromium.launch({ headless: true }); +try { + const page: Page = await browser.newPage({ viewport: { width: 1500, height: 1050 } }); + const note = (text: string) => { (/favicon/.test(text) ? ignored : errors).push(text); }; + page.on('pageerror', error => note(String(error))); + page.on('console', message => { if (message.type() === 'error') note(`${message.text()} @ ${message.location().url || 'unknown'}`); }); + page.on('response', response => { if (response.status() >= 400) note(`http ${response.status()} ${response.url()}`); }); + + const catalogue = await (await fetch(`${base}/__nebula/reconstruction?subjectId=lmc-clouds`)).json(); + assert.ok(catalogue.finiteModel?.modelResultId, 'The LMC needs a discovered finite model to have lenses.'); + await page.goto(`${base}/reconstruction?subject=lmc-clouds`); + await page.waitForSelector('#reconstruction-image option[value="horalek-widefield"]', { state: 'attached' }); + for (const imageId of lenses) { + const expected = catalogue.candidates.find((row: { imageId: string }) => row.imageId === imageId); + assert.ok(expected?.prepared?.resultId, `No baked lens for ${imageId}.`); + await page.selectOption('#reconstruction-image', imageId); + await page.waitForFunction(id => document.querySelector('.reconstruction-controls')?.getAttribute('data-reconstruction-result') === id, + expected.prepared.resultId, { timeout: 120000 }); + + // The third round button, under Levels and Difference map. + const order = await page.locator('.workspace-tool-buttons [data-workspace-tool]').evaluateAll(nodes => nodes.map(node => (node as HTMLElement).dataset.workspaceTool)); + assert.deepEqual(order, ['levels', 'difference', 'radial'], `tool order ${order.join(',')}`); + await page.locator('[data-workspace-tool="radial"]').click(); + const panel = page.locator('.lens-radial-panel'); + await panel.waitFor(); + await page.waitForFunction(id => { + const node = document.querySelector('.lens-radial-panel'); + return node?.dataset.lensRadialState === 'ready' && node.dataset.lensRadialResult === id; + }, expected.prepared.resultId, { timeout: 120000 }); + const measured = await panel.evaluate(node => ({ + resultId: (node as HTMLElement).dataset.lensRadialResult, + polylines: node.querySelectorAll('polyline').length, + canvas: node.querySelectorAll('canvas').length, + numbers: node.querySelector('.lens-radial-numbers')?.textContent?.trim() ?? '', + status: node.querySelector('.lens-radial-status')?.textContent?.trim() ?? '', + })); + assert.equal(measured.resultId, expected.prepared.resultId); + // Source, render and ratio strokes, drawn as SVG; never a canvas. + assert.equal(measured.polylines, 3, `${imageId} polylines ${measured.polylines}`); + assert.equal(measured.canvas, 0); + assert.match(measured.numbers, /half-light radius .+px.+rms log ratio .+worst/s); + assert.match(measured.status, /grid \d+×\d+ · footprint [\d,]+ px/); + await panel.screenshot({ path: `${output}/radial-${imageId}.png` }); + await page.screenshot({ path: `${output}/lab-${imageId}.png` }); + report.push({ imageId, ...measured }); + // Close the panel so the next lens starts from the same closed state. + await page.locator('.workspace-tool-close').click(); + } + assert.deepEqual(errors, [], `Console errors: ${errors.join(' | ')}`); +} finally { await browser.close(); } +await writeFile(`${output}/report.json`, JSON.stringify({ base, lenses, ignored, report }, null, 2) + '\n'); +console.log('LENS_RADIAL_BROWSER_OK', output, JSON.stringify(report.map((row: any) => [row.imageId, row.polylines]))); diff --git a/labs/nebula/packages/lab/package.json b/labs/nebula/packages/lab/package.json index d2b59764a2..8953e057e6 100644 --- a/labs/nebula/packages/lab/package.json +++ b/labs/nebula/packages/lab/package.json @@ -42,6 +42,7 @@ "@layoutit/polycss": "0.2.11", "@cssearth/engine": "workspace:*", "@cssearth/objects": "workspace:*", + "typescript": "5.9.3", "vite": "7.3.1" }, "devDependencies": { diff --git a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler-export.ts b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler-export.ts index c6a125a94a..bbc3c1667a 100644 --- a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler-export.ts +++ b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler-export.ts @@ -21,7 +21,7 @@ export async function exportCompactCompiler(root: string, objectId: string) { const material = receipts.find(m => record(m) && m.sourceId === lens.id); if (!record(material) || material.schema !== 'cssearth-component-bound-material@1' || material.fieldIdentity !== result.scene.fieldIdentity || !Array.isArray(material.components)) throw new TypeError(`Missing accepted component colors for ${lens.id}.`); - return { sourceId: lens.id, components: material.components.map((color: unknown) => { + return { sourceId: lens.id, ...(material.envelopeColors === undefined ? {} : { envelopeColors: material.envelopeColors }), components: material.components.map((color: unknown) => { if (!record(color)) throw new TypeError('Invalid retained component.'); return { id: color.id, rgb: color.rgb, covered: color.covered }; }) }; @@ -36,7 +36,7 @@ export async function exportCompactCompiler(root: string, objectId: string) { } const input = { schema: 'cssearth-compact-compiler@1', objectId, provenance: { resultPath, resultSha256: hash(resultBytes), modelSha256: hash(modelBytes), methodSha256: hash(methodBytes), - interpretation: 'Accepted fitted emission components, per-component source chromaticity, stars and sampling. Derived field inputs, not measured volumetric gas density. Full source acquisition remains available in the research recipes.' }, + interpretation: 'Accepted fitted emission components, any retained photometric envelope with coarse source chromaticity, per-component colors, stars and sampling. Derived field inputs, not measured volumetric gas density. Full source acquisition remains available in the research recipes.' }, field: JSON.parse(modelBytes.toString()), scene: result.scene, materials, sources: result.scene.lenses.map(lens => { const source = result.sources.find(source => source.id === lens.id)!; return { id: lens.id, label: lens.label, credit: source.credit, page: source.page }; }), diff --git a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.test.ts b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.test.ts index ca2e31cbce..95da8af0e5 100644 --- a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.test.ts +++ b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.test.ts @@ -26,3 +26,46 @@ test('compact compiler validates the accepted field, material correspondence and shape.expected[0].resources[0].width = 0; assert.throws(() => readCompactCompiler(shape), /resource/); }); + +import { createHash } from 'node:crypto'; +test('compact replay cannot silently omit a retained density envelope or its colors', async () => { + const value = await input(); + const recipe = JSON.parse(await readFile('labs/nebula/models/omega-centauri/photometric-mge.json', 'utf8')); + value.field.photometricEnvelope = { schema: 'cssearth-photometric-envelope@1', priorIdentity: 'c'.repeat(64), recipe, + width: 2, height: 2, bounds: { min: [-100, -100], max: [100, 100] }, zRange: [-300, 300], gain: [1, 1, 1, 1] }; + for (const material of value.materials) material.envelopeColors = { width: 2, height: 2, rgb: Array(12).fill(255) }; + value.provenance.modelSha256 = createHash('sha256').update(JSON.stringify(value.field)).digest('hex'); + assert.ok(readCompactCompiler(value).field.photometricEnvelope); + const missingColors = structuredClone(value); delete missingColors.materials[0].envelopeColors; + assert.throws(() => readCompactCompiler(missingColors), /envelope colors/); + const missingField = structuredClone(value); delete missingField.field.photometricEnvelope; + for (const material of missingField.materials) delete material.envelopeColors; + assert.throws(() => readCompactCompiler(missingField), /retained model hash/); +}); + +test('compact sampling keeps historical omission and rejects a grouped plan that differs from saved output counts', async () => { + const historical = await input(), before = JSON.stringify(historical.scene.sampling); + assert.equal(JSON.stringify(readCompactCompiler(historical).scene.sampling), before); + assert.equal('layerPlan' in readCompactCompiler(historical).scene.sampling, false); + const planned = structuredClone(historical), reference = { ...planned.scene.sampling.sliceCounts }; + const groups = (count: number) => Array.from({ length: Math.ceil(count / 4) }, (_, i) => ({ startCell: i * 4, endCell: Math.min(count, i * 4 + 4) })); + const axes = { x: groups(reference.x), y: groups(reference.y), z: groups(reference.z) }; + planned.scene.sampling.layerPlan = { schema: 'cssearth-volume-layer-plan@1', referenceSliceCounts: reference, + referenceSamplesPerSlab: 4, axes }; + planned.scene.sampling.sliceCounts = { x: axes.x.length, y: axes.y.length, z: axes.z.length }; + assert.deepEqual(readCompactCompiler(planned).scene.sampling, planned.scene.sampling); + const reported = structuredClone(planned); + reported.scene.sampling.layerOptimization = { schema: 'cssearth-layer-optimization@1', + method: 'gradient-weighted-depth-displacement@1', maximumLayers: 500, + referenceLayers: reference.x + reference.y + reference.z, plannedLayers: axes.x.length + axes.y.length + axes.z.length, + probeWidth: 64, probeSubpixels: 2, targetNormalizedL1: .01, estimatedNormalizedL1: { x: .005, y: .008, z: .009 }, status: 'target-met' }; + assert.deepEqual(readCompactCompiler(reported).scene.sampling, reported.scene.sampling); + const orphanReport = structuredClone(reported); delete orphanReport.scene.sampling.layerPlan; + assert.throws(() => readCompactCompiler(orphanReport), /report requires its retained plan/); + const wrongReport = structuredClone(reported); wrongReport.scene.sampling.layerOptimization.plannedLayers++; + assert.throws(() => readCompactCompiler(wrongReport), /report differs from its plan/); + const wrongCount = structuredClone(planned); wrongCount.scene.sampling.sliceCounts.x++; + assert.throws(() => readCompactCompiler(wrongCount), /differs from its retained layer plan/); + const wrongQuadrature = structuredClone(planned); wrongQuadrature.scene.sampling.layerPlan.referenceSamplesPerSlab = 2; + assert.throws(() => readCompactCompiler(wrongQuadrature), /differs from its retained layer plan/); +}); diff --git a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.ts b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.ts index d569b81f55..895c3fdc9c 100644 --- a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.ts +++ b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-compiler.ts @@ -1,3 +1,4 @@ +import { CSS_COMPILER_RENDER_BUDGET } from '../../../../../../../../src/renderers/css/volume/compiler-render-budget.ts'; /** cssEarth representation adapter; compact replay does not depend on research processing. */ import { replayCompactCompiler as replay, type CompactCompilerBackend } from '@cssearth/volume-bake/compact-inputs/compiler'; import type { CompilerBakeProgress } from '@cssearth/volume-bake/compiler/bake'; @@ -10,6 +11,7 @@ export { readCompactCompiler } from '@cssearth/volume-bake/compact-inputs/compil export function replayCompactCompiler(root: string, pin: Pin, outputDirectory: string, progress?: (progress: CompilerBakeProgress) => void) { const backend: CompactCompilerBackend = { + renderBudget: CSS_COMPILER_RENDER_BUDGET, compileVolume: input => validatePreparedCssVolume(compileCssVolume({ ...input, recipe: { anchors: [] } })), readVolume: validatePreparedCssVolume, prepareStarSprites: prepareCompilerStarSprites, diff --git a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.test.ts b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.test.ts index 83478c89a2..5891dc1509 100644 --- a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.test.ts +++ b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.test.ts @@ -3,10 +3,11 @@ import assert from "node:assert/strict"; import { mkdtemp, mkdir, readFile, writeFile, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; -import { gunzipSync } from "node:zlib"; +import { gunzipSync, gzipSync } from "node:zlib"; import { createHash } from "node:crypto"; import { replayCompactSampled } from "./compact-sampled.ts"; import { jointRecord } from "../../../features/joint-fit/model.ts"; +import { maximumPlanningEmission, prepareCompactSampledInputs } from '@cssearth/volume-bake/compact-inputs/sampled'; test("compact sampled replay rejects changed measured particles before any reconstruction", async () => { const root = await mkdtemp(join(tmpdir(), "nebula-sampled-")); try { @@ -36,3 +37,32 @@ test("compact sampled replay rejects changed measured particles before any recon await rm(root, { recursive: true, force: true }); } }); + +test('sampled planning preserves features unique to any lens without changing its emission', () => { + const reference = (x: number, _y: number, _z: number, out: [number, number, number]) => { out.fill(x < 0 ? 3 : 0); }; + const secondary = (x: number, _y: number, _z: number, out: [number, number, number]) => { out.fill(x > 0 ? 7 : 1); }; + const planning = maximumPlanningEmission([reference, secondary]), reverse = maximumPlanningEmission([secondary, reference]); + const out: [number, number, number] = [0, 0, 0], alternate: [number, number, number] = [0, 0, 0]; + for (const [x, expected] of [[-1, 3], [0, 1], [1, 7]] as const) { + planning(x, 0, 0, out); reverse(x, 0, 0, alternate); + assert.deepEqual(out, [expected, expected, expected]); assert.deepEqual(alternate, out); + } + reference(1, 0, 0, out); assert.deepEqual(out, [0, 0, 0]); + secondary(-1, 0, 0, out); assert.deepEqual(out, [1, 1, 1]); + assert.throws(() => maximumPlanningEmission([]), /at least one/); + const invalid = maximumPlanningEmission([reference, (_x, _y, _z, rgb) => { rgb[0] = 1; }]); + assert.throws(() => invalid(1, 0, 0, out), /finite nonnegative/); +}); + +test('retained sampled loader rejects a renamed scene before reading particles or writing outputs', async () => { + const root = await mkdtemp(join(tmpdir(), 'nebula-retained-sampled-')); + try { + const value: unknown = JSON.parse(gunzipSync(await readFile('src/objects/m1/source/compact/model.json.gz')).toString()); + assert.ok(jointRecord(value)); value.sourceResult = '0'.repeat(64); + const bytes = gzipSync(Buffer.from(JSON.stringify(value))), path = 'input.json.gz'; + await writeFile(join(root, path), bytes); + await assert.rejects(prepareCompactSampledInputs(root, + { path, sha256: createHash('sha256').update(bytes).digest('hex') }, + { decodeFits() { throw new Error('Must reject before decoding'); } }), /source result differs/); + } finally { await rm(root, { recursive: true, force: true }); } +}); diff --git a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.ts b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.ts index b3c84c86fc..f6f3f604a1 100644 --- a/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.ts +++ b/labs/nebula/packages/lab/src/adapters/application/delivery/compact-sampled.ts @@ -1,3 +1,4 @@ +import { CSS_COMPILER_RENDER_BUDGET } from '../../../../../../../../src/renderers/css/volume/compiler-render-budget.ts'; import { replayCompactSampled as replay } from '@cssearth/volume-bake/compact-inputs/sampled'; import { compileCssVolume } from '../../../../../../../../src/renderers/css/preparation/volume.ts'; import { validatePreparedCssVolume } from '../../../../../../../../src/renderers/css/volume/validation.ts'; @@ -187,6 +188,7 @@ export async function exportCompactSampled( } export async function replayCompactSampled(root: string, inputPin: CompilerPin, outputDirectory: string) { return replay(root, inputPin, outputDirectory, { + renderBudget: CSS_COMPILER_RENDER_BUDGET, compileVolume: input => compileCssVolume({ ...input, recipe: { anchors: [] } }), validateVolume: validatePreparedCssVolume, prepareStarSprites: prepareCompilerStarSprites, diff --git a/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-frame.test.ts b/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-frame.test.ts index c6e82424ac..4f14b5bdfb 100644 --- a/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-frame.test.ts +++ b/labs/nebula/packages/lab/src/adapters/application/delivery/nebula-frame.test.ts @@ -4,6 +4,9 @@ import { embedNebulaFrame, embedNebulaVolume, reflectNebulaPoint, ARCSECOND_RADI import { worldRotationFromQuaternion } from '../../../../../../../../src/renderers/css/navigation/world-camera-math.ts'; import { validatePreparedCssVolume } from '../../../../../../../../src/renderers/css/volume/validation.ts'; import type { PreparedCssVolume } from '../../../../../../../../src/renderers/css/volume/types.ts'; +import { compileCssVolume } from '../../../../../../../../src/renderers/css/preparation/volume.ts'; +import { compilerFrame, compilerPreparedPoint, compilerPreparedSlices } from '@cssearth/volume-core/coordinates/compiler-frame'; +import type { VolumeSlices } from '@cssearth/volume-core/contracts/volume-slices'; const frame = { referenceFrame:'lab',epochJdTt:0,originM:[0,0,0] as const,localToReferenceXyzw:[0,0,0,1] as const, metersPerUnit:1,boundsUnits:{min:[-3,-2,-1] as const,max:[4,2,1] as const} }; const sky = { centerIcrsDegrees:[0,0] as [number,number],distancePc:100,imageRotationDegrees:0,arcsecPerUnit:1 }; @@ -35,3 +38,40 @@ test('invalid physical frames cannot silently assign units or a sky direction',( for(const change of [{distancePc:0},{arcsecPerUnit:NaN},{centerIcrsDegrees:[360,0] as [number,number]},{imageRotationDegrees:Infinity}]) assert.throws(()=>embedNebulaFrame(frame,{...sky,...change}),/Invalid physical/); }); + +test('new physical compiler transport and historical source transport produce identical app sky geometry', () => { + const bounds = { min: [-4, -3, -2] as [number, number, number], max: [4, 3, 2] as [number, number, number] }; + const angular = compilerFrame(bounds), physical = compilerFrame(bounds, true); + const slices: VolumeSlices = { boundsUnits: bounds, quads: [{ id: 'z-0', axis: 'z', sliceIndex: 0, + texturePath: 'a.png', widthPx: 2, heightPx: 2, vertices: [[-2, 2, -1], [2, 2, -1], [2, -2, -1], [-2, -2, -1]], + uvs: [[0, 0], [1, 0], [1, 1], [0, 1]], center: [0, 0, -1], normal: [0, 0, 1], sha256: 'a'.repeat(64), bytes: 12, alphaCoverage: 1 }], + provenance: {}, approximation: { method: 'fixture', radialEmission: 'none', limitations: [], samplesPerSlab: 4, + opticalWeight: 1, exposureGain: 1, sliceCounts: { x: 1, y: 1, z: 1 }, slabPitchUnits: { x: 8, y: 6, z: 4 } } }; + for (const axis of ['x', 'y'] as const) slices.quads.push({ ...slices.quads[0]!, id: `${axis}-0`, axis, + normal: axis === 'x' ? [1, 0, 0] : [0, 1, 0], alphaCoverage: 0 }); + const oldBank = compileCssVolume({ id: 'angular', frame: angular.frame, slices, recipe: { anchors: [] } }); + const newBank = compileCssVolume({ id: 'physical', frame: physical.frame, slices: compilerPreparedSlices(slices), recipe: { anchors: [] } }); + const oldApp = embedNebulaVolume(oldBank, embedNebulaFrame(angular.frame, sky), 'same', 'same'); + const newApp = embedNebulaVolume(newBank, embedNebulaFrame(physical.frame, sky), 'same', 'same'); + assert.deepEqual(newApp.frame, oldApp.frame); + assert.deepEqual(newApp.resources, oldApp.resources); + for (const axis of ['x', 'y', 'z'] as const) { + const before = oldApp.stacks.find(stack => stack.axis === axis)!, after = newApp.stacks.find(stack => stack.axis === axis)!; + assert.equal(after.leaves.length, before.leaves.length); + for (let i = 0; i < before.leaves.length; i++) { + const oldLeaf = before.leaves[i]!, newLeaf = after.leaves[i]!; + assert.deepEqual(newLeaf.centerUnits, oldLeaf.centerUnits); + assert.deepEqual(newLeaf.boundsCssPixels, oldLeaf.boundsCssPixels); + assert.equal(newLeaf.texturePath, oldLeaf.texturePath); + const matrix = (value: string) => value.slice(9, -1).split(',').map(Number); + const a = matrix(oldLeaf.style.transform), b = matrix(newLeaf.style.transform); + // Plane-local Z is always zero; compare every rendered corner, not its unused normal column. + for (const x of [0, Number.parseFloat(oldLeaf.style.width)]) for (const y of [0, Number.parseFloat(oldLeaf.style.height)]) + for (const row of [0, 1, 2]) assert.ok(Math.abs(a[row]! * x + a[row + 4]! * y + a[row + 12]! - + b[row]! * x - b[row + 4]! * y - b[row + 12]!) < 1e-9); + } + } + for (const point of [[1, 2, -1], [-2, 1, 1]] as [number, number, number][]) { + assert.deepEqual(reflectNebulaPoint(compilerPreparedPoint(point), physical.frame), reflectNebulaPoint(point, angular.frame)); + } +}); diff --git a/labs/nebula/packages/lab/src/adapters/preparation/css-volume.ts b/labs/nebula/packages/lab/src/adapters/preparation/css-volume.ts index 3e6f13137d..a5fc4052b2 100644 --- a/labs/nebula/packages/lab/src/adapters/preparation/css-volume.ts +++ b/labs/nebula/packages/lab/src/adapters/preparation/css-volume.ts @@ -1,3 +1,4 @@ /** Explicit cssEarth host integration; implementation remains with its source owner. */ export { compileCssVolume } from '../../../../../../../src/renderers/css/preparation/volume.ts'; export type { PreparedCssVolume } from '../../../../../../../src/renderers/css/preparation/volume.ts'; +export { CSS_COMPILER_RENDER_BUDGET } from '../../../../../../../src/renderers/css/volume/compiler-render-budget.ts'; diff --git a/labs/nebula/packages/lab/src/adapters/viewer/compiler-renderer.ts b/labs/nebula/packages/lab/src/adapters/viewer/compiler-renderer.ts index 98cceb9bf4..aeb4448b2b 100644 --- a/labs/nebula/packages/lab/src/adapters/viewer/compiler-renderer.ts +++ b/labs/nebula/packages/lab/src/adapters/viewer/compiler-renderer.ts @@ -3,7 +3,7 @@ import { volumeRenderer } from './volume-renderer'; import type { CompilerViewerBackend } from '@cssearth/volume-viewer/scene/compiler-viewer'; import { presentPhysicalPoseInVolume } from '@cssearth/engine'; import { projectPreparedPoint } from '@cssearth/volume-viewer/camera/point-projection'; -import { transposeWorldRotation, worldRotationFromQuaternion } from '../../../../../../../src/renderers/css/navigation/world-camera-math'; +import { cssViewFromOrientation } from '../../../../../../../src/renderers/css/navigation/world-camera-math'; import type { PreparedCssVolume, VolumeCameraPublication } from '../../../../../../../src/renderers/css/volume/types'; import { assertCompilerBankIdentity, assertCompilerLensGeometry } from '../../server/workflows/compiler/bank-validation.ts'; @@ -13,10 +13,11 @@ export const compilerRenderer: CompilerViewerBackend r[row * 3]! * point[0]! + r[row * 3 + 1]! * point[1]! + r[row * 3 + 2]! * point[2]! + t[row]!); const [px, py] = publication.viewport.principalOffsetPixels; return [publication.viewport.widthPixels! / 2 + px + (eye[0]! - px) * focalPixels / (focalPixels - eye[2]!), @@ -50,6 +52,20 @@ test('posed cloud stays centered, camera orientation is proper, and ordinary-dep assert.throws(() => shapeCloudCamera(frame, image, viewport, { ...framing, zoom: 0 }, 0, 0), /positive extents/); }); +test('prepared compact lights and slab geometry share the same physical camera projection', () => { + const viewport = { width: 900, height: 650 }, framing = { zoom: 1, panX: 21, panY: -17 }; + for (const [yaw, pitch] of [[0, 0], [35, 27], [90, 0], [0, -89]]) { + const camera = shapeCloudCamera(frame, image, viewport, framing, yaw!, pitch!); + const stars = compilerRenderer.starProjection(camera, frame, viewport); + for (const pixel of [[160, 170], [530, 390]] as [number, number][]) { + const point = [(pixel[0] - image.width / 2) * image.unitsPerPixel, + (image.height / 2 - pixel[1]) * image.unitsPerPixel, -1]; + const star = stars.project(point), volume = project(camera, pixel, -point[2]!); + assert.ok(Math.hypot(star.x + viewport.width / 2 - volume[0], star.y + viewport.height / 2 - volume[1]) < 1e-6); + } + } +}); + test('true orthographic CSS transport keeps exact image projection at every depth without large CSS translations', () => { const viewport = { width: 900, height: 650 }, framing = { zoom: 2.5, panX: 21, panY: -17 }; const fit = Math.min(viewport.width / image.width, viewport.height / image.height) * .94 * framing.zoom; @@ -60,10 +76,56 @@ test('true orthographic CSS transport keeps exact image projection at every dept const cx = Math.cos(pitch! * Math.PI / 180), sx = Math.sin(pitch! * Math.PI / 180); for (const z of [-5, 0, 5]) for (const [px, py] of [[0, 0], [768, 534], [213, 421]]) { const x = (px! - image.width / 2) * image.unitsPerPixel, y = (image.height / 2 - py!) * image.unitsPerPixel; - const point = [y * 50, x * 50, z * 50], r = camera.rotation; + const point = [y * 50, x * 50, -z * 50], r = camera.rotation; const actual = [0, 1].map(row => (r[row * 3]! * point[0]! + r[row * 3 + 1]! * point[1]! + r[row * 3 + 2]! * point[2]!) * camera.scale); const expected = [(cy * x - sy * z) * fit / image.unitsPerPixel, (sx * sy * x - cx * y + sx * cy * z) * fit / image.unitsPerPixel]; assert.ok(Math.hypot(actual[0]! - expected[0]!, actual[1]! - expected[1]!) < 1e-9); } } }); + +test('negative source-away depth is nearer and magnifies more than positive source-away depth', () => { + const viewport = { width: 900, height: 650 }, framing = { zoom: 1, panX: 0, panY: 0 }; + const camera = shapeCloudCamera(frame, image, viewport, framing, 0, 0); + assert.ok(camera.world.pose.positionM[2] > 0, 'The physical toward-axis observer must lie at positive local Z.'); + const radius = (sourceAway: number) => { + const point = project(camera, [160, 170], sourceAway); + return Math.hypot(point[0] - viewport.width / 2, point[1] - viewport.height / 2); + }; + assert.ok(radius(-5) > radius(0) && radius(0) > radius(5), 'Near source points must magnify more; this is independent of legacy camera formulas.'); +}); + +test('historical compiler banks transport retained source depth once and agree with their stars', () => { + const oldFrame = { ...frame, referenceFrame: 'lab-sky-angular' }; + const bank: PreparedCssVolume = { schema: 'cssearth-css-volume@1', id: 'old', frame: oldFrame, anchors: [], + resources: [], provenance: {}, approximation: {}, stacks: [{ axis: 'z', leaves: [{ id: 'near', centerUnits: [1, 2, -3], + texturePath: 'pinned.png', widthPx: 1, heightPx: 1, boundsCssPixels: { min: [1, 2, -151], max: [3, 4, -149] }, + style: { width: '1px', height: '1px', transform: 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,100,50,-150,1)', + backgroundSize: '1px 1px', backgroundPosition: '0px 0px' } }] }] }; + const before = structuredClone(bank), actual = physicalLabBank(bank); + assert.deepEqual(bank, before); + assert.deepEqual(actual.stacks[0]!.leaves[0]!.centerUnits, [1, 2, 3]); + assert.equal(actual.frame.referenceFrame, 'lab-sky-west-north-toward'); + assert.match(actual.stacks[0]!.leaves[0]!.style.transform, /100,50,150,1\)$/); + assert.equal(physicalLabBank({ ...bank, frame }).stacks, bank.stacks, 'New prepared geometry must not reflect again.'); + const viewport = { width: 900, height: 650 }, framing = { zoom: 1, panX: 0, panY: 0 }; + const oldCamera = compilerRenderer.camera(oldFrame, image, viewport, framing, 35, 27).publication; + const newCamera = compilerRenderer.camera(frame, image, viewport, framing, 35, 27).publication; + assert.equal(oldCamera.world.referenceFrame, actual.frame.referenceFrame); + assert.doesNotThrow(() => preparedVolumeCameraTransform(oldCamera, actual.frame)); + const historical = compilerRenderer.starProjection(oldCamera, oldFrame, viewport).project([1, 2, -3]); + const current = compilerRenderer.starProjection(newCamera, frame, viewport).project([1, 2, 3]); + assert.deepEqual(historical, current); +}); + +test('legacy Shapes and Joint-fit share the angular-to-physical mount and camera boundary', () => { + for (const referenceFrame of ['lab-sky-angular', 'lab-image-relative-unscaled']) { + const source = { ...frame, referenceFrame, boundsUnits: { min: [-1, -2, -3] as const, max: [4, 5, 6] as const } }; + const actual = physicalLabFrame(source); + assert.deepEqual(actual.boundsUnits, { min: [-1, -2, -6], max: [4, 5, 3] }); + const camera = volumeRenderer.camera(source, image, { width: 900, height: 650 }, { zoom: 1, panX: 0, panY: 0 }, 35, 27); + assert.equal(camera.publication.world.referenceFrame, actual.referenceFrame); + assert.doesNotThrow(() => preparedVolumeCameraTransform(camera.publication, actual)); + assert.equal(source.referenceFrame, referenceFrame, 'Historical receipts stay unchanged.'); + } +}); diff --git a/labs/nebula/packages/lab/src/adapters/viewer/shape-cloud-renderer.ts b/labs/nebula/packages/lab/src/adapters/viewer/shape-cloud-renderer.ts index 13c98b3948..b2fdb7622f 100644 --- a/labs/nebula/packages/lab/src/adapters/viewer/shape-cloud-renderer.ts +++ b/labs/nebula/packages/lab/src/adapters/viewer/shape-cloud-renderer.ts @@ -8,8 +8,12 @@ import type { VolumeCameraPublication } from '../../../../../../../src/renderers export const shapeCloudCameraBackend: ShapeCloudCameraBackend = { cssPixelsPerUnit: 50, publication(frame, image, viewport, framing, rotation, distanceUnits, focalPixels) { + const local = worldRotationFromQuaternion(frame.localToReferenceXyzw); + // Prepared physical axes are west/north/toward. The source-facing CSS presentation has + // z away, so its mapping into the physical frame is a reflection, never a quaternion. + const presentationToReference = [local[0]!, local[1]!, -local[2]!, local[3]!, local[4]!, -local[5]!, local[6]!, local[7]!, -local[8]!]; const world = worldCameraFromCenteredPresentation({ rotation, distanceUnits }, { - ...frame, presentationToReference: worldRotationFromQuaternion(frame.localToReferenceXyzw), + ...frame, presentationToReference, bodyRadiusM: image.width * image.unitsPerPixel * frame.metersPerUnit / 2, }, { focalPixels, principalOffsetPixels: [0, 0] }); return { world, viewport: { widthPixels: viewport.width, heightPixels: viewport.height, focalPixels, diff --git a/labs/nebula/packages/lab/src/adapters/viewer/volume-renderer.ts b/labs/nebula/packages/lab/src/adapters/viewer/volume-renderer.ts index 2770fbcd8b..8a5e21a748 100644 --- a/labs/nebula/packages/lab/src/adapters/viewer/volume-renderer.ts +++ b/labs/nebula/packages/lab/src/adapters/viewer/volume-renderer.ts @@ -4,6 +4,31 @@ import { mountPreparedCssVolume } from '../../../../../../../src/renderers/css/v import { validatePreparedCssVolume } from '../../../../../../../src/renderers/css/volume/validation'; import type { PreparedCssVolume, VolumeCameraPublication } from '../../../../../../../src/renderers/css/volume/types'; import { shapeCloudOrthographicCamera } from './shape-cloud-camera'; +const legacyAngularFrame = (frame: PreparedCssVolume['frame']) => ['lab-sky-angular', 'lab-image-relative-unscaled'].includes(frame.referenceFrame); +/** Rename the runtime-only transported frame; source receipts retain their original frame and pins. */ +export function physicalLabFrame(frame: PreparedCssVolume['frame']): PreparedCssVolume['frame'] { + if (!legacyAngularFrame(frame)) return frame; + return { ...frame, referenceFrame: frame.referenceFrame === 'lab-sky-angular' ? 'lab-sky-west-north-toward' : 'lab-image-west-north-toward', + boundsUnits: { min: [frame.boundsUnits.min[0], frame.boundsUnits.min[1], -frame.boundsUnits.max[2]], + max: [frame.boundsUnits.max[0], frame.boundsUnits.max[1], -frame.boundsUnits.min[2]] } }; +} +/** Historical angular and image-relative Lab banks store source west/north/away coordinates. Transport their retained + * matrices into the same physical west/north/toward basis as current prepared banks. No pixels, + * vertices, texture layout, or correspondence are generated by this compatibility transport. */ +export function physicalLabBank(bank: PreparedCssVolume): PreparedCssVolume { + if (!legacyAngularFrame(bank.frame)) return bank; + return { ...bank, frame: physicalLabFrame(bank.frame), stacks: bank.stacks.map(stack => ({ ...stack, ...(stack.normalUnits ? { normalUnits: [stack.normalUnits[0], stack.normalUnits[1], -stack.normalUnits[2]] as const } : {}), leaves: stack.leaves.map(leaf => { + const match = /^matrix3d\(([^)]+)\)$/.exec(leaf.style.transform); + const matrix = match?.[1]?.split(',').map(Number); + if (!matrix || matrix.length !== 16 || !matrix.every(Number.isFinite)) throw new TypeError('Invalid historical compiler transform.'); + for (const index of [2, 6, 10, 14]) matrix[index] = -matrix[index]!; + const b = leaf.boundsCssPixels; + return { ...leaf, centerUnits: [leaf.centerUnits[0], leaf.centerUnits[1], -leaf.centerUnits[2]] as const, + ...(b ? { boundsCssPixels: { min: [b.min[0], b.min[1], -b.max[2]] as const, max: [b.max[0], b.max[1], -b.min[2]] as const } } : {}), + style: { ...leaf.style, transform: `matrix3d(${matrix.join(',')})` } }; + }) })) }; +} + export const volumeRenderer: VolumeViewerBackend = { validateBank: validatePreparedCssVolume, resources: bank => bank.resources, @@ -11,7 +36,7 @@ export const volumeRenderer: VolumeViewerBackend (['x', 'y', 'z'] as const).flatMap(axis => bank.stacks.find(stack => stack.axis === axis)! .leaves.map(leaf => leaf.texturePath)), mount(host, before, payload, resolveResource) { - const mounted = mountPreparedCssVolume({ host, before, payload, resolveResource }); + const mounted = mountPreparedCssVolume({ host, before, payload: physicalLabBank(payload), resolveResource }); const cameras = [...host.querySelectorAll('.css-volume-camera')]; const scenes = [...host.querySelectorAll('.css-volume-scene')]; const materials = mounted.roots.flatMap((axisRoot, index) => { @@ -30,5 +55,5 @@ export const volumeRenderer: VolumeViewerBackend { + const directory = await realpath(await mkdtemp(join(tmpdir(), 'nebula-module-url-'))); + const dependency = join(directory, 'dependency.ts'), entry = join(directory, 'entry.ts'), outfile = join(directory, 'bundle.mjs'); + const guard = `import { pathToFileURL } from 'node:url'; + const direct = process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href;`; + try { + await writeFile(dependency, `${guard} + if (direct) throw new Error('An imported command ran its entry guard'); + export const source = import.meta.url; + export const spaced = import . meta . url; + export const bracket = import.meta['url']; + export const literal = "import.meta.url"; + export const template = \`literal import.meta.url / \${import.meta.url}\`; + export const pattern = /import.meta.url/.source;`); + await writeFile(entry, `${guard} + import { source, spaced, bracket, literal, template, pattern } from './dependency.ts'; + if (direct) console.log(JSON.stringify({ source, spaced, bracket, literal, template, pattern }));`); + await buildLabModule({ entryPoints: [entry], outfile, bundle: true, platform: 'node', format: 'esm', packages: 'external' }); + const result = spawnSync(process.execPath, [outfile], { encoding: 'utf8', timeout: 10_000 }); + assert.equal(result.status, 0, result.stderr); + const source = pathToFileURL(dependency).href; + assert.deepEqual(JSON.parse(result.stdout), { source, spaced: source, bracket: source, literal: 'import.meta.url', + template: `literal import.meta.url / ${source}`, pattern: 'import.meta.url' }); + } finally { await rm(directory, { recursive: true, force: true }); } +}); diff --git a/labs/nebula/packages/lab/src/cli/build.ts b/labs/nebula/packages/lab/src/cli/build.ts index 43159c41ba..419ddefb68 100644 --- a/labs/nebula/packages/lab/src/cli/build.ts +++ b/labs/nebula/packages/lab/src/cli/build.ts @@ -1,9 +1,39 @@ /** Bundle internal TypeScript owners; native and third-party dependencies remain external. */ +import { readFile, realpath } from 'node:fs/promises'; import { createRequire } from 'node:module'; -import { resolve } from 'node:path'; -import { build, type BuildOptions } from 'esbuild'; +import { dirname, resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { build, type BuildOptions, type Loader } from 'esbuild'; +import ts from 'typescript'; -export function buildLabModule(options: BuildOptions) { +const LOADERS: Record = { '.ts': 'ts', '.mts': 'ts', '.cts': 'ts', '.tsx': 'tsx', '.js': 'js', '.mjs': 'js', '.cjs': 'js', '.jsx': 'jsx' }; + +/** Replace only syntax: source text may also mention the expression inside strings, templates or regexes. */ +function sourceUrls(text: string, path: string): string { + const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true); + const replacements: { start: number; end: number }[] = []; + const visit = (node: ts.Node) => { + const expression = ts.isPropertyAccessExpression(node) && node.name.text === 'url' ? node.expression + : ts.isElementAccessExpression(node) && ts.isStringLiteralLike(node.argumentExpression) && node.argumentExpression.text === 'url' + ? node.expression : undefined; + if (expression && ts.isMetaProperty(expression) && expression.keywordToken === ts.SyntaxKind.ImportKeyword) { + replacements.push({ start: node.getStart(source), end: node.end }); + } else ts.forEachChild(node, visit); + }; + visit(source); + const url = JSON.stringify(pathToFileURL(path).href); + for (const { start, end } of replacements.reverse()) text = text.slice(0, start) + url + text.slice(end); + return text; +} + +export async function buildLabModule(options: BuildOptions) { + const inputs = Array.isArray(options.entryPoints) + ? options.entryPoints.map(entry => typeof entry === 'string' ? entry : entry.in) + : Object.values(options.entryPoints ?? {}); + const entries = new Set(await Promise.all(inputs.map(async entry => { + const path = resolve(options.absWorkingDir ?? process.cwd(), entry); + return options.preserveSymlinks ? path : realpath(path); + }))); return build({ ...options, plugins: [{ name: 'nebula-workspace-source-owners', setup(builder) { @@ -13,5 +43,22 @@ export function buildLabModule(options: BuildOptions) { return { path: require.resolve(args.path) }; }); }, + }, { + // Bundling rewrites every module's `import.meta.url` to the single output file, which breaks the + // standard `import.meta.url === pathToFileURL(process.argv[1]).href` entry-point guard: a bundled + // command-line module sees its own URL equal to the program being run and executes its argument + // parser, throwing a usage error before the real entry does anything. Give each bundled module its + // own source URL back, so only the true entry point still matches `process.argv[1]`. + name: 'nebula-module-source-url', + setup(builder) { + builder.onLoad({ filter: /\.[cm]?[jt]sx?$/ }, async args => { + if (entries.has(args.path)) return undefined; + const text = await readFile(args.path, 'utf8'); + if (!text.includes('import')) return undefined; + const extension = args.path.slice(args.path.lastIndexOf('.')); + return { contents: sourceUrls(text, args.path), + loader: LOADERS[extension] ?? 'ts', resolveDir: dirname(args.path) }; + }); + }, }, ...(options.plugins ?? [])] }); } diff --git a/labs/nebula/packages/lab/src/cli/commands.ts b/labs/nebula/packages/lab/src/cli/commands.ts index 1b75c402ad..bcac5904e4 100644 --- a/labs/nebula/packages/lab/src/cli/commands.ts +++ b/labs/nebula/packages/lab/src/cli/commands.ts @@ -87,5 +87,6 @@ export const labCommands: Record = { "browser-reconstruction-reference": "labs/nebula/packages/lab/browser/browser-reconstruction-reference.ts", "browser-reconstruction-tabs": "labs/nebula/packages/lab/browser/browser-reconstruction-tabs.ts", "browser-lens-levels": "labs/nebula/packages/lab/browser/browser-lens-levels.ts", - "browser-difference-map": "labs/nebula/packages/lab/browser/browser-difference-map.ts" + "browser-difference-map": "labs/nebula/packages/lab/browser/browser-difference-map.ts", + "browser-lens-radial": "labs/nebula/packages/lab/browser/browser-lens-radial.ts" }; diff --git a/labs/nebula/packages/lab/src/cli/commands/acquire-images.ts b/labs/nebula/packages/lab/src/cli/commands/acquire-images.ts index a00a43db95..40102bd63e 100644 --- a/labs/nebula/packages/lab/src/cli/commands/acquire-images.ts +++ b/labs/nebula/packages/lab/src/cli/commands/acquire-images.ts @@ -12,8 +12,14 @@ interface ReferenceImageRecipe { schema: 'cssearth-lab-reference-images@1'; images: { id: string; url: string; sha256: string; bytes: number; width: number; height: number; publisherUrl: string; credit: string; license: string; - output: { path: string; quality: number; effort: number; sha256: string } }[]; + // `resizeWidth` is for a source libwebp cannot encode at native size: the VST Omega Centauri mosaic + // (14540px of a crowded star field) overflows the encoder at every quality, while 8192px encodes. It only + // ever reduces, and the recorded interpretation states the reduction, so a downscale is never silent. + output: { path: string; quality: number; effort: number; sha256: string; resizeWidth?: number } }[]; } +/** sharp reports the sample type; a provenance record states the bit depth a reader recognises. */ +const DEPTH_WORDS: Record = { uchar: '8-bit', ushort: '16-bit', ufloat: '32-bit float', float: '32-bit float' }; + async function hash(path: string) { const digest = createHash('sha256'); for await (const part of createReadStream(path)) digest.update(part); @@ -42,12 +48,21 @@ for (const image of recipe.images) { if (metadata.width !== image.width || metadata.height !== image.height) throw new Error(`Reference dimensions differ: ${image.id}`); const output = resolve(image.output.path); await mkdir(dirname(output), { recursive: true }); - await sharp(original).rotate().toColourspace('srgb').removeAlpha() + const resizeWidth = image.output.resizeWidth; + if (resizeWidth !== undefined && !(Number.isInteger(resizeWidth) && resizeWidth > 0 && resizeWidth < image.width)) { + throw new TypeError(`Reference resizeWidth must be a positive integer below the native width: ${image.id}`); + } + const pipe = sharp(original).rotate().toColourspace('srgb').removeAlpha(); + await (resizeWidth === undefined ? pipe : pipe.resize({ width: resizeWidth })) .webp({ quality: image.output.quality, effort: image.output.effort }).toFile(`${output}.part`); if (await hash(`${output}.part`) !== image.output.sha256) throw new Error(`Reference derivative pin differs: ${image.id}`); await rename(`${output}.part`, output); await writeFile(`${output}.json`, JSON.stringify({ schema: 'cssearth-lab-reference-image@1', source: image, - interpretation: 'Full spatial resolution, converted from publisher 16-bit TIFF to 8-bit sRGB WebP. Lossy display reference; no crop or resize. Original TIFF remains in the ignored cache.', + interpretation: `Converted from the publisher's ${DEPTH_WORDS[metadata.depth ?? ''] ?? `${metadata.depth ?? 'unknown'}-sample`} TIFF to 8-bit sRGB WebP. Lossy display reference; never cropped.${ + resizeWidth === undefined + ? ' Full spatial resolution: not resized.' + : ` Reduced from ${image.width}px to ${resizeWidth}px wide because libwebp cannot encode this source at native size; measure angular scale from the recorded native dimensions, not from this file.` + } Original TIFF remains in the ignored cache.`, outputBytes: (await stat(output)).size }, null, 2) + '\n'); console.log(`REFERENCE_READY ${image.id}: ${image.width}x${image.height}, ${image.output.path}`); } diff --git a/labs/nebula/packages/lab/src/cli/commands/compile-candidates.ts b/labs/nebula/packages/lab/src/cli/commands/compile-candidates.ts index d2e5a20bbd..047e400b27 100644 --- a/labs/nebula/packages/lab/src/cli/commands/compile-candidates.ts +++ b/labs/nebula/packages/lab/src/cli/commands/compile-candidates.ts @@ -8,6 +8,7 @@ import { compileNebula, validateCompilerResult } from '../../server/workflows/co import { jointRecord, jointPath } from '../../features/joint-fit/model.ts'; import { loadDepthModel } from '../../server/workflows/compiler/depth-model.ts'; import { sampledOwnerPins } from '../../features/sampled-prior/ownership.ts'; +import { loadPhotometricPrior } from '../../server/workflows/compiler/photometric-prior.ts'; const [cataloguePath, ...args] = process.argv.slice(2); if (!cataloguePath || args.some(arg => arg !== '--alignment-only' && !/^--object=[a-z0-9-]+$/.test(arg))) { @@ -70,6 +71,8 @@ for (const candidate of selected) { if (recipe.observedStars) inputPaths.push(recipe.observedStars.path); const depth = recipe.depthRecipe ? await loadDepthModel(root, recipe.depthRecipe, recipe.id) : undefined; if (depth) inputPaths.push(depth.recipePath, depth.recipe.evidence.path); + const photometric = recipe.photometricPriorRecipe ? await loadPhotometricPrior(root, recipe.photometricPriorRecipe, recipe.id) : undefined; + if (photometric && recipe.photometricPriorRecipe) inputPaths.push(recipe.photometricPriorRecipe, photometric.recipe.evidence.path); const method: unknown = JSON.parse(await readFile(result.method.path, 'utf8')); if (!jointRecord(method) || !Array.isArray(method.implementation)) throw new TypeError('Missing compiler implementation identity.'); const sampledOwners = recipe.sampledRecipe ? sampledOwnerPins(method, recipe.sampledRecipe) : []; @@ -77,6 +80,9 @@ for (const candidate of selected) { if (depth && (!jointRecord(method.physicalDepth) || !jointRecord(method.physicalDepth.recipe) || !jointRecord(method.physicalDepth.evidence) || method.physicalDepth.recipe.sha256 !== depth.recipeSha256 || method.physicalDepth.evidence.sha256 !== depth.recipe.evidence.sha256)) throw new TypeError('Compiled depth sources differ from the configured recipe or evidence.'); + if (photometric && (!jointRecord(method.photometricPrior) || !jointRecord(method.photometricPrior.recipe) || !jointRecord(method.photometricPrior.evidence) || + method.photometricPrior.recipe.sha256 !== photometric.recipeSha256 || method.photometricPrior.evidence.sha256 !== photometric.recipe.evidence.sha256)) + throw new TypeError('Compiled photometric sources differ from the configured model or evidence.'); for (const owner of method.implementation) { if (!jointRecord(owner) || !jointPath(owner.path) || typeof owner.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(owner.sha256)) throw new TypeError('Invalid compiler implementation owner. Compile again with the current implementation.'); @@ -90,6 +96,9 @@ for (const candidate of selected) { if (depth && (inputs.find(source => source.path === depth.recipePath)?.sha256 !== depth.recipeSha256 || inputs.find(source => source.path === depth.recipe.evidence.path)?.sha256 !== depth.recipe.evidence.sha256)) throw new TypeError('Depth inputs changed during publication. Compile again.'); + if (photometric && (inputs.find(source => source.path === recipe.photometricPriorRecipe)?.sha256 !== photometric.recipeSha256 || + inputs.find(source => source.path === photometric.recipe.evidence.path)?.sha256 !== photometric.recipe.evidence.sha256)) + throw new TypeError('Photometric inputs changed during publication. Compile again.'); await save(resolve(published, `${candidate.id}.json`), { schema: 'cssearth-nebula-compiler-published@1', recipePath: candidate.compilerRecipe, result: resultPin, inputs }); results.push({ id: candidate.id, status: 'complete', result: resultPin, metrics: result.metrics, seconds: (performance.now() - started) / 1000 }); diff --git a/labs/nebula/packages/lab/src/features/compiler/compiler-panel.tsx b/labs/nebula/packages/lab/src/features/compiler/compiler-panel.tsx index bc7c1be5e2..baec51ecdb 100644 --- a/labs/nebula/packages/lab/src/features/compiler/compiler-panel.tsx +++ b/labs/nebula/packages/lab/src/features/compiler/compiler-panel.tsx @@ -50,6 +50,7 @@ function CompilerSession({ recipePath, cataloguePath, observationManifest, publi const controlsChosen = useRef(initialControls !== null); const [controls, setControls] = useState(initialControls ?? { ...defaultCompilerControls }); const [fixedGeometry, setFixedGeometry] = useState(null); + const [fixedDepth, setFixedDepth] = useState(false); const [configuredWeights, setConfiguredWeights] = useState>({}); const [recipeError, setRecipeError] = useState(''); const [presentation, setPresentation] = useState(() => savedPresentation(`${storageKey}:view`)); @@ -71,8 +72,11 @@ function CompilerSession({ recipePath, cataloguePath, observationManifest, publi } const sampled = Boolean(configured.value.sampledRecipe); setFixedGeometry(sampled); + const photometric = Boolean(configured.value.photometricPriorRecipe); + setFixedDepth(photometric); // Sampled geometry has no editable fit controls. Preserve saved fit controls for the standard operator. if (sampled || !controlsChosen.current) setControls(compilerControlsForRecipe(configured.value)); + else if (photometric) setControls(previous => ({ ...previous, depth: 1 })); setConfiguredWeights(configured.value.sourceWeights ?? {}); if (structures.status === 'fulfilled') setCatalogue(structures.value); if (manifest.status === 'fulfilled') setObservations(manifest.value); @@ -176,8 +180,9 @@ function CompilerSession({ recipePath, cataloguePath, observationManifest, publi title="Retain more prepared small-scale image structure in the inferred cloud." onChange={detail => updateControls({ ...controls, detail })} /> updateControls({ ...controls, faint })} /> - updateControls({ ...controls, depth })} /> + {!fixedDepth && updateControls({ ...controls, depth })} />} + {fixedDepth &&

Depth is an inferred realization of the published model.

}

{result ? 'Controls update automatically' : 'Prepared sources restored on compile'}

} {fixedGeometry &&

Fixed reconstructed geometry

} diff --git a/labs/nebula/packages/lab/src/features/compiler/compiler-published.test.ts b/labs/nebula/packages/lab/src/features/compiler/compiler-published.test.ts index f606ef05be..84e31df9d6 100644 --- a/labs/nebula/packages/lab/src/features/compiler/compiler-published.test.ts +++ b/labs/nebula/packages/lab/src/features/compiler/compiler-published.test.ts @@ -63,18 +63,18 @@ test('saved clouds remain inspectable after producer code changes without rewrit }); /** Minimal valid metadata receipt; texture decoding belongs to the volume runtime tests. */ -function completedFixture(options: { depth?: boolean; depthId?: string; ledgerId?: string; declaredEvidenceHash?: string; omitMethodDepth?: boolean; staleSnapshot?: boolean } = {}) { +function completedFixture(options: { depth?: boolean; photometric?: boolean; depthId?: string; ledgerId?: string; declaredEvidenceHash?: string; omitMethodDepth?: boolean; staleSnapshot?: boolean } = {}) { const data = new Map(files), id = '1'.repeat(64), directory = `.local/nebula-lab/compiler/${id}`; const depthPath = 'labs/nebula/models/example/depth.json', evidencePath = 'labs/nebula/models/example/evidence.json'; - const compiler = { ...recipe, ...(options.depth ? { depthRecipe: depthPath } : {}) }; + const compiler = { ...recipe, ...(options.depth ? { depthRecipe: depthPath } : {}), ...(options.photometric ? { photometricPriorRecipe: depthPath } : {}) }; data.set(recipePath, JSON.stringify(compiler)); const inputPaths = [...data.keys()]; const put = (path: string, value: unknown) => { const bytes = JSON.stringify(value); data.set(path, bytes); return { path, sha256: digest(bytes) }; }; let physicalDepth: { recipe: { path: string; sha256: string }; evidence: { path: string; sha256: string } } | undefined; - if (options.depth) { + if (options.depth || options.photometric) { const ledger = { schema: 'cssearth-nebula-physical-evidence@1', subjectId: options.ledgerId ?? recipe.id, sources: [], evidence: [], methods: [] }; const evidence = put(evidencePath, ledger); - const depth = { schema: 'cssearth-nebula-depth-model@1', id: options.depthId ?? recipe.id, + const depth = { schema: options.photometric ? 'cssearth-photometric-mge@1' : 'cssearth-nebula-depth-model@1', id: options.depthId ?? recipe.id, evidence: { ...evidence, sha256: options.declaredEvidenceHash ?? evidence.sha256 } }; put(depthPath, depth); inputPaths.push(depthPath, evidencePath); physicalDepth = { recipe: put(`${directory}/depth.json`, options.staleSnapshot ? { ...depth, historical: true } : depth), @@ -84,7 +84,7 @@ function completedFixture(options: { depth?: boolean; depthId?: string; ledgerId const method = put(`${directory}/method.json`, { recipeSha256: digest(data.get(recipePath)!), implementation: [], request: { action: 'apply', imageId: 'compiler', recipePath, cataloguePath: recipe.structureCatalogue, imageToFrame: {}, evidence: { sensitivity: 1, weights: [] }, controls }, - ...(!options.omitMethodDepth && physicalDepth ? { physicalDepth } : {}) }); + ...(!options.omitMethodDepth && physicalDepth ? options.photometric ? { photometricPrior: physicalDepth } : { physicalDepth } : {}) }); const blob = put(`${directory}/placeholder.json`, {}), bounds = { min: [-1, -1, -1] as [number, number, number], max: [1, 1, 1] as [number, number, number] }; const sky = { min: [-1, -1] as [number, number], max: [1, 1] as [number, number] }; const result: CompilerResult = { schema: 'cssearth-nebula-compiler-result@1', id, label: 'Example', defaultSourceId: 'optical', controls, pipeline: [], @@ -108,6 +108,20 @@ test('legacy and fully pinned depth receipts both restore without processing', a } }); +test('photometric publication requires the exact model and evidence used for the saved volume', async () => { + const good = completedFixture({ photometric: true }); + assert.equal((await loadPublishedCompiler(pointer, recipePath, good.fetchLocal))?.id, good.result.id); + for (const target of ['depthPath', 'evidencePath'] as const) { + const missing = completedFixture({ photometric: true }); + missing.receipt.inputs = missing.receipt.inputs.filter(pin => pin.path !== missing[target]); + await assert.rejects(loadPublishedCompiler(pointer, recipePath, missing.fetchLocal), /configured source|configured evidence/); + } + for (const options of [{ omitMethodDepth: true }, { depthId: 'other' }, { staleSnapshot: true }]) { + const bad = completedFixture({ photometric: true, ...options }); + await assert.rejects(loadPublishedCompiler(pointer, recipePath, bad.fetchLocal), /configured photometric model|configured evidence/); + } +}); + test('a current publication can replace a saved result only for the same controls, evidence and registration', async () => { const fixture = completedFixture(); const expected = readCompilerRequest({ action: 'apply', imageId: 'compiler', recipePath, cataloguePath: recipe.structureCatalogue, diff --git a/labs/nebula/packages/lab/src/features/compiler/compiler-published.ts b/labs/nebula/packages/lab/src/features/compiler/compiler-published.ts index 457a699445..3796378bd2 100644 --- a/labs/nebula/packages/lab/src/features/compiler/compiler-published.ts +++ b/labs/nebula/packages/lab/src/features/compiler/compiler-published.ts @@ -8,8 +8,8 @@ interface Published { recipePath: string; result: Pin; inputs: Pin[] } /** Producer identities are historical metadata; scientific recipes/outputs never match this policy. */ function producerPath(path: string): boolean { return /^labs\/nebula\/(?:src\/.+\.[cm]?tsx?|packages\/(?:lab|volume-core|volume-bake|reconstruction)\/(?:src\/.+\.[cm]?tsx?|package\.json))$/.test(path) || - /^src\/(?:preparation|renderers)\/.+\.[cm]?ts$/.test(path) || - /^tools\/(?:fits\.mts|nebula\/application\/.+\.[cm]?ts)$/.test(path); + /^src\/(?:preparation|renderers|platform)\/.+\.[cm]?ts$/.test(path) || + /^tools\/(?:(?:fits|fits-sky|source-values)\.mts|(?:nebula\/application|objects)\/.+\.[cm]?ts)$/.test(path); } const record = (value: unknown): value is Record => value !== null && typeof value === 'object' && !Array.isArray(value); function pin(value: unknown): Pin { @@ -47,7 +47,8 @@ export async function loadPublishedCompiler(path: string, recipePath: string, fe const recipeBytes = inputs.find(([path]) => path === recipePath)![1]; const recipe = readCompilerRecipe(JSON.parse(new TextDecoder().decode(recipeBytes))); const required = [recipe.observationRecipe, recipe.observationCatalogue, recipe.structureRecipe, recipe.structureCatalogue, - ...(recipe.observedStars ? [recipe.observedStars.path] : []), ...(recipe.jointRecipe ? [recipe.jointRecipe] : []), ...(recipe.depthRecipe ? [recipe.depthRecipe] : []), ...(recipe.sampledRecipe ? [recipe.sampledRecipe] : [])]; + ...(recipe.observedStars ? [recipe.observedStars.path] : []), ...(recipe.jointRecipe ? [recipe.jointRecipe] : []), ...(recipe.depthRecipe ? [recipe.depthRecipe] : []), ...(recipe.sampledRecipe ? [recipe.sampledRecipe] : []), + ...(recipe.photometricPriorRecipe ? [recipe.photometricPriorRecipe] : [])]; if (required.some(path => !inputs.some(([candidate]) => candidate === path))) throw new Error('Prepared nebula receipt does not pin every configured source.'); let depthInputs: { recipe: Pin; evidence: Pin } | undefined; if (recipe.depthRecipe) { @@ -69,6 +70,18 @@ export async function loadPublishedCompiler(path: string, recipePath: string, fe const method: unknown = JSON.parse(new TextDecoder().decode(await checkedBytes(result.method, fetchLocal))); if (!record(method) || method.recipeSha256 !== publication.inputs.find(source => source.path === recipePath)!.sha256 || !Array.isArray(method.implementation)) throw new Error('Prepared nebula method does not match its current recipe.'); + if (recipe.photometricPriorRecipe) { + const model: unknown = JSON.parse(new TextDecoder().decode(inputs.find(([path]) => path === recipe.photometricPriorRecipe)![1])); + if (!record(model) || model.schema !== 'cssearth-photometric-mge@1' || model.id !== recipe.id || !record(method.photometricPrior)) + throw new Error('Prepared nebula omits its configured photometric model.'); + const evidence = pin(model.evidence), snapshot = pin(method.photometricPrior.recipe), evidenceSnapshot = pin(method.photometricPrior.evidence); + if (!evidence.path.startsWith('labs/nebula/models/') || + !publication.inputs.some(input => input.path === evidence.path && input.sha256 === evidence.sha256) || + snapshot.sha256 !== publication.inputs.find(input => input.path === recipe.photometricPriorRecipe)!.sha256 || + evidenceSnapshot.sha256 !== evidence.sha256) + throw new Error('Prepared photometric model differs from its configured evidence.'); + await Promise.all([checkedBytes(snapshot, fetchLocal), checkedBytes(evidenceSnapshot, fetchLocal)]); + } if (recipe.observedStars && (!record(method.observedStars) || !record(method.observedStars.source) || method.observedStars.source.path !== recipe.observedStars.path || method.observedStars.source.sha256 !== recipe.observedStars.sha256 || !publication.inputs.some(input => input.path === recipe.observedStars!.path && input.sha256 === recipe.observedStars!.sha256))) diff --git a/labs/nebula/packages/lab/src/features/compiler/model.ts b/labs/nebula/packages/lab/src/features/compiler/model.ts index 947aabb9db..4fc1306f5d 100644 --- a/labs/nebula/packages/lab/src/features/compiler/model.ts +++ b/labs/nebula/packages/lab/src/features/compiler/model.ts @@ -11,7 +11,7 @@ export interface ObservedStarCataloguePin { path: string; sha256: string } export interface CompilerRequest { action: 'apply'; imageId: 'compiler'; recipePath: string; cataloguePath: string; imageToFrame: Record; evidence: { sensitivity: number; weights: number[] }; controls: CompilerControls } export interface CompilerRecipe { schema: 'cssearth-nebula-compiler@1'; id: string; label: string; observationRecipe: string; - observationCatalogue: string; structureRecipe: string; structureCatalogue: string; jointRecipe?: string; depthRecipe?: string; sampledRecipe?: string; + observationCatalogue: string; structureRecipe: string; structureCatalogue: string; jointRecipe?: string; depthRecipe?: string; sampledRecipe?: string; photometricPriorRecipe?: string; defaultSourceId: string; maximumStars: number; interpretation: string; defaultControls?: CompilerControls; sourceWeights?: Record; starCatalogue?: CompilerStarCatalogue; observedStars?: ObservedStarCataloguePin; targetControls?: CompilerTargetControls; emissionWindow?: CompilerEmissionWindow } const finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v); @@ -33,11 +33,14 @@ export function readCompilerRecipe(v: unknown): CompilerRecipe { !jointPath(v.observationRecipe) || !jointPath(v.observationCatalogue) || !jointPath(v.structureRecipe) || !jointPath(v.structureCatalogue) || (v.jointRecipe !== undefined && !jointPath(v.jointRecipe)) || (v.depthRecipe !== undefined && (!jointPath(v.depthRecipe) || !v.depthRecipe.startsWith('labs/nebula/models/'))) || (v.sampledRecipe !== undefined && (!jointPath(v.sampledRecipe) || !v.sampledRecipe.startsWith('labs/nebula/models/'))) || - [v.jointRecipe, v.depthRecipe, v.sampledRecipe].filter(value => value !== undefined).length > 1 || typeof v.defaultSourceId !== 'string' || !range(v.maximumStars, 0, 2000) || !Number.isInteger(v.maximumStars) || typeof v.interpretation !== 'string') throw new TypeError('Invalid compiler recipe.'); + (v.photometricPriorRecipe !== undefined && (!jointPath(v.photometricPriorRecipe) || !v.photometricPriorRecipe.startsWith('labs/nebula/models/'))) || + [v.jointRecipe, v.depthRecipe, v.sampledRecipe, v.photometricPriorRecipe].filter(value => value !== undefined).length > 1 || typeof v.defaultSourceId !== 'string' || !range(v.maximumStars, 0, 2000) || !Number.isInteger(v.maximumStars) || typeof v.interpretation !== 'string') throw new TypeError('Invalid compiler recipe.'); const targetControls = v.targetControls === undefined ? undefined : readCompilerTargetControls(v.targetControls); const emissionWindow = v.emissionWindow === undefined ? undefined : readCompilerEmissionWindow(v.emissionWindow); if (emissionWindow && v.sampledRecipe !== undefined) throw new TypeError('Image emission windows require the emission-field route.'); const controls = v.defaultControls === undefined ? undefined : readCompilerControls(v.defaultControls); + if (v.photometricPriorRecipe && controls && controls.depth !== 1) + throw new TypeError('Photometric prior controls require depth=1.'); const starCatalogue = v.starCatalogue === undefined ? undefined : readCompilerStarCatalogue(v.starCatalogue); const observedStars = v.observedStars === undefined ? undefined : readObservedStarCataloguePin(v.observedStars); if (observedStars && (starCatalogue || v.sampledRecipe)) throw new TypeError('Choose one supported stellar catalogue route.'); @@ -51,7 +54,8 @@ export function readCompilerRecipe(v: unknown): CompilerRecipe { sourceWeights = Object.fromEntries(Object.entries(v.sourceWeights).map(([id, weight]) => [id, Number(weight)])); } return { schema: v.schema, id: v.id, label: v.label, observationRecipe: v.observationRecipe, observationCatalogue: v.observationCatalogue, - structureRecipe: v.structureRecipe, structureCatalogue: v.structureCatalogue, jointRecipe: v.jointRecipe, ...(v.depthRecipe ? { depthRecipe: v.depthRecipe } : {}), ...(v.sampledRecipe ? { sampledRecipe: v.sampledRecipe } : {}), defaultSourceId: v.defaultSourceId, + structureRecipe: v.structureRecipe, structureCatalogue: v.structureCatalogue, jointRecipe: v.jointRecipe, ...(v.depthRecipe ? { depthRecipe: v.depthRecipe } : {}), ...(v.sampledRecipe ? { sampledRecipe: v.sampledRecipe } : {}), + ...(v.photometricPriorRecipe ? { photometricPriorRecipe: v.photometricPriorRecipe } : {}), defaultSourceId: v.defaultSourceId, maximumStars: v.maximumStars, interpretation: v.interpretation, ...(controls ? { defaultControls: controls } : {}), ...(sourceWeights ? { sourceWeights } : {}), ...(starCatalogue ? { starCatalogue } : {}), ...(observedStars ? { observedStars } : {}), ...(targetControls ? { targetControls } : {}), ...(emissionWindow ? { emissionWindow } : {}) }; } diff --git a/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.css b/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.css new file mode 100644 index 0000000000..77887b8139 --- /dev/null +++ b/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.css @@ -0,0 +1,60 @@ +.lens-radial-legend { + display: flex; + align-items: center; + gap: 5px; + margin: 10px 0 4px; + font-size: 11px; + color: var(--text-secondary); +} +.lens-radial-key { + display: inline-block; + width: 14px; + height: 2px; +} +.lens-radial-legend .lens-radial-key:not(:first-child) { + margin-left: 8px; +} +.lens-radial-status, +.lens-radial-note { + margin: 6px 0 0; + font-size: 10px; + line-height: 1.45; + color: var(--text-muted); + overflow-wrap: anywhere; +} +.lens-radial-status[data-error="true"] { + color: #e8998c; +} +.lens-radial-plot { + display: block; + width: 100%; + height: auto; + margin-top: 4px; + background: #0b0d11; + border-radius: 4px; +} +.lens-radial-plot .lens-radial-frame { + fill: #0b0d11; + stroke: #2a2f3a; + stroke-width: 1; +} +.lens-radial-plot .lens-radial-grid { + stroke: #1d222b; + stroke-width: 1; +} +.lens-radial-plot .lens-radial-zero { + stroke: #5b6472; + stroke-width: 1; +} +.lens-radial-plot .lens-radial-axis { + font-size: 7px; + fill: #9aa3b2; +} +.lens-radial-numbers { + margin: 6px 0 0; + font-family: ui-monospace, Menlo, monospace; + font-size: 10px; + line-height: 1.5; + color: #c8cfdb; + overflow-wrap: anywhere; +} diff --git a/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.test.ts b/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.test.ts new file mode 100644 index 0000000000..8ef49ded81 --- /dev/null +++ b/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.test.ts @@ -0,0 +1,60 @@ +import assert from 'node:assert/strict'; +import { createServer } from 'node:http'; +import test from 'node:test'; +import { build } from 'esbuild'; +import { chromium } from 'playwright'; + +test('radial panel plots dark bins and replaces the measurement when the lens changes', async () => { + const root = process.cwd(); + const fixture = await build({ stdin: { loader: 'tsx', resolveDir: root, contents: ` + import { useState } from 'react'; import { createRoot } from 'react-dom/client'; + import { LensRadialPanel } from './labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel'; + function App() { const [id, setId] = useState('a'.repeat(64)); + return <>; } + createRoot(document.getElementById('fixture')).render();` }, + bundle: true, write: false, format: 'iife', platform: 'browser', outfile: 'fixture.js', + loader: { '.css': 'empty' }, jsx: 'automatic' }); + const script = fixture.outputFiles[0]?.text; + assert.ok(script); + const server = createServer((request, response) => { + const url = new URL(request.url ?? '/', 'http://localhost'); + if (url.pathname === '/__nebula/reconstruction-radial') { + const resultId = url.searchParams.get('resultId'); + response.setHeader('Content-Type', 'application/json'); + response.end(JSON.stringify({ schema: 'cssearth-nebula-lens-radial@1', resultId, + imageId: resultId?.startsWith('a') ? 'first-lens' : 'second-lens', + grid: { width: 10, height: 10 }, bins: 3, footprintPixels: 100, maxRadius: 5, + radialBins: [0, 1, 2].map(index => ({ radius: index + 1, pixels: 10, + sourceMean: 100, renderMean: index ? 100 : 0, ratio: index ? 1 : 0, signedDelta: index ? 0 : -100 })), + halfLightRadiusSource: 2, halfLightRadiusRender: 3, halfLightRadiusRatio: 1.5, + rmsLogRatio: 20, worstBin: { radius: 1, ratio: 0, pixels: 10 }, note: 'Test measurement' })); + } else { + response.setHeader('Content-Type', url.pathname === '/fixture.js' ? 'text/javascript' : 'text/html'); + response.end(url.pathname === '/fixture.js' ? script : '
'); + } + }); + await new Promise(done => server.listen(0, '127.0.0.1', done)); + const address = server.address(); + assert.ok(address && typeof address !== 'string'); + const browser = await chromium.launch({ headless: true }); + try { + const page = await browser.newPage(), errors: string[] = []; + page.on('pageerror', error => errors.push(error.message)); + await page.goto(`http://127.0.0.1:${address.port}`); + for (const id of ['a', 'b']) { + await page.waitForSelector(`[data-lens-radial-state="ready"][data-lens-radial-result="${id.repeat(64)}"]`); + const lines = page.locator('.lens-radial-plot polyline'); + assert.equal(await lines.count(), 3); + const points = (await lines.nth(2).getAttribute('points'))?.split(' ') ?? []; + assert.equal(points.length, 3, 'the zero-ratio core must remain plotted'); + assert.ok(Number(points[0]?.split(',')[1]) > Number(points[1]?.split(',')[1]), 'the dark core must be below the matched annulus'); + assert.match(await page.locator('.lens-radial-numbers').innerText(), /worst ×0\.00/); + assert.match(await page.locator('.lens-radial-status').innerText(), id === 'a' ? /first-lens/ : /second-lens/); + if (id === 'a') await page.getByRole('button', { name: 'Next lens' }).click(); + } + assert.deepEqual(errors, []); + } finally { + await browser.close(); + await new Promise(done => server.close(() => done())); + } +}); diff --git a/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.tsx b/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.tsx new file mode 100644 index 0000000000..6d5eb40c39 --- /dev/null +++ b/labs/nebula/packages/lab/src/features/reconstruction/lens-radial-panel.tsx @@ -0,0 +1,108 @@ +/** + * Live radial profile for the displayed image lens, drawn as inline SVG: does brightness fall off with radius + * the way the source does? + * + * Levels (a histogram) can match p50/p90/p99 exactly while the structure sits in the wrong place; the + * difference map shows where the error is but not its radial shape. This panel plots azimuthally averaged + * source and render brightness against radius from the footprint's own centroid, plus their ratio, so a + * brightness swap between the centre and an annulus — invisible to a histogram — reads as a curve that + * departs from the render÷source = 1 line. Every number comes from `/__nebula/reconstruction-radial`; nothing + * is measured here. + */ +import { useEffect, useState } from 'react'; +import type { LensRadialBin, LensRadialProfile } from '../../server/services/lens-radial.ts'; +import './lens-radial-panel.css'; + +const WIDTH = 320, HEIGHT = 150; +const PLOT = { x: 34, y: 8, w: 280, h: 74 }; +const RATIO = { x: 34, y: 94, w: 280, h: 40 }; +const SOURCE_STROKE = '#c9ced9', RENDER_STROKE = '#48c9c0', RATIO_STROKE = '#e0b34a'; +export const RADIAL_TOOLTIP = 'Radial profile · brightness vs radius, render against this image'; +/** Concentric-rings glyph for the floating Radial profile tool button. */ +export const RadialIcon = () => ; + +function polyline(points: string[], stroke: string) { + return points.length > 1 + ? : null; +} + +function RadialPlot({ profile }: { profile: LensRadialProfile }) { + const defined = profile.radialBins.filter((bin): bin is LensRadialBin & { sourceMean: number; renderMean: number } => + bin.pixels > 0 && bin.sourceMean !== null && bin.renderMean !== null); + const peak = Math.max(1, ...defined.flatMap(bin => [bin.sourceMean, bin.renderMean])); + const maxRadius = Math.max(1, profile.maxRadius); + const at = (radius: number, value: number, box: typeof PLOT) => + `${(box.x + radius / maxRadius * box.w).toFixed(1)},${(box.y + box.h - Math.max(0, value) / peak * box.h).toFixed(1)}`; + const sourceLine = defined.map(bin => at(bin.radius, bin.sourceMean, PLOT)); + const renderLine = defined.map(bin => at(bin.radius, bin.renderMean, PLOT)); + const ratioBins = profile.radialBins.filter((bin): bin is LensRadialBin & { ratio: number } => bin.ratio !== null); + const logRatio = (ratio: number) => Math.log(Math.max(Number.EPSILON, ratio)); + const ratioPeak = Math.max(1, ...ratioBins.map(bin => Math.abs(logRatio(bin.ratio)))); + const ratioLine = ratioBins.map(bin => `${(RATIO.x + bin.radius / maxRadius * RATIO.w).toFixed(1)},` + + `${(RATIO.y + RATIO.h / 2 - logRatio(bin.ratio) / ratioPeak * (RATIO.h / 2 - 2)).toFixed(1)}`); + return + + {[.25, .5, .75].map(fraction => )} + {polyline(sourceLine, SOURCE_STROKE)} + {polyline(renderLine, RENDER_STROKE)} + brightness + + + {polyline(ratioLine, RATIO_STROKE)} + render ÷ source (log) + {[0, .5, 1].map(fraction => {Math.round(fraction * maxRadius)}px)} + ; +} + +/** Measures while mounted; the floating Radial profile tool mounts it only while its panel is open. */ +export function LensRadialPanel({ resultId }: { resultId?: string }) { + const [state, setState] = useState<{ status: 'idle' | 'loading' | 'ready' | 'error'; profile?: LensRadialProfile; error?: string }>({ status: 'idle' }); + useEffect(() => { + if (!resultId) { setState({ status: 'idle' }); return; } + const controller = new AbortController(); + setState({ status: 'loading' }); + void (async () => { + try { + const response = await fetch(`/__nebula/reconstruction-radial?resultId=${encodeURIComponent(resultId)}`, { signal: controller.signal }); + const value = await response.json(); + if (!response.ok) throw new Error(value.error ?? `Radial profile unavailable (HTTP ${response.status}).`); + if (value.schema !== 'cssearth-nebula-lens-radial@1' || value.resultId !== resultId || !Array.isArray(value.radialBins)) + throw new TypeError('Invalid radial profile measurement.'); + if (!controller.signal.aborted) setState({ status: 'ready', profile: value as LensRadialProfile }); + } catch (error) { + if (!controller.signal.aborted) setState({ status: 'error', error: error instanceof Error ? error.message : String(error) }); + } + })(); + return () => controller.abort(); + }, [resultId]); + const profile = state.profile; + return
+ {state.status === 'error' &&

{state.error}

} + {state.status === 'loading' &&

Measuring this lens…

} + {profile && <> +

+ source image + render + ratio +

+ +

+ half-light radius {profile.halfLightRadiusSource?.toFixed(1) ?? '—'}px → {profile.halfLightRadiusRender?.toFixed(1) ?? '—'}px + {' '}(×{profile.halfLightRadiusRatio?.toFixed(2) ?? '—'})
+ rms log ratio {profile.rmsLogRatio?.toFixed(2) ?? '—'} · + {' '}worst {profile.worstBin ? `×${profile.worstBin.ratio.toFixed(2)} @${profile.worstBin.radius.toFixed(0)}px` : '—'} +

+

+ {profile.imageId} · grid {profile.grid.width}×{profile.grid.height} · footprint {profile.footprintPixels.toLocaleString()} px · + {' '}{profile.bins} bins to {profile.maxRadius.toFixed(0)}px +

+

{profile.note}

+ } +
; +} diff --git a/labs/nebula/packages/lab/src/features/reconstruction/reconstruction-controls-react.tsx b/labs/nebula/packages/lab/src/features/reconstruction/reconstruction-controls-react.tsx index 4b5c6d91cb..ec2672d752 100644 --- a/labs/nebula/packages/lab/src/features/reconstruction/reconstruction-controls-react.tsx +++ b/labs/nebula/packages/lab/src/features/reconstruction/reconstruction-controls-react.tsx @@ -10,6 +10,7 @@ import { readCloudAppearance, saveCloudAppearance } from './cloud-appearance-sto import { CloudAppearanceControls } from './cloud-appearance-controls'; import { LensLevelsPanel, LevelsIcon, LEVELS_TOOLTIP } from './lens-levels-panel'; import { differenceTool } from './difference-map'; +import { LensRadialPanel, RadialIcon, RADIAL_TOOLTIP } from './lens-radial-panel'; import type { DifferenceOverlayState } from '../legacy-viewer/difference-plane'; import { saveLensSettings } from './lens-settings-export.ts'; import { ImageCredit } from '../workspace/image-credit'; @@ -276,10 +277,12 @@ export function ReconstructionControls({ context, viewerBusy: busy, onSelect, ca {view.appearanceDirty && !view.running && !view.error && !view.processDisabled ? 'Changes ready · Preview to apply.' : view.text}