lib.rs

7.2 kB · rust · 182 lines

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