# Balloon
## Microsim
### Live player
<div class="microsim-player">
<iframe src="https://editor.p5js.org/sciencenibber/full/JJ37eYM7T" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe>
</div>
<div class="microsim-fallback">
<img src="Microsims/thumbs/Balloon.png" alt="Balloon microsim poster" style="width:100%;border:1px solid #4445;border-radius:6px;">
<p><em>Live microsim (desktop) · <a href="https://editor.p5js.org/sciencenibber/sketches/JJ37eYM7T">open sketch in the p5.js editor</a></em></p>
</div>
**Editor URL:** https://editor.p5js.org/sciencenibber/sketches/JJ37eYM7T
**Description (100 words):**
A side-view ascent simulator. A shaded balloon hovers in a 30-km atmospheric column tinted by air density. Four sliders let the reader pick the [[Lifting_gas|lifting gas]] (helium, hydrogen, hot air, methane), the sea-level envelope volume V_0, the payload mass, and an ascent-speed multiplier. Press play and the balloon climbs along a drag-limited terminal [[Velocity|velocity]]; as it rises, ambient pressure falls and the envelope expands by Boyle's law (V grows visibly with altitude). A dashed magenta line marks the calculated equilibrium altitude z_eq, and a right-side panel reads out live rho_air, rho_gas, V(z), F_lift, F_net, and z to show the buoyancy budget exactly where it tips negative.
```js
// =====================================================================
// Balloon.js -- Wikitube microsim
// Article: Balloon en.wikitube.io/wiki/Balloon
// Room: Helium Pattern: 8 (Geometry crossover --
// topological / spatial visualization)
// ---------------------------------------------------------------------
// Idea: a side-view ascent simulator for a buoyant balloon in the
// US Standard Atmosphere. The reader picks a lifting gas (helium,
// hydrogen, hot air, or methane), sets the sea-level envelope volume
// and the payload mass, and watches the balloon climb until net lift
// goes to zero. As the balloon rises ambient pressure drops and the
// envelope expands (Boyle's law at constant T), so the shaded
// ellipse grows visibly with altitude -- the article's central
// spatial fact, made interactive.
//
// Physics laid out on the canvas:
//
// F_lift = (rho_air - rho_gas) * V * g [buoyancy]
// F_net = F_lift - m_payload * g [free body]
// P V = constant [Boyle, T fixed]
// rho_air = rho_0 * exp(-z / H) [isothermal atm]
//
// Equilibrium altitude z_eq is where rho_air(z) * V(z) equals the
// total system mass m_gas + m_payload. The integrator walks the
// balloon up the column with a simple drag-limited terminal velocity
// so the ascent feels readable rather than instantaneous.
//
// Atmosphere: a simplified two-region model -- exponential decay of
// density with scale height H = 8.5 km up to the tropopause (~11 km),
// then a slower decay above. Good enough to land equilibrium
// altitudes within ~10% of a NASA US-Std-1976 reference, which is
// the right precision for the microsim's pedagogical job.
//
// Visual layout (720 x 520 canvas):
// * top-left: HUD title + en.wikitube.io/wiki/Balloon subtitle
// * top-right: control hints (play / pause / reset, gas-cycle)
// * left band: altitude axis 0 - 30 km, atmospheric-density tint
// * center: the balloon -- shaded ellipse + payload box + tether
// * right band: live readout panel (V, rho_air, rho_gas, F_lift,
// F_net, current altitude, equilibrium altitude)
// * bottom: four sliders (gas idx, V_0 in m^3, m_payload in kg,
// ascent speed multiplier) + canonical equation
//
// Conventions (Wikitube Betterfire Standard v0):
// * single ARTICLE constant at the top, single quotes
// * p5.disableFriendlyErrors = true to keep the editor console clean
// * non-ASCII (Greek rho, dot, arrow) lives in COMMENTS ONLY;
// every text() string literal is ASCII
// * Energy-room palette (P5_JS_EDITOR section 4, line 165)
// * all createSlider calls carry .position(x, y).size(w)
// =====================================================================
const ARTICLE = 'Balloon';
const TITLE = ARTICLE.replace(/_/g, ' ');
p5.disableFriendlyErrors = true;
// ----- Energy room palette (P5_JS_EDITOR section 4, line 165) --------
const BG = 18;
const FG = 240;
const DIM = [240, 240, 240, 140];
const HOT = [220, 110, 60]; // warm: hot-air gas, equation
const COLD = [60, 130, 220]; // cool: atmosphere tint
const COLDER = [40, 80, 180]; // deep cool: high-altitude tint
const STRUCT = [120, 130, 150]; // structural grey: payload, axis
const TRAJ = [240, 220, 80]; // yellow accent: balloon envelope
const SCRATCH = [120, 120, 120, 90]; // grid scratch lines
const ACCENT = [200, 100, 220]; // tether / highlight
// ----- Physical constants -------------------------------------------
const G = 9.80665; // m/s^2, standard gravity
const T_AMBIENT = 288.15; // K, sea-level temperature
const P0 = 101325; // Pa, sea-level pressure
const RHO_0 = 1.225; // kg/m^3, sea-level air density
const R_SPEC_AIR = 287.05; // J/(kg*K), specific gas const, air
const H_SCALE = 8500; // m, scale height (isothermal atm)
const Z_TROPO = 11000; // m, tropopause altitude
const Z_MAX = 30000; // m, plot ceiling
// ----- Gas catalog -- molar mass drives the density at T_AMBIENT, P0
// rho = P * M / (R_univ * T); we precompute rho_0 for each gas. The
// hot-air entry uses the rho at the chosen burner temperature (388 K).
const R_UNIV = 8.31446; // J/(mol*K), universal gas const
const GASES = [
// [label, M (kg/mol), T_gas (K), color]
['Helium', 0.0040026, T_AMBIENT, [180, 220, 255]],
['Hydrogen', 0.0020159, T_AMBIENT, [255, 200, 200]],
['Hot air', 0.028964, 388.15, [255, 170, 80]],
['Methane', 0.016043, T_AMBIENT, [160, 255, 180]]
];
function gasDensity(gIdx) {
const [, M, T_gas] = GASES[gIdx];
return (P0 * M) / (R_UNIV * T_gas);
}
// ----- Atmosphere model ---------------------------------------------
// Two-region exponential: scale height H = 8500 m below tropopause,
// then a softer decay above (effective H' = 6000 m) so the model
// doesn't run too rich at 25-30 km.
function rhoAir(z) {
if (z <= Z_TROPO) {
return RHO_0 * Math.exp(-z / H_SCALE);
}
const rho_tropo = RHO_0 * Math.exp(-Z_TROPO / H_SCALE);
return rho_tropo * Math.exp(-(z - Z_TROPO) / 6000);
}
function pAir(z) {
// Same form for P, since isothermal scaling gives P proportional to rho.
if (z <= Z_TROPO) {
return P0 * Math.exp(-z / H_SCALE);
}
const p_tropo = P0 * Math.exp(-Z_TROPO / H_SCALE);
return p_tropo * Math.exp(-(z - Z_TROPO) / 6000);
}
// Envelope volume from Boyle's law at constant T_gas:
// P_inside = P_air(z), so V(z) = V_0 * P_0 / P_air(z)
function envelopeVolume(V0, z) {
return V0 * P0 / pAir(z);
}
// ----- Sliders + state ----------------------------------------------
let gasSlider, volumeSlider, payloadSlider, speedSlider;
let playBtn, resetBtn, gasBtn;
let gIdx = 0; // 0 = helium (default)
let z_current = 0; // m, current altitude
let v_current = 0; // m/s, current vertical velocity
let playing = false;
let lastReset = 0;
// ----- Layout rectangles (set in setup) -----------------------------
let columnX, columnY, columnW, columnH;
let readoutX, readoutY, readoutW, readoutH;
function setup() {
createCanvas(720, 520);
pixelDensity(2);
textFont('system-ui');
// Side view: altitude column on the left, payload column in middle,
// numerical readout column on the right.
columnX = 70;
columnY = 60;
columnW = 280;
columnH = 360;
readoutX = columnX + columnW + 30;
readoutY = columnY;
readoutW = width - readoutX - 30;
readoutH = columnH;
// Sliders along the bottom strip. Each carries explicit position+size
// per Betterfire Standard (P5_JS_EDITOR section 2).
const sliderY = height - 60;
gasSlider = createSlider(0, GASES.length - 1, 0, 1)
.position(70, sliderY).size(120);
volumeSlider = createSlider(1, 200, 30, 1)
.position(220, sliderY).size(120);
payloadSlider = createSlider(0, 80, 5, 1)
.position(370, sliderY).size(120);
speedSlider = createSlider(1, 200, 50, 1)
.position(520, sliderY).size(120);
// Buttons sit above the sliders.
playBtn = createButton('play / pause')
.position(70, height - 30).size(110, 22);
playBtn.mousePressed(() => { playing = !playing; });
resetBtn = createButton('reset')
.position(190, height - 30).size(80, 22);
resetBtn.mousePressed(() => { z_current = 0; v_current = 0; playing = false; });
}
function draw() {
background(BG);
// Pull every slider value once at the top of draw().
gIdx = gasSlider.value();
const V0 = volumeSlider.value(); // m^3 sea-level envelope
const m_payload = payloadSlider.value(); // kg
const speedMult = speedSlider.value() / 50; // 1 -> 1x; 200 -> 4x
const rho_gas_0 = gasDensity(gIdx);
const m_gas = rho_gas_0 * V0;
// Net force at current altitude (drives the integrator).
const rho_a = rhoAir(z_current);
const V_z = envelopeVolume(V0, z_current);
// Gas mass is conserved; gas density scales with the expanded volume.
const rho_g = m_gas / V_z;
const F_lift = (rho_a - rho_g) * V_z * G;
const F_net = F_lift - m_payload * G;
// Equilibrium altitude: scan the column for the height where
// (rho_air(z) - rho_gas(z)) * V(z) * g - m_payload * g changes sign.
const z_eq = findEquilibrium(V0, m_gas, m_payload);
// Integrate ascent with a simple drag-limited terminal velocity.
// Drag balances net force at v_term ~ sqrt(2 |F_net| / (rho_a * Cd * A)).
if (playing) {
const A_cross = Math.PI * Math.pow((3 * V_z) / (4 * Math.PI), 2 / 3); // cross section of a sphere of volume V
const Cd = 0.47;
const v_term = Math.sign(F_net) *
Math.sqrt(2 * Math.abs(F_net) / (rho_a * Cd * A_cross + 1e-6));
// Relax toward terminal velocity.
v_current += (v_term - v_current) * 0.08;
z_current += v_current * (deltaTime / 1000) * speedMult;
if (z_current < 0) { z_current = 0; v_current = 0; }
if (z_current > Z_MAX) { z_current = Z_MAX; v_current = 0; }
}
drawColumn(z_eq);
drawBalloon(V_z, z_current);
drawReadout(rho_a, rho_g, V_z, F_lift, F_net, z_eq, m_gas, m_payload);
drawSliderLabels(V0, m_payload, speedMult);
drawHUD();
drawEquation();
}
// =====================================================================
// Equilibrium-altitude scan
// =====================================================================
// Walk the column from 0 to Z_MAX in 200 steps; equilibrium is the
// first z where lift turns negative. Returns Z_MAX if balloon never
// reaches equilibrium (over-buoyant) or -1 if it cannot lift off.
function findEquilibrium(V0, m_gas, m_payload) {
const N = 200;
let prevF = ((RHO_0) - (m_gas / V0)) * V0 * G - m_payload * G;
if (prevF <= 0) return -1; // can't lift off
for (let i = 1; i <= N; i++) {
const z = (i / N) * Z_MAX;
const V_z = envelopeVolume(V0, z);
const F = (rhoAir(z) - m_gas / V_z) * V_z * G - m_payload * G;
if (F <= 0) {
// Linear interpolate between the bracketing steps.
const zPrev = ((i - 1) / N) * Z_MAX;
const frac = prevF / (prevF - F);
return zPrev + frac * (z - zPrev);
}
prevF = F;
}
return Z_MAX;
}
// =====================================================================
// Drawing
// =====================================================================
// ----- atmospheric column with altitude axis ------------------------
function drawColumn(z_eq) {
// Background gradient: dense at the bottom, thin at the top.
noStroke();
const NBANDS = 60;
for (let i = 0; i < NBANDS; i++) {
const z = (i / NBANDS) * Z_MAX;
const rho = rhoAir(z);
const alpha = map(rho, 0, RHO_0, 30, 180);
const r = lerp(COLDER[0], COLD[0], rho / RHO_0);
const g = lerp(COLDER[1], COLD[1], rho / RHO_0);
const b = lerp(COLDER[2], COLD[2], rho / RHO_0);
fill(r, g, b, alpha);
const y0 = map(z + Z_MAX / NBANDS, 0, Z_MAX, columnY + columnH, columnY);
const y1 = map(z, 0, Z_MAX, columnY + columnH, columnY);
rect(columnX, y0, columnW, y1 - y0 + 1);
}
// Altitude axis ticks (every 5 km).
stroke(...STRUCT); strokeWeight(1); fill(...STRUCT); textSize(10);
textAlign(RIGHT, CENTER);
for (let z = 0; z <= Z_MAX; z += 5000) {
const y = map(z, 0, Z_MAX, columnY + columnH, columnY);
line(columnX - 4, y, columnX, y);
noStroke();
text(nf(z / 1000, 1, 0) + ' km', columnX - 8, y);
stroke(...STRUCT);
}
// Tropopause marker.
const yTropo = map(Z_TROPO, 0, Z_MAX, columnY + columnH, columnY);
stroke(...DIM); strokeWeight(1); drawingContext.setLineDash([4, 4]);
line(columnX, yTropo, columnX + columnW, yTropo);
drawingContext.setLineDash([]);
noStroke(); fill(...DIM); textSize(10);
textAlign(LEFT, BOTTOM);
text('tropopause', columnX + 6, yTropo - 2);
// Equilibrium-altitude dashed line.
if (z_eq > 0 && z_eq < Z_MAX) {
const yEq = map(z_eq, 0, Z_MAX, columnY + columnH, columnY);
stroke(...ACCENT, 200); strokeWeight(1.2);
drawingContext.setLineDash([6, 4]);
line(columnX, yEq, columnX + columnW, yEq);
drawingContext.setLineDash([]);
noStroke(); fill(...ACCENT); textSize(10);
textAlign(LEFT, BOTTOM);
text('z_eq = ' + nf(z_eq / 1000, 1, 1) + ' km', columnX + 6, yEq - 2);
}
// Ground.
fill(...STRUCT); noStroke();
rect(columnX, columnY + columnH, columnW, 4);
}
// ----- balloon at current altitude ----------------------------------
function drawBalloon(V_z, z) {
// Map balloon volume to a pixel radius. Use cube root so volume
// grows visibly without overflowing the canvas at high altitude.
// r_px = K * V^(1/3); K chosen so V=30 m^3 -> r=26 px.
const r_px = 26 * Math.pow(V_z / 30, 1 / 3);
const xc = columnX + columnW / 2;
const yc = map(z, 0, Z_MAX, columnY + columnH - 14, columnY + 30);
// Tether to the payload box.
stroke(...ACCENT); strokeWeight(1);
line(xc, yc + r_px, xc, yc + r_px + 18);
// Payload box (5 px tall, scales gently with payload mass).
const m_payload = payloadSlider.value();
const boxH = 5 + Math.min(m_payload * 0.2, 12);
fill(...STRUCT); noStroke();
rectMode(CENTER);
rect(xc, yc + r_px + 18 + boxH / 2, 16, boxH, 1);
rectMode(CORNER);
// Envelope: shaded ellipse for a 3D feel. Highlight a quarter-circle.
const gasCol = GASES[gIdx][3];
noStroke();
// Soft outer glow.
fill(gasCol[0], gasCol[1], gasCol[2], 60);
ellipse(xc, yc, r_px * 2.4, r_px * 2.6);
// Main envelope.
fill(gasCol[0], gasCol[1], gasCol[2], 220);
ellipse(xc, yc, r_px * 2, r_px * 2.2);
// Highlight crescent (upper-left).
fill(255, 255, 255, 70);
ellipse(xc - r_px * 0.35, yc - r_px * 0.45, r_px * 0.9, r_px * 0.7);
// Outline.
stroke(...TRAJ, 200); strokeWeight(1.2); noFill();
ellipse(xc, yc, r_px * 2, r_px * 2.2);
}
// ----- right-side numerical readout ---------------------------------
function drawReadout(rho_a, rho_g, V_z, F_lift, F_net, z_eq, m_gas, m_payload) {
noStroke(); fill(BG + 6); rect(readoutX, readoutY, readoutW, readoutH, 4);
stroke(...STRUCT, 120); strokeWeight(1); noFill();
rect(readoutX, readoutY, readoutW, readoutH, 4);
noStroke(); fill(FG); textSize(12); textAlign(LEFT, TOP);
let y = readoutY + 12;
const x = readoutX + 12;
const dy = 18;
text('Gas : ' + GASES[gIdx][0], x, y); y += dy;
text('rho_gas : ' + nf(rho_g, 1, 4) + ' kg/m^3', x, y); y += dy;
text('rho_air : ' + nf(rho_a, 1, 4) + ' kg/m^3', x, y); y += dy;
text('V(z) : ' + nf(V_z, 1, 1) + ' m^3', x, y); y += dy;
text('m_gas : ' + nf(m_gas, 1, 2) + ' kg', x, y); y += dy;
text('m_pay : ' + nf(m_payload, 1, 1) + ' kg', x, y); y += dy;
y += 6;
fill(F_lift > 0 ? TRAJ : HOT);
text('F_lift : ' + nf(F_lift, 1, 1) + ' N', x, y); y += dy;
fill(F_net > 0 ? TRAJ : HOT);
text('F_net : ' + nf(F_net, 1, 1) + ' N', x, y); y += dy;
fill(FG);
y += 6;
text('z : ' + nf(z_current / 1000, 1, 2) + ' km', x, y); y += dy;
text('v_z : ' + nf(v_current, 1, 2) + ' m/s', x, y); y += dy;
fill(ACCENT);
text('z_eq : ' + (z_eq < 0 ? 'no liftoff' :
(z_eq >= Z_MAX ? '> 30 km' :
nf(z_eq / 1000, 1, 2) + ' km')), x, y);
}
// ----- slider labels at the bottom ----------------------------------
function drawSliderLabels(V0, m_payload, speedMult) {
noStroke(); fill(...DIM); textSize(11); textAlign(LEFT, BOTTOM);
const ySliderLabel = height - 64;
text('gas: ' + GASES[gIdx][0], 70, ySliderLabel);
text('V_0 = ' + nf(V0, 1, 0) + ' m^3', 220, ySliderLabel);
text('m_payload = ' + nf(m_payload, 1, 0) + ' kg', 370, ySliderLabel);
text('speed x ' + nf(speedMult, 1, 2), 520, ySliderLabel);
}
// ----- HUD: title + wikitube subtitle -------------------------------
function drawHUD() {
noStroke(); fill(FG); textSize(22); textAlign(LEFT, TOP);
text(TITLE, 14, 14);
fill(...DIM); textSize(12);
text('Wikitube microsim . en.wikitube.io/wiki/' + ARTICLE, 14, 40);
// Top-right hint line.
fill(...DIM); textSize(11); textAlign(RIGHT, TOP);
text('play / pause to launch . reset to ground', width - 14, 16);
text('Boyle expansion: V(z) = V_0 * P_0 / P(z)', width - 14, 30);
}
// ----- bottom-right canonical equation ------------------------------
function drawEquation() {
noStroke(); fill(...HOT); textSize(13); textAlign(RIGHT, BOTTOM);
text('F_lift = (rho_air - rho_gas) * V * g', width - 14, height - 88);
}
```
## Links (Wikipedia order)
<!-- injected from _registry/childlinks/Balloon.json (2026-07-30T02:09:12Z) -->
`Aerobot` · `Air_balloon_(disambiguation)` · `Airship` · `Angioplasty` · `Association_of_Science_and_Technology_Centers` · `Atheroma` · `Atmosphere_of_Earth` · `Atmospheric_pressure` · `Balloon_(aeronautics)` · `Balloon_(disambiguation)` · `Balloon_catheter` · `Balloon_drops_at_United_States_presidential_nominating_conventions` · `Balloon_modelling` · `Balloon_popping` · `Balloon_release` · `Balloon_rocket` · `Balloon_tamponade` · `Barrage_balloon` · `Biodegradation` · `Blood_vessel` · `Buoyancy` · `California_Balloon_Law` · `Catheter` · `Convention_(meeting)` · [[Density]] · [[Electric_power_transmission]] · `Finland` · `Flogo` · `Foley_catheter` · `France` · `Gas_balloon` · [[Helium]] · `Helium_atom` · `Helsinki` · `Hevea_brasiliensis` · `High-altitude_balloon` · `Hot_air_balloon` · [[Hydrogen]] · `Italy` · `Jacques_Charles` · `Jewish_Community_Relations_Council` · `Kinetic_energy` · `Latex` · `List_of_balloon_uses` · `List_of_inflatable_manufactured_goods` · `Marine_biology` · `Marine_debris` · `Maryland` · `Michael_Faraday` · `Molecular_diffusion` · `Montgolfier_brothers` · `Mylar_balloon_(geometry)` · `Myocardial_infarction` · `Natural_rubber` · `Nature_reserve` · `Neoprene` · `New_Year's_Eve` · [[Newton's_laws_of_motion]] · `Nitrous_oxide` · `Nylon` · `Observation_balloon` · [[Oxygen]] · `Pig_bladder` · `Pink_Floyd_pigs` · `Plastic` · `Pneumatic_bladder` · `Polymer` · `Potential_energy` · `Practical_joke` · `Pride_parade` · `Proportionality_(mathematics)` · `Pump` · `Radiosonde` · `Rainforest_Alliance` · `Reader's_Digest` · `Recycling` · `Research_balloon` · `Reuse` · `Rockoon` · `Screen_printing` · `Solar_balloon` · `Speech_balloon` · `Sperm_whale` · `Stent` · `Stomach` · `São_Paulo` · `Tethered_balloon` · `Thomas_Hancock_(inventor)` · `Toy_balloon` · `Two-balloon_experiment` · `Uterus` · `Waste_management` · `Water` · `Water_balloon` · `Water_gun` · [[Wayback_Machine]] · `Weather_balloon` · `Wikisource`
## From the vault media library
!Balloon thumb.png
*Balloon — from the vault's own media holdings, placed 2026-07-09. MTN / Wikitube.io original · CC BY-SA 4.0.*
<!-- LOCAL-MEDIA-PASS:END -->
> **Room:** [[Helium]] · **Status:** ✅ shipped
## Overview
A balloon is a flexible bag inflated with a gas — air, hot air, hydrogen, helium, or another lifting medium — whose envelope volume and contained-gas [[Density|density]] together govern its buoyancy. The first crewed flight, by the Montgolfier brothers in November 1783, used a hot-air balloon; ten days later Jacques Charles flew the first hydrogen balloon, establishing the two architectures still in use today. Balloons fall into three broad classes: toy and decorative balloons (latex or foil), aerostatic vehicles (hot-air sport balloons, gas balloons, blimps, and airships), and scientific or military aerostats (weather radiosondes, stratospheric research platforms, tethered surveillance balloons, and high-altitude pseudo-satellites).
The [[Physics|physics]] is governed by Archimedes' principle: net lift equals (ρ_air − ρ_gas) · V · g, so envelope volume and the density contrast with surrounding air determine payload. Helium provides about 93% of hydrogen's lift while being nonflammable, which is why it dominates civil scientific and tethered applications; hot air, with a density contrast set by the ideal-gas law (ρ ∝ 1/T), trades lower lift for cheap, renewable buoyancy. As a balloon ascends, ambient pressure drops, the envelope expands, and either a relief valve vents gas or a superpressure design holds constant volume. Balloons are central to meteorology (~73,000 NWS radiosondes per year), atmospheric [[Science|science]], party and advertising markets, [[Leak|leak]]-testing pressure systems, and emerging stratospheric communications and remote-sensing platforms.
## See also
- Room hub: [[Helium]]
- p5.js Editor conventions: P5 JS EDITOR
- Wiki root: MAIN
---
*Scaffolded by `generative-microsim` from row 127 of the Helium sheet on 2026-05-14T12:25:28Z.*
<!-- LOCAL-MEDIA-PASS:START -->
<!-- CRAFT-LINK:START g12 -->
*Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].*
<!-- CRAFT-LINK:END -->
## Wikipedia : Wikitube
**Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Balloon) : [Wikitube](https://en.wikitube.io/wiki/Balloon)
## Previous hub tags
Tree parents: [[Helium]] · [[Hydrogen]].
Legacy hubs: none.
---
*Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*