lib.rs

7.5 kB · rust · 187 lines

1#![doc = include_str!("../README.md")]2#![deny(missing_docs)]34use mrlyrs::core::colors::{Color, Theme, DARK, LIGHT};5use mrlyrs::math::bang::Code;6use mrlyrs::Error;7use std::cell::Cell;8use wasm_bindgen::prelude::*;910/// The Apollonian gasket: a packing grown from its root quadruple in exact integers, the Ford circles it rests on the line, and the Farey stack they shadow.11pub mod apollonian;12/// The elementary automata: their rows stepped, their space-time diagrams and the card of one rule.13pub mod automata;14/// The universes: codes, symmetries, counts, closed-form fills and names.15pub mod bang;16/// The blends: registry sequences drawn as terms, ratios, differences and the recurrence they satisfy, and the term operations that mix two of them.17pub mod blend;18/// The slice carry automaton: its digit polynomial, its even block, its ladder, its sign law and its spectral ratio.19pub mod carry;20/// The census: which integers the whole registry writes inside a pinned window, how often, and which rows write one.21pub mod census;22/// The Chladni stills: soups stepped on big design masks by FFT convolution, the kernel drawn, the spectrum and its ring profile read.23pub mod chladni;24/// The exact crops: the designs trimmed to rational shapes, tallied, swept, drawn and masked.25pub mod crop;26/// The design Mobius meter: its elements, the meter drawn against log x, its density echo and residual, and the ordinates its spectrum carries.27pub mod echo;28/// The alphabet: text laid out as a grid, written in stroke order, cycled, and read glyph by glyph.29pub mod font;30/// The primes of the plane: the Gaussian and the Eisenstein windows painted, counted, clicked and weighed by norm.31pub mod gauss;32/// The networks of the designs: nodes, branches, roles and censuses, and the force layout that relaxes them.33pub mod graph;34/// The laboratory: the sequence press and the moire presets.35pub mod lab;36/// The lattice: the Farey nodes, the totients and the window the stack lights, counted, painted and walked into pi.37pub mod lattice;38/// The ledger: every measure of every design as a sequence, searched, identified and read against the curated records.39pub mod ledger;40/// The life grids stepped, run and driven by sequences.41pub mod life;42/// The magic words: the folded design, its census, its press readings and its prefix rates.43pub mod magic;44/// The memory designs: a rule on `k` consecutive digits read, the words it accepts drawn, and the Perron root that measures them.45pub mod memory;46/// The standing patterns of a design mask: its eigenvalue field on the frequency torus, one eigenvalue, the large-values count and a real mode.47pub mod modes;48/// The Thue-Morse word: its two constructions, its plane lifts, its runs and the difference filter.49pub mod morse;50/// The novelty meter: the totients read through a smooth and a sharp window on a log grid of y, and the waves of the first zeros that the smooth reading is.51pub mod novelty;52/// The elementary partials: eight partial sums, products and prime counts read at one depth and walked to it.53pub mod partials;54/// The primes: the sieve stepped, the stone pile, the count chart and the carpet witness.55pub mod prime;56/// The race: seeded walkers loose on a flat design.57pub mod race;58/// The radix designs: a base in a ring of the plane, a digit per residue class with a unit twist, the points they place and the glue they collide into.59pub mod radix;60/// The crossing shell of a circle on a design, read as a rooted tree and painted.61pub mod shell;62/// The punctured schedules: the Wallis sieve rastered, its punctures listed, its ratios walked and its limits read.63pub mod sieve;64/// The hexagon projections of a cube as SVG.65pub mod six;66/// The snail: the whole numbers wound on the square spiral with every grown cell a design tile whose side is a power of the base.67pub mod snail;68/// The 3d scene kit: the packed wire format the shaders read.69pub mod space;70/// The Laplacian spectra of the designs: eigenvalues, degeneracy and the spectral exponent.71pub mod spectrum;72/// The turntable: designs, moire fields and slices spun about their centre into ring profiles and wheels.73pub mod spin;74/// The spirals: the whole numbers wound on a square or hexagonal sheet, painted, clicked and read along a quadratic.75pub mod spiral;76/// The spirograph: a flat design as the wheel, a pencil in every cell, rolled on a line, a circle or a polygon.77pub mod spirograph;78/// The ghost star of the hexagon moire: the stacked cut, the band it is measured on, the arm ink law and the cell-frame decay.79pub mod star;80/// The cubes as packed faces, filled cells and censuses.81pub mod three;82/// The tessellations: a design repeated across the plane, the cube and the hexagonal mesh, drawn and counted.83pub mod tile;84/// The tourbillon: the odd parity carpets spun about the centre, one angle per layer, stacked inside the inscribed disc.85pub mod tourbillon;86/// The inner tube of a design: its distance field, the tube area at a radius, the Minkowski profile and the closed limit of the interior-hole class.87pub mod tube;88/// The flat designs as byte grids, painted pixels and censuses.89pub mod two;90/// The cube designs stacked into a moire volume: its faces at a level, and the planes that cut it.91pub mod volume;92/// The mass side of a weighted design: its level-L mass field, the pressure, the multifractal spectrum and the local dimensions.93pub mod weights;94/// The critical line: zeta walked at one half plus i t, its zeros counted and listed, and the prime staircase against the explicit formula.95pub mod zeta;9697// THEME9899thread_local! {100    static DARK_MODE: Cell<bool> = const { Cell::new(true) };101}102103/// Switches every sheet painted from now on to the dark theme, or to the light one.104#[wasm_bindgen]105pub fn set_theme(dark: bool) {106    DARK_MODE.with(|mode| mode.set(dark));107}108109pub(crate) fn theme() -> &'static Theme {110    if DARK_MODE.with(Cell::get) {111        &DARK112    } else {113        &LIGHT114    }115}116117pub(crate) fn rgba(c: Color) -> [u8; 4] {118    [c.r, c.g, c.b, c.a]119}120121// SHEETS122123/// A byte grid: its width, its height and its row-major types.124#[wasm_bindgen(getter_with_clone)]125pub struct Grid {126    /// The count of columns.127    pub width: u32,128    /// The count of rows.129    pub height: u32,130    /// The type of every site, row by row.131    pub types: Vec<u8>,132}133134/// A pixel sheet: its width, its height and its row-major RGBA bytes.135#[wasm_bindgen(getter_with_clone)]136pub struct Pixels {137    /// The count of columns.138    pub width: u32,139    /// The count of rows.140    pub height: u32,141    /// Four bytes per pixel, row by row.142    pub rgba: Vec<u8>,143}144145/// The one error a call raises: a message the page catches as a thrown Error.146#[derive(Debug)]147pub struct Fault(String);148149impl Fault {150    fn new(message: impl Into<String>) -> Fault {151        Fault(message.into())152    }153}154155impl From<Error> for Fault {156    fn from(error: Error) -> Fault {157        Fault(error.to_string())158    }159}160161impl From<Fault> for JsValue {162    fn from(fault: Fault) -> JsValue {163        JsError::new(&fault.0).into()164    }165}166167impl Pixels {168    fn of(width: usize, height: usize, colors: Vec<[u8; 4]>) -> Pixels {169        Pixels {170            width: width as u32,171            height: height as u32,172            rgba: colors.concat(),173        }174    }175}176177fn code_of(text: &str) -> Result<u128, Fault> {178    text.trim()179        .parse()180        .map_err(|_| Fault::new(format!("code {text:?} is not a whole number.")))181}182183fn checked(code: &str, dimension: usize, base: usize) -> Result<u128, Fault> {184    let code = code_of(code)?;185    mrlyrs::math::bang::code_to_corners(Code::from(code), dimension, base)?;186    Ok(code)187}