import { type ViewController } from "@johnmorrisdotca/kazoku-ui/view-controls"; import type { GeoPoint, GlobeView } from "../types.ts"; import { type CameraMode, type LightMode } from "./earth.ts"; import { type PaintSpec } from "../paint/buffer.ts"; import type { SatelliteInfo, SatelliteRef, Satellites } from "../satellites/types.ts"; import { type SatelliteStyle } from "../space/satellite-layer.ts"; import { type SatelliteOthers } from "../space/satellite-focus.ts"; import { type PathStats } from "../space/path-controls.ts"; import { type PathHit, type PathRequest, type PathStyle } from "../space/paths.ts"; import type { Credit, DataSource } from "../data-door.ts"; import { type BodyLabelSettings } from "./body-label.ts"; import type { SkyKeepClear } from "../sky/keep-clear.ts"; import type { SkyLabelStyle } from "../sky/style.ts"; import { type Place, type PlaceLook } from "../markers/places.ts"; import { type CityNamesStyle } from "../cities/host.ts"; import { type BorderSets } from "../borders/lines.ts"; import type { BorderData, BorderStats } from "../borders/layer.ts"; import { type RouteLeg } from "../route.ts"; import type { GridStats } from "../grid/layer.ts"; import { type CountryNamesStats, type CountryNamesStyle } from "../country-names/host.ts"; import { type SeaNamesStats } from "../sea-names/host.ts"; import { setSharedRenderer, setThreeLoader } from "./shared.ts"; export { setSharedRenderer, setThreeLoader }; export type { CameraMode }; import type { OverlayHost } from "../markers/layer.ts"; import { type Layer } from "./tiers.ts"; import type { TileStats } from "./tile-set.ts"; type EarthLayer = Extract; /** * What the realistic Earth is doing: `loading` its pictures, `live` and drawing, `unavailable` (no WebGL), `lost` (the GPU took the context; it comes back by itself) or `idle` (another view has the page's one WebGL context; press or focus it to take it). * * @example * ```ts no-run * import type { ChikyuEarthRealistic, EarthState } from "@johnmorrisdotca/chikyu-earth/realistic/element"; * * const describe = (earth: ChikyuEarthRealistic): EarthState => earth.stats.state; * console.log(typeof describe); * ``` */ export type EarthState = "loading" | "live" | "unavailable" | "lost" | "idle"; type SatelliteStats = { groups: number; placed: number; segments: number; tooFast: boolean; dotScale: number; longestStreakPx: number; streakCapPx: number; weight: number; fade: number; earthPx: number; epochMs: number; propagations: number; lastBatchMs: number; maxBatchMs: number; updateMs: number; maxUpdateMs: number; averageUpdateMs: number; updates: number; selectedRing: boolean; hoverPath: boolean; hoverOpacity: number; selectedOpacity: number; orbitLines: number; estimated: number; }; /** * A `speed` attribute: how many seconds pass for each real second. * * @param value - The attribute's text, or `null` when it is not there. * @returns The speed, or `null` when the value is empty or not a number (the clock then follows `time`: real time for "now", held for a date). * * @example * ```ts no-run * import { readSpeed } from "@johnmorrisdotca/chikyu-earth/realistic/element"; * * console.log(readSpeed("86400"), readSpeed("-3600"), readSpeed(null)); * ``` */ export declare const readSpeed: (value: string | null) => number | null; /** * A `time` attribute: "now" (or none) follows the clock, else an ISO date such as 2026-06-21T12:00:00Z. * * @param value - The attribute's text, or `null` when it is not there. * @returns The moment in milliseconds since the Unix epoch, or `"now"` when the value is empty, `"now"` or not a date. * * @example * ```ts no-run * import { readTime } from "@johnmorrisdotca/chikyu-earth/realistic/element"; * * console.log(readTime("2026-06-21T12:00:00Z"), readTime(null), readTime("tomorrow")); * ``` */ export declare const readTime: (value: string | null) => number | "now"; /** * The `` custom element: the Earth from space, drawn with three.js through kazoku-ui's shared renderer (one WebGL context for the page). It takes `center` (`"lon,lat"`), `time` (`now` or an ISO date; the real Sun at that moment), `clouds="off"`, `lights="off"`, `live-seconds`, `texture-base` (where the pictures are served from), `tiles` (where a set of finer map tiles is served from, see the Earth tiles guide: only the tiles in view are loaded, over the package's own pictures, which stay as the far view and the fallback; without it, or when a tile cannot be fetched, the Earth is drawn as before) and `max-ratio` (the most device pixels to a CSS pixel the canvas is drawn at, 2 at most, and `0.5` draws at half the size and scales it up: for a background; read when the element connects, and it is the shared renderer's cap for the whole page), and a shared view controller's camera through `setView`. It draws only when something changes, at most 30 times a second, and nothing while it is out of sight or the tab is hidden. * * It has a clock, like ``'s: `speed` is how many seconds pass for each real second (`1` is real time, `0` holds, `3600` is an hour a second, `86400` a day a second, a negative number runs backwards), and the clock runs from `time`, the moment shown. * The Sun's light, the night side and the clouds follow it. Without a `speed`, nothing about a page from before changes: `time="now"` (or no `time`) follows the real clock, the Sun and the clouds put right every `live-seconds` (a minute by default, a second at the least), * and a date holds still. A `speed` runs the clock from the moment shown at that rate (from now, when `time` is "now"); `speed="0"` holds it. At real time it steps every `live-seconds`; faster, it draws as often as the Sun's turn moves a pixel, once a second at least and 30 a second at most * (a reader who prefers reduced motion gets one step a second), and nothing at all while it is held, out of sight or in a hidden tab. * * While time runs it sends `chikyu-timechange` with `detail: { time, running: true }` (the moment shown in milliseconds since 1970), at most four times a second however fast the picture is drawn and not from a hidden tab, and once with `running: false` when the clock holds * (a date is set, or `speed` is set to 0): a page writes the date into its date box from it. It is not sent for a `time` the page sets itself. * * `meteors` (the attribute, with or without a value other than `off`; the property is a boolean) draws meteors as they look from space: short streaks 80 to 120 km up, * only where it is dark or twilight, more of them where an active shower's radiant stands high and on the side that faces the Earth's way. Each streak's place and * moment are drawn at random (and said so in a line under the picture, which `meteors-label="off"` takes away for a page that says it itself); how many there are, * where they fall, their height and the showers' dates are real (`@johnmorrisdotca/chikyu-earth/meteors`). They run while the clock runs, at any speed, and not * at all while it is held, out of sight, in a hidden tab, or for a reader who prefers reduced motion until the page sets a `speed` (a Play). `chikyu-meteors` * is sent when the strongest active shower changes, with `detail: { shower, zhr }` (`shower` is `null` when none is active). * `meteors-strength` (0 to 1, the property `meteorsStrength`; 1 when the page says nothing) makes them subtler: fewer streaks and fainter ones, none at 0, and nothing that is real changes. * * `borders` draws the borders on the land as thin lines that turn with the Earth: `countries` (chizu's, at any size), `regions` (provinces, states and the like, from the page's `borderData.regions`, * once the Earth is large enough to tell them apart), or both with a bare attribute. The shapes are loaded only when a set is switched on; `chikyu-borders-unavailable` is sent when they cannot be. * * `grid` draws the meridians and parallels on the Earth (every 30 degrees while it is small on the screen, every 15 once it is large), with the equator, the tropics, the polar circles and the prime * meridian picked out, light on the day side and dim on the night side. `country-names` names the countries at the middle of the part of each in view, in the page's language, never over another * name, as many as fit (40 at most, or the number given); the outlines are loaded only when it is set, and `chikyu-country-names-unavailable` is sent when they cannot be. * * @example * ```ts no-run * import type { ChikyuEarthRealistic } from "@johnmorrisdotca/chikyu-earth/realistic/element"; * * const earth = document.createElement("chikyu-earth-realistic") as ChikyuEarthRealistic; * earth.setAttribute("center", "139.7,35.7"); * earth.setAttribute("time", "2026-06-21T03:00Z"); * earth.setAttribute("texture-base", "/textures/"); * earth.setAttribute("tiles", "/tiles/"); * earth.setAttribute("speed", "86400"); * earth.placeGroups = false; // place-groups="off": every place keeps its own ring * earth.paint = { id: "25544", length: "1d", swath: "track" }; * earth.clearPaint(); * earth.setAttribute("star-names", "12"); * earth.addEventListener("chikyu-sky-pick", (event) => { * const pick = (event as CustomEvent<{ kind: string; name?: string; abbreviation?: string }>).detail; * console.log(pick.kind, pick.name ?? pick.abbreviation); * }); * earth.addEventListener("chikyu-timechange", (event) => { * const { time, running } = (event as CustomEvent<{ time: number; running: boolean }>).detail; * console.log(new Date(time).toISOString(), running ? "running" : "held"); * }); * document.body.append(earth); * ``` */ export declare class ChikyuEarthRealistic extends HTMLElement { #private; static observedAttributes: string[]; connectedCallback(): void; disconnectedCallback(): void; attributeChangedCallback(name: string, _old: string | null, value: string | null): void; /** * How many times its real thickness the air is drawn, from 1 (the true thickness) to 5 (the attribute `air-thickness`; 3 when the page says nothing). The shell, and the heights over which the air thins, are that many times larger, and the * air's own light is the same, so a ring that is a hair's breadth at whole-Earth zoom can be seen. While it is above 1 the element says so in a line under the picture (`air-label="off"` takes the line away, for a page that says it itself). */ get airThickness(): number; set airThickness(value: number); /** * Meteors seen from space, on or off (the attribute `meteors`): see the class's description. Off by default, and nothing of theirs is made until they are first switched on. */ get meteors(): boolean; set meteors(value: boolean); /** * How strongly the meteors are drawn, from 0 to 1 (the attribute `meteors-strength`; 1, the full look, when the page says nothing): it scales how bright each streak is and how many are drawn, so 0.3 is * fewer and fainter and 0 draws none. It changes nothing that is real: the rates, the showers and `chikyu-meteors` are the same at every strength, and the line under the picture still says the streaks are an illustration. * A number outside the range is brought to its nearest end; setting the property writes the attribute. */ get meteorsStrength(): number; set meteorsStrength(value: number); /** * The name written on the Earth, as the family's body label: `EARTH` (`地球` on a Japanese page) laid on the globe so it turns with it, the surface showing through the letters. Off (`null`) unless the page sets it. The plain attributes are the family's: * `body-label` (`painted`, `etched`, `outline` or `burned`; absent, no label), `body-label-strength` (0 to 1, 0.5), `body-label-repeat` (`once`, `both` or `around`), `body-label-latitude` (degrees), `body-label-facing` (present: always facing the reader), * `body-label-font` (a CSS font family the page has loaded; Michroma, fetched once, when left out) and `body-label-fallback-font` (for letters the font has none of, such as Japanese). The property is the same options as an object, or `null`; setting it writes the attributes. * Nothing of it is fetched or made until it is first set, it is not drawn while the Earth is under 24 pixels in radius, and nothing is drawn at rest. A three.js handed over with `setThreeLoader` must include `CanvasTexture`, `SphereGeometry`, `MeshLambertMaterial`, `SRGBColorSpace`, `NormalBlending` * and `AdditiveBlending`; without them `chikyu-body-label-unavailable` is sent and the name is not drawn. */ get bodyLabel(): BodyLabelSettings | null; set bodyLabel(value: Partial | null); /** * The names of the brightest stars and the constellations as faint lines, laid over the sky the page draws (hoshi-stars' `sky-labels`, an optional peer loaded only when one of these is set). The plain attributes are hoshi's: `star-names` (a count of the brightest stars in view and not covered by the * Earth, the Moon or the Sun; bare is 10), `star-names-magnitude` (only stars at least that bright) and `constellation-lines` (the 88 figures as lines at this strength, 0 to 1; bare is 0.16): none of them, and nothing is loaded. The figure under the pointer or touched is at full strength and shows its name. Names are in the * page's language and never overlap. Nothing is redrawn at rest. `chikyu-sky-unavailable` is sent when hoshi-stars is not there. The property is the look of the names, a partial `SkyLabelStyle` (font, size, case, ring, leader and the rest). */ get skyStyle(): Partial; set skyStyle(value: Partial); /** * The constellation that is picked, by its IAU abbreviation (`Ori`), or `null`. A reader picks one by a click or a tap on its lines or inside its figure (and with the key `C`, or `Shift`+`C` for the previous, while the element has the focus); a click on empty sky, or `Escape`, lets it go. The picked figure's lines are lit and its name is * shown at the middle of the part of it in view, until another is picked or it is let go. A page sets the property to pick one itself, which sends no event. `chikyu-constellation-pick` is sent at each pick of the reader's, with `detail` `{ abbreviation, id, name, english, japanese, kind, culture }` (`culture` is `iau` unless `constellation-culture` names another), and `null` when it is let go; `chikyu-constellation-hover` is sent the same way as a mouse rests on a figure and leaves it. * A press or a tap on a named star, or on a figure, also sends `chikyu-sky-pick`: a star is `{ kind: "star", hr, name, designation, x, y, pointerType }` (`name` as drawn, `x` and `y` CSS pixels inside the element) and a figure is `{ kind: "constellation", abbreviation, pointerType }`. Each named star and each figure in view is a button, so a keyboard reaches it and Enter picks it, and the pick is read out; the keys `C` and `Shift`+`C` (the next and the previous figure) send it too. Nothing is drawn at rest. * Needs `constellation-lines` set. `constellation-culture` (`iau` by default, `western`, `japanese` or `chinese`; each is fetched only when asked for, and the value is exactly what the page sets) makes the figures, the pick and the names those of that sky culture. The attribute `constellation-names` (off by default) writes the name of every figure in view at the middle of the part of it that is on the picture, quieter than the star names and clear of them, of the Earth, the Moon, the Sun, the places and satellites named, and of the places kept clear (`keepClear`). */ get constellation(): string | null; set constellation(value: string | null); /** * Places on the picture where the sky's names must not go: a page's own text laid over the element, say. Each is a rectangle in the element's own CSS pixels from its top left (`{ x, y, width, height }`), or an element of the page whose box is read. A star name whose box touches * one is left out, and so is a star whose point is in one (the next star is named instead); the picked constellation's name is moved clear of it. The lines are still drawn. The boxes are read when the list changes, when the page or an element is resized or scrolled, and not at each frame: a * page that moves its text without resizing it sets the property again. The attribute `keep-clear` takes a CSS selector for the same (`keep-clear=".hero h1, .hero .lead"`). Nothing is redrawn at rest. */ get keepClear(): SkyKeepClear[]; set keepClear(value: readonly SkyKeepClear[] | null); /** * Places marked on the Earth (the attribute `places`, a JSON array): each `{ id, lon, lat, label, kind, color }`, `kind` being `here` (where the reader is: drawn bright and taller, with a quiet pulse) or `favourite` * (the default: quieter), and `color` an optional CSS colour of its own. The first `PLACE_MARKS` in sight (`here` first, then in the order given) stand up out of the ground with their names; every other place * is a ring on the ground, all of them one draw call, and places that crowd are gathered into one ring with their count. They turn with the Earth, are hidden on its far side, are dimmer on its night side * and keep their size in pixels at any zoom. Names never overlap one another; one with no room is left out. The element stores nothing and sends nothing: the page hands the places over and keeps them where * it likes. Setting the property writes the attribute; at most `MAX_PLACES` are drawn. Nothing is drawn again at rest: the pulse is the page's own animation, stopped out of sight and for a reader who asked * for less motion. */ get places(): Place[]; set places(value: readonly Place[]); /** * Name each `here` place with the nearest city (the attribute `here-city`). `false` (the default) leaves the page's label and loads nothing. * `true` looks within 100 km (`HERE_CITY_KM`). A number is that limit in kilometres, at most 20,000 (`HERE_CITY_MAX_KM`); a city further away is not used, and the page's label stays. * The cities are kuni's capitals, the other cities of a million and the others of 100,000, an optional peer loaded only when this is on and a `here` place is set. The name follows the page's language * (the short Japanese name, then the Japanese name, else English). `places` is not changed: only the drawn name is. Nothing is drawn again at rest. * * @example * ```ts no-run * import type { ChikyuEarthRealistic } from "@johnmorrisdotca/chikyu-earth/realistic/element"; * * const earth = document.querySelector("chikyu-earth-realistic") as ChikyuEarthRealistic; * earth.hereCity = true; * console.log(earth.hereCity); // 100 * earth.hereCity = false; * ``` */ get hereCity(): false | number; set hereCity(value: false | true | number); /** * A route between two places (the attribute `route`, `lon,lat,lon,lat`). Null, the default, draws none. The line is the WGS84 geodesic, split at the date line, and it turns with the Earth. * Setting the property writes the attribute. Nothing is drawn again at rest: the line is drawn with the picture, and only when the route or the view changes. */ get route(): { from: GeoPoint; to: GeoPoint; } | null; set route(value: { from: GeoPoint; to: GeoPoint; } | null); /** The distance, bearings and flight-time estimate for `route`, or null when none is set. The flight time assumes 900 km/h. */ get routeInfo(): RouteLeg | null; /** * Turn the Earth so a place of `places` is in the middle, at a pace a reader can follow (at once with `smooth: false`, for a reader who asked for less motion, or before the picture is live); the zoom * and pan stay. The place is named by its `id`, or by its label in any case. The tilt is held to 90 degrees either way, so a place more than 90 degrees of latitude from `center` comes as near the middle * as that allows. * * @param text - The place's id or label. * @param options - `smooth` (true by default). * @returns The place, once the turn has started; `undefined` when there is no such place. */ goToPlace(text: string, options?: { smooth?: boolean; }): Promise; /** * Whether places that crowd are gathered into one ring with their count (the attribute `place-groups`): on by default, `off` leaves every place its own ring. Setting the property writes the attribute. * * @example * ```ts no-run * import type { ChikyuEarthRealistic } from "@johnmorrisdotca/chikyu-earth/realistic/element"; * * const earth = document.querySelector("chikyu-earth-realistic") as ChikyuEarthRealistic; * earth.placeGroups = false; * earth.getAttribute("place-groups"); // "off" * earth.placeGroups = true; * earth.hasAttribute("place-groups"); // false * ``` */ get placeGroups(): boolean; set placeGroups(value: boolean); /** How the places are drawn (the attribute `places-look`): `beam` (a light rising out of the ground with a ring at its foot, the default), `pin` (a thin stick with a round head) or `ring` (only the ring on the ground). */ get placesLook(): PlaceLook; set placesLook(value: PlaceLook); /** * The look of the names of cities (`city-names`): font, size, weight, colour, the outline round the text, and the dot's colour and size. Any of them may be left out; the Earth's size, the language and the data are not set here. */ get cityNamesStyle(): CityNamesStyle; set cityNamesStyle(value: CityNamesStyle); /** Whether the meridians and parallels are drawn (the attribute `grid`). Setting it writes the attribute, or takes it away. */ get grid(): boolean; set grid(value: boolean); /** * The look of the names of countries (`country-names`): font, weight, colour, the outline round the text, and the smallest and largest text size. Any of them may be left out; the Earth's size, the * language and the data are not set here. */ get countryNamesStyle(): CountryNamesStyle; set countryNamesStyle(value: CountryNamesStyle); /** * Names of oceans, seas and continents (the attribute `sea-names`). Off unless set: a bare attribute is on. Oceans and continents from far out, seas once the Earth is large on the screen. A city name keeps the space where both fit only one. Nothing is drawn again at rest. * * @example * ```ts no-run * import type { ChikyuEarthRealistic } from "@johnmorrisdotca/chikyu-earth/realistic/element"; * * const earth = document.querySelector("chikyu-earth-realistic") as ChikyuEarthRealistic; * earth.seaNames = true; * console.log(earth.seaNames); * earth.seaNames = false; * ``` */ get seaNames(): boolean; set seaNames(value: boolean); /** * Which borders are drawn (the attribute `borders`): the countries' at any size, and the regions' (provinces, states, prefectures) once the Earth is large enough on the screen to tell them apart. * Setting it writes the attribute: both sets as `borders="countries regions"`, one as its own word, none takes the attribute away. */ get borders(): BorderSets; set borders(value: BorderSets); /** * Where the borders' shapes come from (see `BorderData`): `countries` in place of chizu's `world-geo`, and `regions`, a country's regions by its code, which draws the regions; without it none are drawn. * Set it before `borders` is switched on: shapes already loaded are kept. */ get borderData(): BorderData; set borderData(value: BorderData); /** The controller behind the element's own hands (`set`, `fit`, `state`), while it is in a page. */ get controller(): ViewController | undefined; /** * The outside sources of map this Earth draws from (the data door): each carries its own licence and credit, and a map source for the `day` or `night` layer takes the place of the folder of tiles for that layer. Assign a list to * replace them; a source that is refused (an empty credit, no licence, a clashing id, a kind the Earth does not draw, a layer it does not know) throws a `TypeError` and nothing changes. A property, never an attribute: data is not text. */ get sources(): readonly DataSource[]; set sources(list: readonly unknown[]); /** Adds an outside source of map: checked at once (a `TypeError` for one that is refused), and the Earth draws from it. Returns the function that takes it away. */ addSource(source: unknown): () => void; /** Takes a source away by its id: its loads stop, its tiles are freed, its credit goes. Returns whether there was one. */ removeSource(id: string): boolean; /** Switches a source off (`false`) or on again, and keeps it in the Earth: a layers panel's switch. The attribute `data="own"` ignores every outside source at once. */ enableSource(id: string, on: boolean): void; /** * Whose data is in the last drawn frame: the package's own first (its pictures; its finer tiles while a window of them is in view) and then each outside source that gave a tile, with how many (`used`). `creditLine(credits, "en" | "ja")` * from `@johnmorrisdotca/chikyu-earth/door` writes them as a line with the licences. `chikyu-creditschange` fires when this set changes (not at each frame), with `detail: { credits }`. */ credits(): Credit[]; /** Where the finer map tiles are served from (a folder with `manifest.json`), or `null` for none; the attribute `tiles`. The Earth loads only the tiles in view, over its own pictures. */ get tiles(): string | null; set tiles(value: string | null); /** * Finer imagery than the package's own tiles, read by the browser from NASA's imagery service. `gibs` turns it on; anything else, or leaving it out, leaves it off. The picture is NASA's Landsat annual true-colour mosaic (30 m, no cloud, land only, the year 2000), laid over the package's picture only where the view is closer than the package's own tiles; where it has no data (the sea, Antarctica, the far north) the package's picture stays. A tile that is slow or missing leaves the coarser picture in place. * `tiles-finer-layer` is `landsat` (the default), `today` (the daily MODIS Terra picture, with its clouds, for the most recent day that has one, looked for from the day before the moment on show back at most 10 days, one tile a day) or another layer's id. `tiles-finer-date` names a year of the Landsat mosaic by its date (`1990-06-01`), or, for a daily layer, is `latest` (the default), `previous-day`, `shown` or one day `yyyy-mm-dd`. `tiles-finer-timeout` is how many milliseconds a tile is given to arrive before it is left (2000 when the page says nothing). */ get tilesFiner(): string | null; set tilesFiner(value: string | null); /** A box laid over the Earth for markers (see `@johnmorrisdotca/chikyu-earth/markers`): where it is, the pose of the last draw, and a way to hear the next. */ get overlay(): OverlayHost; /** Where the view starts: longitude and latitude; the shared controls' yaw and tilt turn it from there. */ get centre(): GeoPoint; set centre(value: GeoPoint); /** * How the camera is held (the `camera` attribute). `space` (the default): held in the stars, looking at the place `center` names as it is at the * moment the camera is set (when the element opens, and again when `time` or `center` is set), so the Earth turns beneath it as the clock runs, with the day and night line where the Sun really is. `ground`: over the place `center` names on the ground, so the Earth keeps still and the clock moves the light across it. `sun`: held on the Sun's side, `center` being the longitude and * latitude from the sub-solar point (`0,0` looks straight at the noon place and shows no night), so the day and night line keeps its place on the screen while the Earth turns beneath. A drag turns the view about the same body in any of them. */ get camera(): CameraMode; set camera(value: CameraMode); /** True for the full-screen mode (the `immersive` attribute): the element fills its box in any shape, a plain wheel zooms instead of scrolling the page, and a touch drag turns the view instead of scrolling. */ get immersive(): boolean; set immersive(value: boolean); /** The moment shown: milliseconds since the epoch, or "now" while it follows the real clock. The clock runs from it at `speed`, so a number read while time runs is the moment it has reached. */ get time(): number | "now"; set time(value: number | Date | "now"); /** * Seconds of time for each real second: `1` is real time, `0` holds, `3600` is an hour a second, `86400` a day a second, a negative number runs backwards. Without one (the attribute `speed` left out) the clock * follows `time`: real time for "now", held for a date. Reading it gives the speed in force. Setting it is setting the attribute (and `null`-like, a value that is not a number, takes it off); it works out the moment shown up to now at the old speed first, so a hold keeps the moment the reader saw last. */ get speed(): number; set speed(value: number); get clouds(): boolean; set clouds(value: boolean); /** How the Earth is lit: `sun` (true, the default), `lit` (always lit: the night side is never a black frame) or `boost` (the true terminator with the night side raised). */ get light(): LightMode; set light(value: LightMode); get lights(): boolean; set lights(value: boolean); /** What the element is doing, for a page or a test: its state, the texture widths held, the map tiles held, the draws made. */ get stats(): { state: EarthState; tiers: Record; tiles: TileStats; satellites: SatelliteStats; /** The cross-fade when `light` changes to or from `lit` (300 ms, a cut under reduced motion): `mix` is 0 for the true light and 1 for `lit`, and `fading` is true while it moves and another frame is wanted. */ lightFade: { mix: number; fading: boolean; }; /** The page's paths: asked for, drawn (with the chosen satellite's own), left out over the cap of 16, unmatched, whether the chosen satellite's own orbit is drawn, draw calls they took at the last draw (0 or 1), the path under the mouse and the `chikyu-path-click` events sent. */ paths: PathStats; draws: number; contexts: number; canvas: { width: number; height: number; pixels: number; }; assets: { entries: number; refs: number; }; /** The meteors: whether they are on, the streaks alive now and started so far, the streaks a second being drawn, and the strongest active shower's code and rate. */ meteors: { on: boolean; strength: number; alive: number; spawned: number; perSecond: number; shower: string | null; zhr: number; }; /** The name written on the Earth: whether `body-label` is set, its text, the label is made, and it is showing (it is hidden while the Earth is small). */ bodyLabel: { on: boolean; text: string; made: boolean; showing: boolean; }; /** The names of the stars and the constellation lines: whether one is asked for, whether hoshi-stars is loaded, the names and figures laid out at the last draw, the figure picked, how many times the layer was drawn, the language its names were last laid out in, and the named stars' own points on the screen (`stars`). */ sky: { on: boolean; loaded: boolean; names: number; figures: number; picked: string | null; pick: string | null; hover: string | null; constellations: number; culture: string; renders: number; lang: string; stars: { text: string; x: number; y: number; }[]; }; /** The places: how many were handed over, how many are drawn and named at the last draw, and how many times they were laid out. `sprites` is the rings in the picture's one draw call (0 when it cannot draw them); `dots` is the circles drawn in the page instead. */ places: { places: number; shown: number; labels: number; renders: number; marks: number; groups: number; sprites: number; dots: number; omitted: number; }; /** The nearest city on a `here` marker (`here-city`): whether it is on, the kilometre limit (0 when off), whether kuni's cities have arrived, and whether that load is still going. */ hereCity: { on: boolean; maxKm: number; loaded: boolean; pending: boolean; }; /** The names of cities: whether `city-names` is set and the most it asks for, the Earth's radius on the screen, the tiers of kuni's cities that have arrived and how many cities, the names shown at the last draw and how many times the layer was drawn. */ cityNames: { on: boolean; max: number; radius: number; tiers: string[]; cities: number; names: number; renders: number; }; /** The borders: the segments of each set, whether each was drawn at the last draw, the countries whose regions have arrived, how many times a set's lines were made, and whether a set could not be loaded. */ borders: BorderStats; /** The grid: whether it was drawn at the last draw, whether every 15 degrees (else 30), its segments then, how many times its lines were made, and whether it could not be made. */ grid: GridStats; /** The route between two places: whether one is set, and its geodesic distance, great-circle distance and flight time at 900 km/h. */ route: { on: boolean; kilometres: number; greatCircleKm: number; flightHours: number; }; /** The names of countries: whether `country-names` is set and the most it asks for, the countries loaded, the names shown at the last draw, how many times they were laid out, and whether the outlines could not be loaded. */ countryNames: CountryNamesStats; /** The names of oceans, seas and continents: whether `sea-names` is on, the Earth's radius on the screen, the names shown at the last draw, and how many times the layer was laid out. */ seaNames: SeaNamesStats; }; /** * Apply a shared view controller's camera (yaw, tilt, zoom, pan). A change under half a pixel is not drawn, a settled change always is, * and draws are at most 30 a second. */ setView(view: GlobeView, final?: boolean): void; /** * Colour each satellite by its orbit class (low, medium, geostationary, highly elliptical, other). Off by default, so a group keeps the colour it was given. The attribute is `satellite-tint="orbit"`. */ get satelliteTint(): "off" | "orbit"; set satelliteTint(value: "off" | "orbit"); /** * The longest a satellite's streak may be on the screen, in CSS pixels (the attribute `satellite-streak-max`; 8 when the page says nothing; `0` or `off` for no cap). Above 60 times real time each satellite is drawn as a streak along its orbit * for the stretch one frame spans, and at a fast clock that stretch is long: at an hour a second a low satellite would cross a tenth of the Earth in one frame. The cap is a length on the screen, so a low and a high satellite are drawn equally long, and the streak keeps the look it has at 10 minutes a second at any speed. It is the smaller of this number of pixels and 0.025 of the Earth's drawn radius (about 160 km of orbit, what a low satellite covers in a frame at 10 minutes a second), so as the Earth is drawn smaller the streak shrinks in proportion, to a dot, instead of staying as long on a small Earth as on a large one. The marks also lose weight on a small Earth: below a drawn radius of 150 pixels the streaks are fainter and the dark rim of the dots fades, gone at 40 pixels, and a crowd of satellites on a small Earth is drawn fainter in proportion so thousands of them do not wash it. Pointing along the orbit and ending at the satellite, it is the same length at any frame rate. Off restores the whole stretch. * * @example * ```ts * import "@johnmorrisdotca/chikyu-earth/realistic/element"; * * const earth = document.querySelector("chikyu-earth-realistic")!; * earth.satelliteStreakMax = 12; * ``` */ get satelliteStreakMax(): number; set satelliteStreakMax(value: number); /** * Show a group of satellites (made by `createSatellites`) under a name, or take the group away with `null`. A group is one draw call however many satellites it holds, so every group of the catalogue can be shown at once. Giving the name of a group * that is already shown replaces it. `style`: `color` and `size` (CSS pixels) of the dots, and `orbits` to draw every orbit (only for a group of 40 or fewer, such as the stations). The groups are placed by SGP4 about once a second and interpolated * between. Above `MAX_SATELLITE_SPEED` each satellite is a short streak along its orbit instead of being hidden. They are hidden by the Earth when they are behind it, and draw at most 30 times a second and not at all while the clock holds. * * @param group - The group's name, for `showSatellites`, `selectSatellite` and the events. * @param satellites - The group, or `null` to remove it. * @param style - How to draw it. */ /** * Paint one satellite's path on the Earth. `id` is a NORAD catalogue number or `group:index`. `length` is how long the trail is kept, in simulated time (`1d` when left out, or `1w`, `1m`). `swath` is `track` (the point under the satellite, the default) or `coverage` (where it is at least 10° above the horizon). Setting another satellite clears the trail. `null` clears it. */ get paint(): PaintSpec | null; set paint(value: PaintSpec | null); /** Take the painted trail off the Earth. */ clearPaint(): void; /** Texels the trail has painted. 0 after `clearPaint`, and again when the painted satellite changes. */ get paintPixels(): number; setSatellites(group: string, satellites: Satellites | null, style?: Partial): void; /** Show or hide a group without losing it. */ showSatellites(group: string, on: boolean): void; /** * The groups now set. `count` is how many satellites the group holds, `visible` is the shown state from `showSatellites` (a focus does not change it), `placed` is how many the last draw placed (0 when the group is not drawn) and `emphasis` is how a focus treats it: `focus`, `dim`, `hidden` or `plain` (no focus). */ get satelliteGroups(): { name: string; count: number; visible: boolean; placed: number; emphasis: "focus" | "dim" | "hidden" | "plain"; }[]; /** The group `focusSatelliteGroup` is showing on its own, or `null`. */ get focusedSatelliteGroup(): string | null; /** * Show one group on its own. The others are drawn dimmer (`others: "dim"`, the default, through the same dimming an old element set uses) or not drawn (`"hide"`). `frame` (true by default) pulls the camera back, by this view's own zoom, until the group's orbits fit: the distance is the greatest apogee of the group, from each satellite's mean motion and eccentricity, and it stops at 8 Earth radii. `null` puts every group back to the shown state it had, and puts the camera back when it was moved. A name that `setSatellites` has not set returns `{ ok: false, reason: "not-set" }` and changes nothing. It does not throw. When the choice changes, `chikyu-satellite-focus` is sent with `{ group, count }`. * * @param name - The group's name, or `null` to clear the focus. * @param options - `others` and `frame`. * @returns `{ ok: true, group, count }` when the group is set (`group` is `null` and `count` is 0 when cleared). `{ ok: false, reason: "not-set" }` when it is not. */ focusSatelliteGroup(name: string | null, options?: { others?: SatelliteOthers; frame?: boolean; }): { ok: true; group: string | null; count: number; } | { ok: false; reason: "not-set"; }; /** * Draw a faint orbit while the pointer rests on a satellite. On unless `hover-path="off"`. Left unset, it is on when `names-on-hover` is on. * The colour and the opacity are the custom properties `--chikyu-hover-path` and `--chikyu-hover-path-opacity`. */ get hoverPath(): boolean; set hoverPath(value: boolean); /** Show a satellite's name while the pointer rests on it. On unless `names-on-hover="off"`. A touch does not rest, so it shows nothing. */ get namesOnHover(): boolean; set namesOnHover(value: boolean); /** Mark one satellite: a larger ring round it and its orbit drawn. `null` lets it go. */ selectSatellite(ref: SatelliteRef | null): void; /** * Where a satellite is on the screen as of the last draw: `{ x, y, visible, heightKm }` in CSS pixels from the view's top left, `visible` meaning it is inside the box and not behind the Earth. `null` when its group is not set or not shown, it cannot be placed, or it is behind the camera. */ placeSatellite(ref: SatelliteRef): { x: number; y: number; visible: boolean; heightKm: number; } | null; /** * Keep placing satellites that are far from their element sets, as an estimate (the attribute `estimate-far`, off unless set; `estimate-far="off"` is off). A satellite is left out when the moment shown is more than `maxAgeDays` (30) from its elements; on, it is carried forward or back by the same SGP4 code * instead, and drawn lighter than a dimmed one. **An estimate is where the satellite would be if its orbit had not changed since the elements were taken.** It is worst for low orbits (drag changes them within days, and a manoeuvre moves the satellite along its path, so after weeks the estimate can be far along the orbit from the truth, and a satellite that has re-entered is not there at all) and for a long time away; a high orbit changes slowly and is close for months. Never before a satellite's launch or after its decay when its elements carry `LAUNCH_DATE` and `DECAY_DATE` (else the year of its `OBJECT_ID` is the earliest); * one SGP4 cannot carry that far, or brings down below about 120 km, is left out and is not counted as placed. Each estimated satellite is `estimated: true`, with `estimatedDays`, in `placeSatellite`, `satelliteInfo`, `chikyu-satellite-visibility` and `chikyu-satellite-click`, and `stats.satellites.estimated` counts them. * It applies to every group, those the page made with `createSatellites(sets, { estimateFar: true })` too. * * @example * ```ts * import type { ChikyuSpace } from "@johnmorrisdotca/chikyu-earth/space"; * * const farFromToday = (space: ChikyuSpace): void => { * space.estimateFar = true; * space.addEventListener("chikyu-satellite-click", (event) => console.log((event as CustomEvent).detail.estimated, (event as CustomEvent).detail.estimatedDays)); * }; * console.log(typeof farFromToday); * ``` */ get estimateFar(): boolean; set estimateFar(value: boolean); /** The satellite marked by `selectSatellite` or by a press on it, if any. */ get selectedSatellite(): SatelliteRef | null; /** * Draw these satellites' orbits at once, each in a look from the table (`pathStyles`), without a satellite being chosen. One draw call for all of them and the chosen satellite's own orbit, and nothing is drawn at rest. At most 16 are kept, the last of the list. * `id` is a NORAD catalogue number or `group:index` (`stations:0`); an id that matches no satellite is skipped (`stats.paths.unresolved`). A satellite asked for twice is drawn once, in the later look. `style` is the name of a look (`selected`, `hovered`, `favourite`, `path`, or one of the page's own) * or a partial look over `path`. `[]` takes them all away. Where the pointer is on one, `chikyu-path-hover` and `chikyu-path-click` say which (`path-hit`). * * @param list - The paths, oldest first. * * @example * ```ts * import type { ChikyuSpace } from "@johnmorrisdotca/chikyu-earth/space"; * * const show = (space: ChikyuSpace): void => space.setPaths([{ id: 25544, style: "favourite" }, { id: "stations:1", style: { color: "#7fdbff", dash: [8, 4] } }]); * console.log(typeof show); * ``` */ setPaths(list: readonly PathRequest[]): void; /** The paths in use, as set (the last 16). Setting it is `setPaths`. */ get paths(): PathRequest[]; set paths(list: readonly PathRequest[]); /** * Change the looks the paths are drawn in, by name. Each entry is a partial look over the built-in one of that name (or over `path`, for a name of the page's own); `null` takes the page's entry away. Without `replace` the entries are added to those already set. * The built-in looks differ by width and dash as well as colour: `selected` (white, 2 px, solid, also the look of the chosen satellite's own orbit), `hovered` (white, 1.5 px, dashed), `favourite` (amber, 1.75 px, dotted) and `path` (white, 1.5 px, solid). * A look is `{ color, width (0.5 to 8 CSS pixels), opacity (0 to 1), dash ([dash, gap] in CSS pixels, or null) }`. * * @param table - The entries by name. * @param replace - `true` to drop the entries set before. * * @example * ```ts * import type { ChikyuSpace } from "@johnmorrisdotca/chikyu-earth/space"; * * const quiet = (space: ChikyuSpace): void => space.setPathStyles({ selected: { color: "#ffd166", width: 3, dash: null } }); * console.log(typeof quiet); * ``` */ setPathStyles(table: Readonly | null>>, replace?: boolean): void; /** The table of looks in use, whole: the built-in ones with the page's own over them. A copy. */ get pathStyles(): Record; set pathStyles(table: Readonly | null>>); /** * Draw the chosen satellite's own orbit (the attribute `selected-path`; on unless `off`). Off, `selectSatellite` still rings and names the satellite and a ride still follows it, but no line is drawn: the page draws it, with `setPaths` and the `selected` look, or its own. The look of the line when it is on is the `selected` entry of `pathStyles`. */ get selectedPath(): boolean; set selectedPath(value: boolean); /** * How near, in CSS pixels, the pointer has to be to a path for the pick and hover events to report it (the attribute `path-hit`; 8 when left out, 0 to 40; `0` or `off` turns the test off). A touch is given twice that, and at least 16. * The test covers the page's paths and the chosen satellite's own orbit, not the part of an orbit the Earth hides, and a satellite's dot under the pointer comes first. In a ride from a satellite the test is off unless the attribute is set. */ get pathHit(): number; set pathHit(value: number); /** * Which is heard first where a satellite's dot and a path lie under the pointer (the attribute `path-priority`): `dots`, the default, or `paths`. With `dots` a press or a hover is the dot's, and a path is heard only where no dot is within 12 px: at the Low level, with thousands of dots crowding a line, a path can go unheard. * With `paths` a path of the page's (`setPaths`, or the chosen satellite's own orbit) is heard before a dot, **except** a dot of a satellite that is itself one of the paths' satellites or the chosen or ridden one: that satellite's own dot still wins, and a press on it is `chikyu-satellite-click`. * Either way one press has one meaning, in this order. `dots`: any dot, then a path, then the sky. `paths`: a listed or chosen satellite's dot, then a path, then any other dot, then the sky. Anything but `paths` reads as `dots`. */ get pathPriority(): "dots" | "paths"; set pathPriority(value: "dots" | "paths"); /** * The path under a point of the element, from the last draw: its id as given, the satellite (`ref`, the same shape as in `chikyu-satellite-click`), the name of its look, the nearest point on it and the distance to it, or `null`. * * @param x - CSS pixels from the element's left. * @param y - CSS pixels from its top. * @param radiusPx - How near the point must be, 0 to 200; `path-hit` when left out. * @returns The path, or `null` when none is within reach. * * @example * ```ts * import type { ChikyuSpace } from "@johnmorrisdotca/chikyu-earth/space"; * * const name = (space: ChikyuSpace, x: number, y: number): string => space.pathAt(x, y, 10)?.style ?? "none"; * console.log(typeof name); * ``` */ pathAt(x: number, y: number, radiusPx?: number): PathHit | null; /** Facts about one satellite at the moment shown (name, number, element age, height, speed, period, and `ownerCountry` when the owner is one country); undefined if it cannot be placed then. */ satelliteInfo(ref: SatelliteRef): SatelliteInfo | undefined; /** The view as it is (for a page that wants to read it back). */ get view(): GlobeView; } declare global { interface HTMLElementTagNameMap { "chikyu-earth-realistic": ChikyuEarthRealistic; } }