{"version":3,"sources":["turf.mjs"],"sourcesContent":["// TURF (world version 9, the owner's spec of Oct 5: \"Turf on Regolith\", confirmed). On living ground the surface is\n// regolith, and turf caps it like a grass block: solid on every top, and a band down each side that borders a top (an\n// eighth of a kube deep until Oct 12; then the owner's wavy hem; since Oct 26 a straight one, HEM_DEPTH below). It comes in all 32 palette colours, by star and by life, spreads about a kube every five minutes,\n// and keeps growing while nobody is there: everything below is a pure function of the world's seed, its edits and the\n// minute those edits were made, so the page and both servers work out the same turf whenever they are asked.\n//\n// THREE BYTE-IDENTICAL COPIES: public/, functions/lib/ and zone-server/lib/, checked by generate-version-hash.js. No\n// imports, so the same bytes resolve in all three, and transient-shape.js and genDensity.mjs can read it.\n//\n// What lives here:\n//   * the palette and where each colour grows (leaf turf by star class; flower, glow, fungal, tholin, silicate turf),\n//     and the one colour a world shows for each life type on it (turfColourOf);\n//   * which regolith lies under the turf (soilNamesOf: the crust's same-colour twin);\n//   * THE TOP RULE (topMask) the renderer draws by;\n//   * THE CLOCK: the wait a bare kube has before turf takes it (turfWait), and evaluateTurf, which works out the turf of\n//     every kube the edits have touched at any minute, and which records a server should settle when it writes.\n\nexport const TURF_SINCE = 9;            // the world version turf ships in (transient-shape.js ROCKY_GENERATORS[9])\n// THE TURF SEAT: a cell's turf, when it differs from what the seed grew, is written at a fifth part of its local key,\n// past the 27 bit seats (bit-slot.js) and FLORA_VOID's 27: 'lx_ly_lz_28'. Its value is the colour's Turf Bit (turf, or a\n// planted bit), or null (stripped or dead); the chunk doc's `t` map holds the minute at the same key.\nexport const TURF_SEAT = 28;\nexport const COVER_DEATH = 1;           // minutes a covered turf lives: a kube, slab or liquid on its top\nexport const SKY_DEATH = 60;            // minutes a turf lives without sky (a roof, an overhang)\nexport const ROOT_DELAY = 1;            // minutes a planted bit takes to root\nexport const WAIT_MEAN = 5, WAIT_MIN = 1, WAIT_MAX = 20;   // d(c) = clamp(−5 · ln u, 1, 20) minutes\n\n// THE PALETTE, in kubes.json order: a colour's number (1–32) is its place here, and must never change.\nexport const TURF_COLOURS = Object.freeze(['Lumina', 'Gleam', 'Drift', 'Lull', 'Veil', 'Haze', 'Void', 'Ignition', 'Cinder', 'Arid',\n  'Scorched', 'Radiance', 'Nova', 'Solis', 'Corona', 'Farout', 'Starlight', 'Flash', 'Wisp', 'Spirit', 'Fathom', 'Gloam', 'Halo',\n  'Bloom', 'Verge', 'Tide', 'Aura', 'Ether', 'Surge', 'Reach', 'Glint', 'Echo']);\nconst HEX = { Lumina: '#FFFFFF', Gleam: '#E5E5E5', Drift: '#B0C4DE', Lull: '#808080', Veil: '#666666', Haze: '#4B4B4B', Void: '#1A1A1A',\n  Ignition: '#FF0000', Cinder: '#FF4500', Arid: '#D2B48C', Scorched: '#A0522D', Radiance: '#FFD700', Nova: '#FFFF00', Solis: '#CD853F',\n  Corona: '#FFDEAD', Farout: '#FF69B4', Starlight: '#FFB6C1', Flash: '#FF00FF', Wisp: '#EE82EE', Spirit: '#9370DB', Fathom: '#800080',\n  Gloam: '#4B3621', Halo: '#E6E6FA', Bloom: '#32CD32', Verge: '#228B22', Tide: '#008080', Aura: '#00FFFF', Ether: '#1E90FF',\n  Surge: '#4169E1', Reach: '#00008B', Glint: '#AFEEEE', Echo: '#708090' };\n// A turf's colour on screen: the palette's, Void's near-black included (the violet Umbra sheen was dropped Oct 7, as for\n// Void leaves in biomes.mjs leafHex).\nexport const turfHex = (c) => HEX[c] || '#228B22';\nexport const turfColourNumber = (c) => TURF_COLOURS.indexOf(c) + 1;\nexport const turfBitName = (c) => c + ' Turf Bit';\n// WHAT MINING A TURFED KUBE GIVES, as the crosshair's pill names it (the owner, Oct 8: \"x Regolith + x Turf\"): the kube\n// and its turf, \"Veil Regolith + Aura Turf\"; the turf comes as an \"Aura Turf Bit\" (turfBitName).\nexport const turfedKubeName = (kube, c) => kube + ' + ' + c + ' Turf';\nexport function colourOfTurfBit(name) {\n    const m = /^([A-Z][a-z]+) Turf Bit$/.exec(String(name || ''));\n    return m && TURF_COLOURS.indexOf(m[1]) >= 0 ? m[1] : null;\n}\nexport const isTurfBitName = (n) => colourOfTurfBit(n) != null;\n\n// WHERE EACH COLOUR GROWS. Leaf turf (carbon and water life) takes its star's light, the owner's physics rule: each class\n// draws from today's LEAF_BY_CLASS (biomes.mjs) and the flower, glow, fungal, tholin and silicate turf from today's\n// organics.mjs FAMILIES, with seven new homes so that every one of the 32 grows somewhere: Drift (O, B: their pale colour\n// until Oct 1), Surge (F: deeper than Ether's blue), Ignition (K: the chart's pure red), Reach (M and rogue: the near-black\n// blue the M chart had no colour for), Lull, Veil and Haze (fungal: fungi need no starlight; Veil and Haze also rogue).\nexport const TURF_FAMILIES = Object.freeze(['leaf', 'petal', 'glow', 'fungal', 'tholin', 'silicate']);\nexport const LEAF_POOLS = Object.freeze({\n    O: ['Lumina', 'Gleam', 'Halo', 'Drift'], B: ['Halo', 'Starlight', 'Glint', 'Gleam', 'Drift'], A: ['Starlight', 'Glint', 'Farout', 'Halo'],\n    F: ['Ether', 'Wisp', 'Flash', 'Spirit', 'Bloom', 'Nova', 'Surge'], G: ['Verge', 'Bloom', 'Aura', 'Tide', 'Cinder', 'Fathom'],\n    K: ['Solis', 'Nova', 'Cinder', 'Scorched', 'Spirit', 'Ether', 'Tide', 'Ignition'], M: ['Void', 'Gloam', 'Fathom', 'Reach'],\n    R: ['Void', 'Gloam', 'Fathom', 'Reach', 'Veil', 'Haze'] });\nexport const FAMILY_POOLS = Object.freeze({\n    petal: ['Farout', 'Starlight', 'Wisp', 'Radiance', 'Nova'],\n    glow: ['Aura', 'Ether', 'Spirit', 'Flash', 'Radiance', 'Bloom'],\n    fungal: ['Gleam', 'Halo', 'Tide', 'Gloam', 'Echo', 'Solis', 'Scorched', 'Spirit', 'Lull', 'Veil', 'Haze'],\n    tholin: ['Solis', 'Scorched', 'Arid', 'Gloam', 'Corona', 'Cinder'],\n    silicate: ['Lumina', 'Glint', 'Spirit', 'Fathom', 'Radiance', 'Void', 'Cinder', 'Scorched', 'Nova', 'Echo'] });\nexport const turfPool = (family, cls) => (family === 'leaf' ? (LEAF_POOLS[cls] || LEAF_POOLS.R) : (FAMILY_POOLS[family] || []));\n// Which life type each living biome's ground grows (biomes.mjs ids). The ground under a sea is not a top open to the sky,\n// so tidal gardens carry none whatever they are made of.\nexport const BIOME_TURF = Object.freeze({\n    woods: 'leaf', rimeWoods: 'leaf', aridParkland: 'leaf', hothouseCanopy: 'leaf', reedspireStands: 'leaf', stiltrootFens: 'leaf',\n    lichenSteppe: 'leaf', matCrags: 'leaf', resinLattices: 'leaf', siphonTubes: 'leaf', landKelp: 'leaf', boneArches: 'leaf',\n    fleshPods: 'leaf', prismCoral: 'leaf', veinCoral: 'leaf', vaultedReefs: 'leaf',\n    hanging: 'leaf',   // version 12's hanging gardens (thorn scrub keeps its bare red earth; stromatolites live under the sea)\n    bloomCarpets: 'petal',\n    nightsideGlow: 'glow', glowcapStands: 'glow', glowmossPillars: 'glow', glowMosaic: 'glow', glowSlime: 'glow',\n    gillTowers: 'fungal', puffballDomes: 'fungal', shelfTerraces: 'fungal',\n    tholinThickets: 'tholin', methaneMats: 'tholin', bubbleFens: 'tholin', cryoFerns: 'tholin', rimeFringe: 'tholin', tholinReefs: 'tholin', methaneOasis: 'tholin',\n    spiritGardens: 'silicate', quartzDendrites: 'silicate', silicateShells: 'silicate', latticeColonies: 'silicate', sulfurBlooms: 'silicate',\n    rustSpires: 'silicate', glassVeinwood: 'silicate', crystalWarrens: 'silicate' });\n// The chemistry each life type is (biomes.mjs lifeChemistryOf names), and the temperatures each chemistry lives at,\n// the outer bounds of its biomes' own ranges.\nexport const FAMILY_CHEM = Object.freeze({ leaf: 'carbon', petal: 'carbon', glow: 'carbon', fungal: 'carbon', tholin: 'methane', silicate: 'silicon' });\nexport const CHEM_RANGE_C = Object.freeze({ carbon: [-40, 50], methane: [-200, -150], silicon: [150, 900] });\nconst CHEMS_OF = (() => {\n    const out = {};\n    for (const c of TURF_COLOURS) out[c] = [];\n    const add = (c, chem) => { if (out[c].indexOf(chem) < 0) out[c].push(chem); };\n    for (const cls in LEAF_POOLS) for (const c of LEAF_POOLS[cls]) add(c, 'carbon');\n    for (const f in FAMILY_POOLS) for (const c of FAMILY_POOLS[f]) add(c, FAMILY_CHEM[f]);\n    return out;\n})();\n// The chemistries a colour of turf can live in: a turf bit takes root where the world's life is one of them.\nexport const chemsOfColour = (c) => CHEMS_OF[c] || [];\nexport function climateSuits(colour, chem, tempC) {\n    if (!chem || chemsOfColour(colour).indexOf(chem) < 0) return false;\n    const r = CHEM_RANGE_C[chem];\n    return !!r && tempC >= r[0] && tempC <= r[1];\n}\n\n// FNV-1a over a string to [0, 1), as biomes.mjs hash01 is.\nfunction hash01(s) {\n    let h = 2166136261;\n    for (let i = 0; i < s.length; i++) h = Math.imul(h ^ s.charCodeAt(i), 16777619);\n    h ^= h >>> 15; h = Math.imul(h, 0x2c1b3c6d); h ^= h >>> 12;\n    return (h >>> 0) / 4294967296;\n}\nexport const turfSeedOf = (addr) => Math.floor(hash01(String(addr || '') + '#turfwait') * 4294967296) | 0;\n// ONE COLOUR PER LIFE TYPE PER WORLD, drawn from its pool by the world's address. `cls` is the star's class letter, or\n// null for a rogue world.\nexport function turfColourOf(addr, cls, family) {\n    const pool = turfPool(family, cls || 'R');\n    return pool.length ? pool[Math.floor(hash01(String(addr || '') + '#turf:' + family) * pool.length)] : null;\n}\n\n// WHICH REGOLITH LIES UNDER THE TURF: the same-colour twin of the crust that would have been there (every Mineral has\n// one: Cinder Mineral → Cinder Regolith). A crust with no twin (Silicon, Sulfur, Carbon, Phosphorus, Halite) takes the\n// world's other crust's twin, or Gloam Regolith if that has none either.\nconst twinOf = (n) => { const m = /^(.+) (Mineral|Regolith)$/.exec(String(n || '')); return m ? m[1] + ' Regolith' : null; };\nexport function soilNamesOf(crust0, crust1) {\n    const a = twinOf(crust0), b = twinOf(crust1);\n    return [a || b || 'Gloam Regolith', b || a || 'Gloam Regolith'];\n}\n// A PIGMENT'S REGOLITH (\"Gloam Regolith\": one word and Regolith), never a building kube made of one (\"Gloam Rammed Regolith\",\n// \"Gloam Sintered Regolith\", building-kubes.mjs, Oct 13): turf takes root on ground, not on masonry.\nexport const isRegolithName = (n) => /^\\S+ Regolith$/.test(String(n || ''));\n\n// THE WAIT: how long a bare, eligible kube waits, once a neighbour carries turf, before turf takes it. A clamped\n// exponential with a mean of 5.0 minutes (18% wait the floor, 1.8% the cap), from the cell's own hash, so the same\n// kube always waits the same time and an edge comes out ragged.\nexport function turfWait(x, y, z, seed) {\n    let h = Math.imul(x, 0x27d4eb2d) ^ Math.imul(y, 0x165667b1) ^ Math.imul(z, 0x3c6ef372) ^ seed;\n    h = Math.imul(h ^ (h >>> 15), 0x85ebca6b); h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35); h ^= h >>> 16;\n    const u = ((h >>> 0) + 0.5) / 4294967296;\n    const d = -WAIT_MEAN * Math.log(u);\n    return d < WAIT_MIN ? WAIT_MIN : d > WAIT_MAX ? WAIT_MAX : d;\n}\n\n// A CELL'S UP: the largest axis of its centre and its sign (bit-slot.js cellUpFace, the walker's gravity).\nexport function upOf(x, y, z) {\n    const cx = x + 0.5, cy = y + 0.5, cz = z + 0.5, ax = cx < 0 ? -cx : cx, ay = cy < 0 ? -cy : cy, az = cz < 0 ? -cz : cz;\n    const a = (ax >= ay && ax >= az) ? 0 : (ay >= az ? 1 : 2);\n    return { a, s: (a === 0 ? cx : a === 1 ? cy : cz) >= 0 ? 1 : -1 };\n}\nconst AXIS = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];\n// THE TOP RULE. An exposed face is a top when the air cell beyond it belongs to the world face its normal points to:\n// that air cell's largest axis is the normal's axis, with the same sign. On flat ground that is the up face alone; along\n// a world's edge two; on a corner kube three. A hillside looks into its own face's air, so it is a side. Returns the six\n// bits (0 +x, 1 −x, 2 +y, 3 −y, 4 +z, 5 −z, BoxGeometry's order) of the cell's tops; `open(x, y, z)` says whether a\n// neighbouring cell lets the face show (air, or anything less than a whole kube).\nexport function topMask(open, x, y, z) {\n    let m = 0;\n    for (let n = 0; n < 6; n++) {\n        const a = n >> 1, sg = (n & 1) ? -1 : 1;\n        const nx = x + (a === 0 ? sg : 0), ny = y + (a === 1 ? sg : 0), nz = z + (a === 2 ? sg : 0);\n        if (!open(nx, ny, nz)) continue;\n        const c = [nx + 0.5, ny + 0.5, nz + 0.5], ca = c[a] < 0 ? -c[a] : c[a];\n        const o1 = c[(a + 1) % 3] < 0 ? -c[(a + 1) % 3] : c[(a + 1) % 3], o2 = c[(a + 2) % 3] < 0 ? -c[(a + 2) % 3] : c[(a + 2) % 3];\n        if (sg * c[a] > 0 && ca >= o1 && ca >= o2) m |= 1 << n;\n    }\n    return m;\n}\n// THE HEM (the owner, Oct 26: \"right now turf has a wavy texture on regoliths' sides. Let's just make it a straight line\n// where the current bottom of those waves [are] instead\"). Down each side that borders a top, turf reaches HEM_DEPTH of a\n// kube, a straight line: 1/7 + 1/24, the deepest the Oct 12 'waves' hem reached (1/7 + sin(u · 6π) / 24, at its crests).\n// One depth everywhere, so it runs on along a row of kubes and turns at the same depth round every edge and corner.\n// Stated without a face: the band of a top on axis a is the depth from that top against HEM_DEPTH, so the test needs no\n// normal (this function, the shader and the icon all make it from a point alone).\nexport const HEM_DEPTH = 1 / 7 + 1 / 24;\n// Is a point at cell-local position (lx, ly, lz) in 0..1 on turf, for a cell whose tops are `mask`? On a top itself, and\n// within the hem of every edge a side shares with a top. The shader's own test (system-view.js TURF_GLSL) and the icon's\n// (app.js turfIconPaint), stated here so a test can hold the three to each other.\nexport function turfAtLocal(mask, lx, ly, lz) {\n    const l = [lx, ly, lz];\n    for (let n = 0; n < 6; n++) {\n        if (!((mask >> n) & 1)) continue;\n        const a = n >> 1, d = (n & 1) ? l[a] : 1 - l[a];\n        if (d <= HEM_DEPTH) return true;\n    }\n    return false;\n}\n\n// ─────────────────────────────── THE CLOCK ───────────────────────────────\n// evaluateTurf(view, T) works out, at minute T, the turf of every kube the world's edits have touched, from:\n//   view.seeds()              the cells any edit names: a placed or mined kube, a turf seat\n//   view.inside(x, y, z)      inside the world's grid\n//   view.full(x, y, z)        a whole kube fills the cell (ground the seed made and nobody mined, a kube placed, sea ice)\n//   view.liquid(x, y, z)      a liquid stands there (a sea, a lake, a pool a player poured: deep enough to cover)\n//   view.wetSince(x, y, z)    (optional) the minute that liquid has stood there since: a cover's start, as a kube's stamp\n//   view.placed(x, y, z)      a player placed what stands in the cell\n//   view.kubeAt(x, y, z)      the kube in the cell, by name, or null\n//   view.natural(x, y, z)     the colour the seed grew there, or null\n//   view.record(x, y, z)      the turf seat: { v: colour | null, t } or null\n//   view.stamp(x, y, z)       the minute the cell's kube last changed, or null\n//   view.spreadGround(x,y,z)  turf may spread here: ground of a living biome, or regolith a player placed\n//   view.climate(x, y, z)     { chem, tempC } where the cell stands\n//   view.seed                 turfSeedOf(addr)\n// A bare kube is eligible when it is regolith on spread ground, its top neither covered nor roofed. It is exposed at t0,\n// the first minute one of its 8 neighbouring columns (within a step up or down) carries live turf, but never before it\n// became bare; it turfs at t0 + turfWait, in the colour of the neighbour that turfed first (an exact tie: the lower\n// colour number), if its climate suits that colour. Turf dies COVER_DEATH after something covers it and SKY_DEATH after\n// it loses the sky. A planted bit roots at its record's minute (ROOT_DELAY after it was placed), if the climate suits.\n// Returns { turf: Map key → { c, t }, bare: Set key, lying: Map key → colour, settle: [{ x, y, z, v, t }], next } for\n// the touched kubes (a key is turfCellKey); every other kube shows what the seed grew there.\nexport const turfCellKey = (x, y, z) => ((x + 256) * 512 + (y + 256)) * 512 + (z + 256);\nexport const turfCellXYZ = (k) => [Math.floor(k / 262144) - 256, Math.floor(k / 512) % 512 - 256, k % 512 - 256];\nconst NEG = -Infinity;\n// A minute fit to store: \"long ago\" is minute 0, the epoch.\nconst minuteOf = (t) => (Number.isFinite(t) ? t : 0);\nfunction stepCell(x, y, z, a, k) { return a === 0 ? [x + k, y, z] : a === 1 ? [x, y + k, z] : [x, y, z + k]; }\n// The 8 surrounding columns of a cell, each up a step, level or down a step, along its own up.\nfunction neighbours(x, y, z) {\n    const u = upOf(x, y, z), A = AXIS[u.a], U = AXIS[(u.a + 1) % 3], V = AXIS[(u.a + 2) % 3], out = [];\n    for (let du = -1; du <= 1; du++) for (let dv = -1; dv <= 1; dv++) {\n        if (!du && !dv) continue;\n        for (let dh = -1; dh <= 1; dh++) {\n            const h = dh * u.s;\n            out.push([x + du * U[0] + dv * V[0] + h * A[0], y + du * U[1] + dv * V[1] + h * A[1], z + du * U[2] + dv * V[2] + h * A[2]]);\n        }\n    }\n    return out;\n}\n// A small binary heap of [time, colour number, key].\nfunction heapPush(h, e) { h.push(e); let i = h.length - 1; while (i > 0) { const p = (i - 1) >> 1; if (less(h[p], h[i])) break; [h[p], h[i]] = [h[i], h[p]]; i = p; } }\nfunction heapPop(h) { const top = h[0], last = h.pop(); if (h.length) { h[0] = last; let i = 0; for (;;) { const l = 2 * i + 1, r = l + 1; let m = i;\n    if (l < h.length && less(h[l], h[m])) m = l; if (r < h.length && less(h[r], h[m])) m = r; if (m === i) break; [h[m], h[i]] = [h[i], h[m]]; i = m; } } return top; }\nconst less = (a, b) => a[0] < b[0] || (a[0] === b[0] && (a[1] < b[1] || (a[1] === b[1] && a[2] < b[2])));\nexport function evaluateTurf(view, T) {\n    // THE KUBES IN PLAY: every cell an edit names, the one under it (mining a kube bares the regolith below), and the\n    // ground under every placed kube (it is roofed, or covered).\n    const D = new Map();                                           // key → [x, y, z]\n    const add = (x, y, z) => { if (view.inside(x, y, z)) D.set(turfCellKey(x, y, z), [x, y, z]); };\n    for (const [x, y, z] of view.seeds()) {\n        add(x, y, z);\n        const u = upOf(x, y, z), b = stepCell(x, y, z, u.a, -u.s); add(b[0], b[1], b[2]);\n        if (view.placed(x, y, z) && view.full(x, y, z)) {\n            for (let k = 1; k < 512; k++) { const c = stepCell(x, y, z, u.a, -u.s * k); if (!view.inside(c[0], c[1], c[2])) break;\n                if (view.full(c[0], c[1], c[2])) { add(c[0], c[1], c[2]); break; } }\n        }\n    }\n    // EACH ONE'S STATE, before any spreading.\n    const S = new Map();\n    for (const [k, [x, y, z]] of D) {\n        if (!view.full(x, y, z) || !/^\\S+ Regolith$/.test(String(view.kubeAt(x, y, z) || ''))) continue;\n        const u = upOf(x, y, z), a = stepCell(x, y, z, u.a, u.s);\n        if (view.full(a[0], a[1], a[2]) && !view.placed(a[0], a[1], a[2])) continue;   // buried under ground the seed made: no top\n        const solidOver = view.full(a[0], a[1], a[2]), covered = solidOver || view.liquid(a[0], a[1], a[2]);\n        const coverSince = !covered ? null : (!solidOver && view.wetSince) ? (view.wetSince(a[0], a[1], a[2]) ?? NEG) : (view.stamp(a[0], a[1], a[2]) ?? NEG);\n        // THE SKY: nothing whole above along its up, to the grid's edge. A roof a player placed closes it from the earliest\n        // minute among the roofs standing; ground the seed made, for ever.\n        let sky = true, skySince = null;\n        for (let j = 1; j < 512; j++) { const c = stepCell(x, y, z, u.a, u.s * j); if (!view.inside(c[0], c[1], c[2])) break;\n            if (!view.full(c[0], c[1], c[2])) continue;\n            sky = false; const st = view.placed(c[0], c[1], c[2]) ? (view.stamp(c[0], c[1], c[2]) ?? NEG) : NEG;\n            if (skySince == null || st < skySince) skySince = st; }\n        const rec = view.record(x, y, z), st = view.stamp(x, y, z), sa = view.stamp(a[0], a[1], a[2]);\n        let colour = null, since = NEG, lying = false, bareSince = NEG, recorded = false;\n        if (rec && rec.t >= (st ?? NEG)) {\n            recorded = true;\n            // A planted bit lies on its kube until the minute it roots, and for good where the climate does not suit it.\n            if (rec.v) { const cl = view.climate(x, y, z);\n                if (rec.t > T || !climateSuits(rec.v, cl.chem, cl.tempC)) lying = true; else { colour = rec.v; since = rec.t; } }\n            else bareSince = rec.t;\n        } else if (st != null) bareSince = st;\n        else { const n = view.natural(x, y, z); if (n) colour = n; }\n        if (!colour && sa != null && sa > bareSince) bareSince = sa;\n        S.set(k, { x, y, z, covered, coverSince, sky, skySince, colour, since, lying, lyingColour: lying ? rec.v : null, bareSince, recorded, rec });\n    }\n    // DEATHS: covered, or without sky. Turf that will die does not spread meanwhile; live turf does.\n    const turf = new Map(), bare = new Set(), lyingOut = new Map(), settle = [];\n    let next = Infinity;\n    const live = new Map();                                        // key → { t, n (colour number), c }\n    for (const [k, s] of S) {\n        if (s.lying) { lyingOut.set(k, s.lyingColour); if (s.rec.t > T && s.rec.t < next) next = s.rec.t; bare.add(k); continue; }\n        if (!s.colour) continue;\n        let death = Infinity;\n        if (s.covered) death = Math.max(s.since, s.coverSince) + COVER_DEATH;\n        if (!s.sky) death = Math.min(death, Math.max(s.since, s.skySince) + SKY_DEATH);\n        if (death <= T) { bare.add(k); s.colour = null; s.bareSince = death;\n            if (!(s.recorded && s.rec.v == null)) settle.push({ x: s.x, y: s.y, z: s.z, v: null, t: minuteOf(death) }); continue; }\n        if (death < next) next = death;\n        turf.set(k, { c: s.colour, t: s.since });\n        if (!s.covered && s.sky) live.set(k, { t: s.since, n: turfColourNumber(s.colour), c: s.colour });\n    }\n    // THE SPREAD, as a shortest path over the waits: a bare kube's arrival is the earliest minute a live neighbour gives it\n    // (never before it became bare) plus its own wait.\n    const eligible = (s) => s && !s.colour && !s.lying && !s.covered && s.sky && view.spreadGround(s.x, s.y, s.z);\n    const heap = [], best = new Map(), done = new Set();\n    const offer = (k, s, t0, src) => {\n        const cl = view.climate(s.x, s.y, s.z);\n        if (!climateSuits(src.c, cl.chem, cl.tempC)) return;\n        const t = Math.max(t0, s.bareSince) + turfWait(s.x, s.y, s.z, view.seed), b = best.get(k);\n        if (b && (b.t < t || (b.t === t && b.n <= src.n))) return;\n        best.set(k, { t, n: src.n, c: src.c }); heapPush(heap, [t, src.n, k]);\n    };\n    // Seed the heap from every live neighbour, touched or not (what the seed grew, outside the touched kubes, is live).\n    for (const [k, s] of S) {\n        if (!eligible(s)) continue;\n        for (const [nx, ny, nz] of neighbours(s.x, s.y, s.z)) {\n            const nk = turfCellKey(nx, ny, nz);\n            let src = live.get(nk);\n            if (!src && !D.has(nk) && view.inside(nx, ny, nz) && view.full(nx, ny, nz)) { const c = view.natural(nx, ny, nz); if (c) src = { t: NEG, n: turfColourNumber(c), c }; }\n            if (src) offer(k, s, src.t, src);\n        }\n    }\n    while (heap.length) {\n        const [t, n, k] = heapPop(heap);\n        if (done.has(k)) continue;\n        const b = best.get(k); if (!b || b.t !== t || b.n !== n) continue;\n        done.add(k);\n        if (t > T) { if (t < next) next = t; continue; }          // arrives later: bare for now, and it seeds nothing yet\n        const s = S.get(k);\n        turf.set(k, { c: b.c, t }); settle.push({ x: s.x, y: s.y, z: s.z, v: b.c, t: minuteOf(t) });\n        for (const [nx, ny, nz] of neighbours(s.x, s.y, s.z)) { const nk = turfCellKey(nx, ny, nz), ns = S.get(nk); if (!done.has(nk) && eligible(ns)) offer(nk, ns, t, b); }\n    }\n    for (const [k, s] of S) if (!turf.has(k) && !lyingOut.has(k)) bare.add(k);\n    return { turf, bare, lying: lyingOut, settle, next };\n}\n\n// ─────────────────────────────── THE SERVERS' VIEW ───────────────────────────────\n// evaluateTurf over what a server holds: the world's fields (transient-shape rockyFields, version 9: `turf`), its\n// generator (genDensity worldGen, for what a kube is), its sea, and EVERY chunk of its edits, { id: { blocks, t } } with\n// the blocks already decoded to names. functions/index.js submitEdits and zone-server/lib/edits.js both call this, so\n// the two validators cannot weigh turf differently. `nameAt(x, y, z)` is genDensity kubeNameAt over the generator.\n// `water` (optional, the reservoirs plan of Oct 6): { coverAt(x, y, z) → the minute liquid deep enough to cover has stood\n// in the cell since, or null; cells() → every cell wet other than as generated }. Without it only the generated sea\n// covers, as before; with it a poured or adopted pool covers what is under it, and a drained bed stops covering.\nexport function serverTurfView({ fields, nameAt, sea, chunks, HALF, VOX_CHUNK, addr, isBit, SEA_CELL, water = null }) {\n    const tf = fields.turf || null;\n    const loc = (x, y, z) => {\n        const ax = x + HALF, ay = y + HALF, az = z + HALF;\n        const cx = Math.floor(ax / VOX_CHUNK), cy = Math.floor(ay / VOX_CHUNK), cz = Math.floor(az / VOX_CHUNK);\n        return { id: cx + '_' + cy + '_' + cz, lk: (ax - cx * VOX_CHUNK) + '_' + (ay - cy * VOX_CHUNK) + '_' + (az - cz * VOX_CHUNK) };\n    };\n    const cell = (x, y, z) => { const p = loc(x, y, z), c = chunks[p.id]; return c ? c.blocks[p.lk] : undefined; };\n    const inside = (x, y, z) => x >= -HALF && x < HALF && y >= -HALF && y < HALF && z >= -HALF && z < HALF;\n    const seaAt = (x, y, z) => (sea ? sea.at(x, y, z) : SEA_CELL.DRY);\n    const full = (x, y, z) => { if (!inside(x, y, z)) return false; const w = cell(x, y, z);\n        if (typeof w === 'string') return !isBit(w); if (w === null) return false;\n        return fields.isSolid(x, y, z) || seaAt(x, y, z) >= SEA_CELL.ICE; };\n    const view = {\n        seed: turfSeedOf(addr), inside, full,\n        seeds() { const out = [];\n            for (const id in chunks) { const p = id.split('_').map(Number), c = chunks[id];\n                for (const lk in c.blocks) { const q = lk.split('_').map(Number);\n                    if (q.length === 4 && q[3] !== TURF_SEAT) continue;   // a bit's seat changes no ground\n                    out.push([p[0] * VOX_CHUNK + q[0] - HALF, p[1] * VOX_CHUNK + q[1] - HALF, p[2] * VOX_CHUNK + q[2] - HALF]); } }\n            if (water) for (const c of water.cells()) out.push(c);\n            return out; },\n        liquid: water ? (x, y, z) => inside(x, y, z) && !full(x, y, z) && water.coverAt(x, y, z) != null\n                      : (x, y, z) => cell(x, y, z) === undefined && !fields.isSolid(x, y, z) && seaAt(x, y, z) === SEA_CELL.LIQUID,\n        wetSince: water ? (x, y, z) => water.coverAt(x, y, z) : null,\n        placed: (x, y, z) => typeof cell(x, y, z) === 'string',\n        kubeAt: (x, y, z) => { const w = cell(x, y, z); if (typeof w === 'string') return w; if (w === null) return null; return fields.isSolid(x, y, z) ? nameAt(x, y, z) : null; },\n        natural: (x, y, z) => { if (!tf || cell(x, y, z) !== undefined) return null; const c = tf.at(x, y, z); if (!c) return null;\n            const u = upOf(x, y, z), a = stepCell(x, y, z, u.a, u.s);\n            if (seaAt(a[0], a[1], a[2]) !== SEA_CELL.DRY || fields.isSolid(a[0], a[1], a[2])) return null;\n            return c; },\n        record: (x, y, z) => { const p = loc(x, y, z), c = chunks[p.id]; if (!c) return null; const k = p.lk + '_' + TURF_SEAT;\n            if (!(k in c.blocks)) return null; const v = c.blocks[k];\n            return { v: v === null ? null : colourOfTurfBit(v), t: Number.isFinite(c.t && c.t[k]) ? c.t[k] : NEG }; },\n        stamp: (x, y, z) => { const p = loc(x, y, z), c = chunks[p.id]; if (!c || !c.t || !(p.lk in c.blocks)) return null;\n            return Number.isFinite(c.t[p.lk]) ? c.t[p.lk] : NEG; },\n        spreadGround: (x, y, z) => { const w = cell(x, y, z); if (typeof w === 'string') return /^\\S+ Regolith$/.test(w);\n            return w === undefined && !!tf && tf.soil(x, y, z); },\n        climate: (x, y, z) => (tf ? { chem: tf.chem, tempC: tf.tempAt(x, y, z) } : { chem: null, tempC: 0 }),\n    };\n    return { view, loc };\n}\n// THE TURF OF ONE KUBE at minute T, over a view: { colour } when it carries turf, { lying } when a planted bit lies on\n// it, or null. (evaluateTurf answers for the touched kubes; any other kube shows what the seed grew there.)\nexport function turfOfCell(view, res, x, y, z) {\n    const k = turfCellKey(x, y, z);\n    if (res.turf.has(k)) return { colour: res.turf.get(k).c };\n    if (res.lying.has(k)) return { lying: res.lying.get(k) };\n    if (res.bare.has(k)) return null;\n    if (!view.full(x, y, z)) return null;\n    const c = view.natural(x, y, z);\n    return c ? { colour: c } : null;\n}\n"],"mappings":"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","names":["st"],"file":"turf.mjs"}