// PROCITY Lane C — bible.js [v7.0-beta wave 1, R32 — THE GUIDE + THE GEM (charter system #3)] // The in-game price guide: thriftgod's BIBLE concept as a VALUE BAND per item. The band is the // 90s guide book, not an oracle — it names a range ("guide $25–59"), never a verdict. A **gem** // is an item ASKING under its band's low edge; spotting one is the player's skill, so nothing in // any UI ever says "gem". // // THE DERIVATION RULING (R32): band NUMBERS mirror Lane E's pipeline thresholds // (pipeline/build_stock_pack.py price_band(): record 8/25/60 · book 5/15/40 · toy 6/20/50 — // duplicated verbatim in godverse_stock.py, validated by validate_pack.py). We derive ranges in // JS from the band LABEL the packs already carry instead of re-baking band data into atlases — // so charter risk #3 (a re-emitted pack orphaning owned skus) never opens. If E's thresholds // move, this table moves with them in the same commit (the two files name each other). // // THE STRUCTURAL CONSEQUENCE (why the no-pump law survives the beta, LANE_C_PUB §9.1): // real/mint pack items derive `price_band` FROM `price`, so real asking always sits INSIDE its // band ⇒ bandLow ≤ asking ⇒ sellOffer(bandLow) ≤ bandLow − 1 < asking: every real round trip // stays strictly negative with the basis swapped. Only PARODY stock (proceduralSleeves) rolls a // seeded under-band gem — and per-day scarcity (the save's `pulls`) makes each gem profit ONCE. // Growth is bounded by finds, not arbitrage loops — charter law #2, made structural. // // Zero DOM, zero draws, zero fetch, zero storage: a pure table + pure functions. ?classic=1 / // ?dig=0 never import a caller, and importing this module alone has no effect at all. // kind → band → [low, high]; `high: null` = open-ended (the card renders "$60+"). // Lows/highs are E's threshold edges: a band [t0, t1) renders as $t0–(t1−1). export const BANDS = { record: { bargain: [2, 7], standard: [8, 24], collector: [25, 59], grail: [60, null] }, book: { bargain: [1, 4], standard: [5, 14], collector: [15, 39], grail: [40, null] }, toy: { bargain: [2, 5], standard: [6, 19], collector: [20, 49], grail: [50, null] }, }; export const BAND_ORDER = ['bargain', 'standard', 'collector', 'grail']; // bandRange('record','collector') → [25, 59] | null on unknown kind/band (fail-closed: no range, // no guide line, no basis swap — never an invented number). export function bandRange(kind, band) { const k = BANDS[kind]; const r = k && k[String(band || '').toLowerCase()]; return r ? [r[0], r[1]] : null; } // The guide line for a card stamp — "guide $25–59" / "guide $60+" / '' when unknowable. export function guideText(kind, band) { const r = bandRange(kind, band); if (!r) return ''; return r[1] == null ? `guide $${r[0]}+` : `guide $${r[0]}–${r[1]}`; } // The sell basis for a collection entry (LANE_C_PUB §9.1, the pre-ratified beta swap): bandLow // when the entry carries a band the BIBLE knows, else the alpha basis (pricePaid) — so every // alpha-era find (no band field) sells exactly as it did before this round. The sellOffer() // CLAMP SHAPE is sell.js's and survives untouched; this function only chooses the number fed in. export function sellBasis(entry) { if (entry && entry.band) { const r = bandRange(entry.type, entry.band); if (r) return r[0]; } return entry ? (entry.pricePaid != null ? entry.pricePaid : entry.price) : 0; }