@restless-dreams/orbit 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/bin/orbit.js +2972 -213
- package/dist/bin/orbit.js.map +25 -13
- package/dist/{chunk-mtrnm0yc.js → chunk-fkdfgtx9.js} +3156 -2854
- package/dist/chunk-fkdfgtx9.js.map +75 -0
- package/dist/{chunk-7n00wx0t.js → chunk-y748hzcr.js} +2 -2
- package/dist/{chunk-0gwh723s.js → chunk-zze4tc9n.js} +2 -2
- package/dist/core/branch-colors.d.ts +57 -0
- package/dist/core/document-source.d.ts +1 -1
- package/dist/core/editing.d.ts +8 -5
- package/dist/core/engine/scene.d.ts +5 -4
- package/dist/core/engine/views.d.ts +10 -2
- package/dist/core/index.d.ts +10 -0
- package/dist/core/input-controller.d.ts +7 -0
- package/dist/core/languages.d.ts +2 -0
- package/dist/core/node-attributes.d.ts +1 -1
- package/dist/core/other-apps/freemind.d.ts +8 -0
- package/dist/core/other-apps/icons.d.ts +16 -0
- package/dist/core/other-apps/ideas.d.ts +76 -0
- package/dist/core/other-apps/import.d.ts +28 -0
- package/dist/core/other-apps/inflate.d.ts +22 -0
- package/dist/core/other-apps/markup.d.ts +51 -0
- package/dist/core/other-apps/notes.d.ts +80 -0
- package/dist/core/other-apps/opml.d.ts +26 -0
- package/dist/core/other-apps/reading.d.ts +36 -0
- package/dist/core/other-apps/xmind.d.ts +14 -0
- package/dist/core/other-apps/zip.d.ts +37 -0
- package/dist/core/print-layout.d.ts +70 -0
- package/dist/core/renderer/content-painter.d.ts +30 -0
- package/dist/core/renderer/dom.d.ts +15 -0
- package/dist/core/renderer/families.d.ts +35 -0
- package/dist/core/renderer/label-painter.d.ts +93 -0
- package/dist/core/renderer/node-painter.d.ts +113 -0
- package/dist/core/renderer/numbers.d.ts +2 -0
- package/dist/core/renderer/options.d.ts +12 -0
- package/dist/core/renderer/rings-and-links.d.ts +23 -0
- package/dist/core/renderer/scene-helpers.d.ts +33 -0
- package/dist/core/renderer/trees.d.ts +22 -0
- package/dist/core/svg-renderer.d.ts +6 -109
- package/dist/core/types.d.ts +9 -1
- package/dist/core/web-page/page.d.ts +2 -1
- package/dist/core/web-page/runtime.d.ts +1 -1
- package/dist/index.js +2935 -26
- package/dist/index.js.map +18 -6
- package/dist/marked/index.js +2 -2
- package/dist/react/index.js +2 -2
- package/dist/web-page.js +79 -79
- package/llms-full.txt +205 -5
- package/llms.txt +2 -1
- package/package.json +1 -1
- package/skills/orbit/SKILL.md +1 -1
- package/skills/orbit/references/editing.md +2 -1
- package/skills/orbit/references/format.md +28 -0
- package/skills/orbit/references/guide.md +25 -1
- package/skills/orbit/references/import-export.md +115 -0
- package/skills/orbit/references/languages.md +1 -0
- package/skills/orbit/references/recipes.md +9 -0
- package/skills/orbit/references/theming.md +15 -0
- package/dist/chunk-mtrnm0yc.js.map +0 -63
- /package/dist/{chunk-7n00wx0t.js.map → chunk-y748hzcr.js.map} +0 -0
- /package/dist/{chunk-0gwh723s.js.map → chunk-zze4tc9n.js.map} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads files out of a zip archive, such as an XMind map: its directory,
|
|
3
|
+
* then each entry on request, stored or deflated, checked against its
|
|
4
|
+
* CRC-32. Archives that span disks, need ZIP64 or are encrypted are refused,
|
|
5
|
+
* and so is an entry that would unpack past the archive's limits.
|
|
6
|
+
*/
|
|
7
|
+
/** An archive that can't be read, or an entry that can't be unpacked. */
|
|
8
|
+
export declare class ZipError extends Error {
|
|
9
|
+
constructor(message: string);
|
|
10
|
+
}
|
|
11
|
+
export interface ZipLimits {
|
|
12
|
+
/** The most entries an archive may list. */
|
|
13
|
+
entries: number;
|
|
14
|
+
/** The most bytes one entry may unpack to. */
|
|
15
|
+
entrySize: number;
|
|
16
|
+
/** The most bytes all the entries read may unpack to, together. */
|
|
17
|
+
totalSize: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_ZIP_LIMITS: ZipLimits;
|
|
20
|
+
/** Whether bytes start the way every zip archive does. */
|
|
21
|
+
export declare const isZip: (bytes: Uint8Array) => boolean;
|
|
22
|
+
export declare class ZipArchive {
|
|
23
|
+
private readonly bytes;
|
|
24
|
+
private readonly view;
|
|
25
|
+
private readonly limits;
|
|
26
|
+
private readonly entries;
|
|
27
|
+
private unpacked;
|
|
28
|
+
constructor(bytes: Uint8Array, limits?: Partial<ZipLimits>);
|
|
29
|
+
/** The names of the files in the archive, folders left out. */
|
|
30
|
+
get names(): string[];
|
|
31
|
+
has(name: string): boolean;
|
|
32
|
+
/** An entry's bytes, or null when the archive has no such file. */
|
|
33
|
+
read(name: string): Uint8Array | null;
|
|
34
|
+
/** An entry as UTF-8 text, or null when the archive has no such file. */
|
|
35
|
+
text(name: string): string | null;
|
|
36
|
+
private readDirectory;
|
|
37
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A map laid out for paper: its title, the map as a picture that fits the
|
|
3
|
+
* page, then every idea in reading order with its details, link, note and
|
|
4
|
+
* media. Orbit's web pages print with it, and so can any page that shows a
|
|
5
|
+
* map: lay it out in an element that only shows in print.
|
|
6
|
+
*/
|
|
7
|
+
import { type OrbitNodeType, type OrbitStatusStyle } from './extensions.js';
|
|
8
|
+
import { type OrbitStrings } from './languages.js';
|
|
9
|
+
import { type OrbitThemeName } from './themes.js';
|
|
10
|
+
import type { OrbitDocument, OrbitNode, OrbitRendererTheme, OrbitThemePreset, ViewMode } from './types.js';
|
|
11
|
+
export interface OrbitPrintOptions {
|
|
12
|
+
/** The heading at the top. Default: the map's `title`, or its root's text. */
|
|
13
|
+
title?: string;
|
|
14
|
+
/** Whether the map's picture comes before the outline. Default: true. */
|
|
15
|
+
picture?: boolean;
|
|
16
|
+
/** What the picture shows: `focus`, a node with its orbit, or `all`, the whole map. Default: the map's `view`, or `focus`. */
|
|
17
|
+
viewMode?: ViewMode;
|
|
18
|
+
/** The node in the middle of the picture in focus mode, by id. Default: the root. */
|
|
19
|
+
focus?: string;
|
|
20
|
+
/**
|
|
21
|
+
* The map's theme: a theme name or `{ preset, tokens }`. Default: the
|
|
22
|
+
* document's. Paper is light, so a dark theme prints as its light
|
|
23
|
+
* counterpart (see `printTheme`), and nothing prints a background.
|
|
24
|
+
*/
|
|
25
|
+
theme?: OrbitThemePreset | (string & {}) | OrbitRendererTheme;
|
|
26
|
+
/** The map's colors: the root's, then one per top-level branch. Default: the document's, or the theme's. */
|
|
27
|
+
palette?: string[];
|
|
28
|
+
/** The language of the few words the layout has: a BCP 47 tag. Default: English. */
|
|
29
|
+
language?: string;
|
|
30
|
+
/** Words to change, over the language's. */
|
|
31
|
+
strings?: Partial<OrbitStrings>;
|
|
32
|
+
/** Resolves relative picture, video and link URLs. Default: the document's `baseUrl`. */
|
|
33
|
+
baseUrl?: string;
|
|
34
|
+
/** Node types by name, before the registered ones: their icons, colors, labels and details. */
|
|
35
|
+
nodeTypes?: Record<string, OrbitNodeType>;
|
|
36
|
+
/** Status words and how they look, before the registered ones. */
|
|
37
|
+
statuses?: Record<string, OrbitStatusStyle>;
|
|
38
|
+
/** The type a node that names none is laid out as (see `RendererOptions.nodeTypeFor`). */
|
|
39
|
+
nodeTypeFor?: (node: OrbitNode) => string | undefined;
|
|
40
|
+
/** Prefix for the picture's SVG ids; give each layout in one page its own. Default: `orbit-print`. */
|
|
41
|
+
idPrefix?: string;
|
|
42
|
+
}
|
|
43
|
+
/** The light theme each dark built-in theme prints as. Light themes print as themselves. */
|
|
44
|
+
export declare const PRINT_THEMES: Readonly<Partial<Record<OrbitThemePreset, OrbitThemeName>>>;
|
|
45
|
+
/**
|
|
46
|
+
* The theme a map prints in: the map's own when it's light, otherwise its
|
|
47
|
+
* light counterpart (`PRINT_THEMES`), always without a background. A dark
|
|
48
|
+
* theme of your own keeps only its colors (`color-root` to `color-7`).
|
|
49
|
+
*/
|
|
50
|
+
export declare const printTheme: (theme: string | OrbitRendererTheme | undefined) => OrbitRendererTheme;
|
|
51
|
+
/**
|
|
52
|
+
* Lays a map out for print in `container`, replacing what it held, and
|
|
53
|
+
* returns the layout: the title, the map as a picture that fits the page,
|
|
54
|
+
* then every idea in reading order, nested by depth, with its icon, status,
|
|
55
|
+
* priority, tags, link (its address printed), note, picture and video. An
|
|
56
|
+
* idea stays whole across page breaks, and a heading stays with what
|
|
57
|
+
* follows it.
|
|
58
|
+
*
|
|
59
|
+
* It's laid out on screen like any element: hide it there and show it in
|
|
60
|
+
* print, as Orbit's web pages do.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* import { renderPrintLayout } from '@restless-dreams/orbit';
|
|
65
|
+
*
|
|
66
|
+
* renderPrintLayout(document.querySelector('#print'), markdown, { viewMode: 'all' });
|
|
67
|
+
* // #print { display: none } @media print { #print { display: block } #app { display: none } }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare const renderPrintLayout: (container: HTMLElement, input: string | OrbitDocument, options?: OrbitPrintOptions) => HTMLElement;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What node types draw inside their nodes (`render`), in an HTML layer over
|
|
3
|
+
* the map: a 100 × 100 px box per node, moved and scaled with it each frame,
|
|
4
|
+
* created when the node comes on the map and cleaned up when it leaves.
|
|
5
|
+
*/
|
|
6
|
+
import type { Display } from '../engine/display.js';
|
|
7
|
+
import type { Viewport } from '../engine/camera.js';
|
|
8
|
+
import type { MapExtensions } from '../extensions.js';
|
|
9
|
+
/** What node contents need from the map around them. */
|
|
10
|
+
export interface ContentHost {
|
|
11
|
+
extensions(): MapExtensions;
|
|
12
|
+
viewport(): Viewport;
|
|
13
|
+
/** Nodes changed since the last frame. */
|
|
14
|
+
changedIds(): ReadonlySet<string>;
|
|
15
|
+
}
|
|
16
|
+
export declare class ContentPainter {
|
|
17
|
+
private readonly layer;
|
|
18
|
+
private readonly host;
|
|
19
|
+
private readonly contents;
|
|
20
|
+
constructor(layer: HTMLDivElement, host: ContentHost);
|
|
21
|
+
/** Cleans up every node's content. */
|
|
22
|
+
clear(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Draws what node types render inside their nodes: a 100 × 100 px box per
|
|
25
|
+
* node, moved and scaled with it each frame, created when the node comes
|
|
26
|
+
* on the map and cleaned up when it leaves.
|
|
27
|
+
*/
|
|
28
|
+
paint(display: Display): void;
|
|
29
|
+
private remove;
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** The page around a map: its elements, events, focus and scrolling, as the renderer reads them. */
|
|
2
|
+
import { OrbitWords } from '../languages.js';
|
|
3
|
+
export declare const reportListenerError: (error: unknown) => void;
|
|
4
|
+
export declare const createEmptyState: (words: OrbitWords) => HTMLDivElement;
|
|
5
|
+
/** The empty map's message and hint, in `words`' language. */
|
|
6
|
+
export declare const fillEmptyState: (empty: HTMLDivElement, words: OrbitWords) => void;
|
|
7
|
+
/** The + in arrow-key order around the orbit. */
|
|
8
|
+
export declare const SLOT_STOP = "\0slot";
|
|
9
|
+
export declare const isAddSlot: (target: EventTarget | null) => boolean;
|
|
10
|
+
export declare const nodeIdFrom: (target: EventTarget | null) => string | null;
|
|
11
|
+
export declare const isFocusVisible: (target: EventTarget | null) => boolean;
|
|
12
|
+
export declare const isApplePlatform: () => boolean;
|
|
13
|
+
/** Whether the document, or any element around `element`, can scroll. */
|
|
14
|
+
export declare const scrollsAround: (element: Element) => boolean;
|
|
15
|
+
export declare const parentAcrossShadow: (element: Element) => Element | null;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Families: the renderer draws nodes in groups of siblings, and a group whose
|
|
3
|
+
* members come or go together in a flight (one `Cluster`) moves as one, with
|
|
4
|
+
* one transform per frame instead of one per node.
|
|
5
|
+
*/
|
|
6
|
+
import type { Cluster, DisplayNode } from '../engine/display.js';
|
|
7
|
+
import { NodeView } from '../engine/views.js';
|
|
8
|
+
/**
|
|
9
|
+
* Children of one parent, drawn in one group in the layer of their role. In
|
|
10
|
+
* a flight, the members of a family often come or go together, growing out
|
|
11
|
+
* of their parent or shrinking into it, and then the group moves instead of
|
|
12
|
+
* each of them: one transform per frame instead of hundreds.
|
|
13
|
+
*/
|
|
14
|
+
export interface Family {
|
|
15
|
+
group: SVGGElement;
|
|
16
|
+
layer: 'sun' | 'moon' | 'node';
|
|
17
|
+
parentId: string;
|
|
18
|
+
transform: string;
|
|
19
|
+
opacity: string;
|
|
20
|
+
hidden: boolean;
|
|
21
|
+
/** This frame's members, and the motion they all share (null if they don't), once worked out. */
|
|
22
|
+
members: FamilyMember[];
|
|
23
|
+
motion?: Cluster | null;
|
|
24
|
+
}
|
|
25
|
+
export interface FamilyMember {
|
|
26
|
+
entry: DisplayNode;
|
|
27
|
+
view: NodeView;
|
|
28
|
+
family: Family;
|
|
29
|
+
}
|
|
30
|
+
export declare const sameMotion: (first: Cluster, second: Cluster) => boolean;
|
|
31
|
+
/** The motion all of a family's members share this frame, or null when they move each on their own. */
|
|
32
|
+
export declare const familyMotion: (family: Family) => Cluster | null;
|
|
33
|
+
/** A cluster too faint or too small to draw. */
|
|
34
|
+
export declare const clusterHidden: (cluster: Cluster) => boolean;
|
|
35
|
+
export declare const moveFamily: (family: Family, motion: Cluster | null) => void;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Names and "+N" counts, in the HTML layer over the map. Each frame's names
|
|
3
|
+
* are planned for its display (see `planLabels`), shown a share at a time on
|
|
4
|
+
* an animated map, and ride along as one layer while only the camera moves.
|
|
5
|
+
*/
|
|
6
|
+
import type { LabelFonts } from '../engine/text-measure.js';
|
|
7
|
+
import type { Viewport } from '../engine/camera.js';
|
|
8
|
+
import type { Display, DisplayNode } from '../engine/display.js';
|
|
9
|
+
import type { Scene } from '../engine/scene.js';
|
|
10
|
+
import type { MapExtensions } from '../extensions.js';
|
|
11
|
+
import { type LabelPlacement, type NodeView } from '../engine/views.js';
|
|
12
|
+
/** What the names need from the map around them. */
|
|
13
|
+
export interface LabelHost {
|
|
14
|
+
extensions(): MapExtensions;
|
|
15
|
+
viewport(): Viewport;
|
|
16
|
+
/** The scene on screen, or null during a flight: names keep their order for a scene. */
|
|
17
|
+
restingScene(): Scene | null;
|
|
18
|
+
inFlight(): boolean;
|
|
19
|
+
/** Whether only the camera moves: a camera flight, a wheel zoom, a glide or a drag. */
|
|
20
|
+
cameraMoving(): boolean;
|
|
21
|
+
/** Nodes changed since the last frame. */
|
|
22
|
+
changedIds(): ReadonlySet<string>;
|
|
23
|
+
/** The node whose text is being typed, which shows the field instead of its name. */
|
|
24
|
+
editedId(): string | null;
|
|
25
|
+
animationsEnabled(): boolean;
|
|
26
|
+
requestPaint(): void;
|
|
27
|
+
nodeView(id: string): NodeView | undefined;
|
|
28
|
+
themeTokens(): Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
export declare class LabelPainter {
|
|
31
|
+
private readonly layer;
|
|
32
|
+
private readonly fonts;
|
|
33
|
+
private readonly host;
|
|
34
|
+
private readonly labels;
|
|
35
|
+
private readonly counts;
|
|
36
|
+
/**
|
|
37
|
+
* Nodes in the order their labels are placed, for one display, and their
|
|
38
|
+
* ids for a scene at rest: the order holds while the orbit spins, only the
|
|
39
|
+
* entries are new each frame.
|
|
40
|
+
*/
|
|
41
|
+
private labelOrder;
|
|
42
|
+
/** The camera labels and counts were last placed for, and the nodes they were placed for. */
|
|
43
|
+
private placed;
|
|
44
|
+
/** Names planned to show that wait for a later frame (see `LABELS_SHOWN_PER_FRAME`), placed for `placed`'s camera, and whether the map moved then. */
|
|
45
|
+
private waiting;
|
|
46
|
+
private layerTransform;
|
|
47
|
+
private readonly lightText;
|
|
48
|
+
/** The theme's label colors, resolved when first needed after each theme change. */
|
|
49
|
+
private textColors;
|
|
50
|
+
constructor(layer: HTMLDivElement, fonts: LabelFonts, host: LabelHost);
|
|
51
|
+
/** Places the names and counts for this frame's display, or lets them ride along with the camera. */
|
|
52
|
+
paint(display: Display): void;
|
|
53
|
+
/** Where the node's name is drawn now. */
|
|
54
|
+
placementOf(id: string): LabelPlacement | undefined;
|
|
55
|
+
/** Forgets which nodes' names are light (their colors may have changed). */
|
|
56
|
+
forgetLightText(): void;
|
|
57
|
+
/** Forgets the theme's text colors and which names are light (the theme changed). */
|
|
58
|
+
forgetTextColors(): void;
|
|
59
|
+
/** Forgets a node that left the map. */
|
|
60
|
+
forgetNode(id: string): void;
|
|
61
|
+
/** Takes every name and count off the map. */
|
|
62
|
+
clear(): void;
|
|
63
|
+
/**
|
|
64
|
+
* While only the camera moves (a pan, a pinch, a zoom, a glide), labels and counts ride along
|
|
65
|
+
* as one layer instead of being placed again on every frame, which for a big view means
|
|
66
|
+
* restyling hundreds of them. They're placed again once the camera rests, or has gone far
|
|
67
|
+
* enough that they'd be too big or too small, or missing for nodes coming into view. Returns
|
|
68
|
+
* the layer's transform from where they were placed, or null to place them now.
|
|
69
|
+
*/
|
|
70
|
+
private ride;
|
|
71
|
+
/** Fits and places every label again, where it is (the fonts changed). */
|
|
72
|
+
refit(): void;
|
|
73
|
+
/** Whether the labels were placed for this very view: the same nodes, the camera where it was, nothing changed. */
|
|
74
|
+
private still;
|
|
75
|
+
private setLayerTransform;
|
|
76
|
+
private paintLabels;
|
|
77
|
+
/** Shows a planned label: its view (made when it has none yet) placed and fitted as planned. */
|
|
78
|
+
private showLabel;
|
|
79
|
+
/**
|
|
80
|
+
* While the labels ride along with the camera, shows the next names
|
|
81
|
+
* waiting to: placed as planned, for the camera the labels were placed
|
|
82
|
+
* at, so they ride along with the rest.
|
|
83
|
+
*/
|
|
84
|
+
private showWaiting;
|
|
85
|
+
/** Whether the node shows a picture or its type's own content, so its label goes outside. */
|
|
86
|
+
private showsImage;
|
|
87
|
+
/** Whether the theme's light text has more contrast on this node's color than its dark text. Measured once per node and color. */
|
|
88
|
+
usesLightText(entry: DisplayNode): boolean;
|
|
89
|
+
/** The theme's label colors as plain values. */
|
|
90
|
+
private resolveTextColors;
|
|
91
|
+
/** The "+N" of nodes with children that aren't drawn, at their lower right. In the label layer, so they ride along with the labels. */
|
|
92
|
+
private paintCounts;
|
|
93
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The nodes on the map: a view per node, drawn in groups of siblings (see
|
|
3
|
+
* `families.ts`), kept in step with each frame's display. Small flat bodies
|
|
4
|
+
* become specks, an orbit spinning turns the layers its planets and moons are
|
|
5
|
+
* in, and while only the camera moves the nodes hold still.
|
|
6
|
+
*/
|
|
7
|
+
import type { Display } from '../engine/display.js';
|
|
8
|
+
import type { Scene } from '../engine/scene.js';
|
|
9
|
+
import type { MapExtensions } from '../extensions.js';
|
|
10
|
+
import type { OrbitWords } from '../languages.js';
|
|
11
|
+
import { NodeView, type ViewIds } from '../engine/views.js';
|
|
12
|
+
/** What the nodes need from the map around them. */
|
|
13
|
+
export interface NodeHost {
|
|
14
|
+
extensions(): MapExtensions;
|
|
15
|
+
words(): OrbitWords;
|
|
16
|
+
baseUrl(): string | undefined;
|
|
17
|
+
/** The scene on screen (the one a flight leaves, until it lands). */
|
|
18
|
+
scene(): Scene | null;
|
|
19
|
+
inFlight(): boolean;
|
|
20
|
+
/** Whether the orbit is at rest: not dragged, coasting or settling. */
|
|
21
|
+
spinResting(): boolean;
|
|
22
|
+
/** Whether the slow drift is running. */
|
|
23
|
+
driftRunning(): boolean;
|
|
24
|
+
/** The node whose text is being typed, if any. */
|
|
25
|
+
editedId(): string | null;
|
|
26
|
+
/** The node lifted to be dragged, the bodies carried under the press (null when nothing is), and the node it would drop into. */
|
|
27
|
+
drag(): {
|
|
28
|
+
liftedId: string | null;
|
|
29
|
+
carried: Set<string> | null;
|
|
30
|
+
targetId: string | null;
|
|
31
|
+
};
|
|
32
|
+
/** Nodes changed since the last frame. */
|
|
33
|
+
changedIds(): ReadonlySet<string>;
|
|
34
|
+
requestPaint(): void;
|
|
35
|
+
/** A node's view came on the map: the map's tab stops need placing again. */
|
|
36
|
+
tabStopsChanged(): void;
|
|
37
|
+
/** A node's view left the map. */
|
|
38
|
+
viewRemoved(id: string): void;
|
|
39
|
+
}
|
|
40
|
+
/** The layers nodes are drawn in. */
|
|
41
|
+
export interface NodeLayers {
|
|
42
|
+
moons: SVGGElement;
|
|
43
|
+
nodes: SVGGElement;
|
|
44
|
+
suns: SVGGElement;
|
|
45
|
+
carried: SVGGElement;
|
|
46
|
+
}
|
|
47
|
+
export declare class NodePainter {
|
|
48
|
+
private readonly root;
|
|
49
|
+
private readonly definitions;
|
|
50
|
+
private readonly ids;
|
|
51
|
+
private readonly layers;
|
|
52
|
+
private readonly host;
|
|
53
|
+
/** The orbit's turn as last written to the layers of its planets and moons (see `paintTurn`). */
|
|
54
|
+
private turnTransform;
|
|
55
|
+
/** The turn the shading of specks is turned back by (see `turnShading`). */
|
|
56
|
+
private speckLighting;
|
|
57
|
+
/** The on-screen radius (px) below which bodies were last drawn as specks (see `speckRadius`). */
|
|
58
|
+
private specksBelow;
|
|
59
|
+
/**
|
|
60
|
+
* The nodes as last painted at rest, with what they were drawn for: while
|
|
61
|
+
* only the camera or the orbit's turn changes, they hold still, all but
|
|
62
|
+
* the bodies turned back upright (see `paintNodes`).
|
|
63
|
+
*/
|
|
64
|
+
private stillNodes;
|
|
65
|
+
private readonly nodeViews;
|
|
66
|
+
/** The family group each node's element is in (see `Family`). */
|
|
67
|
+
private readonly nodeGroups;
|
|
68
|
+
private readonly families;
|
|
69
|
+
/** Counts flights, so each one's arrivals get groups of their own. */
|
|
70
|
+
private flightCount;
|
|
71
|
+
private familyCount;
|
|
72
|
+
/** The lifted node and the drop target last drawn, so a change draws every node again. */
|
|
73
|
+
private dragMarks;
|
|
74
|
+
constructor(root: HTMLDivElement, definitions: SVGDefsElement, ids: ViewIds, layers: NodeLayers, host: NodeHost);
|
|
75
|
+
/** The view drawing a node, if it's on the map. */
|
|
76
|
+
view(id: string): NodeView | undefined;
|
|
77
|
+
/** Every node's view, by id. */
|
|
78
|
+
entries(): IterableIterator<[string, NodeView]>;
|
|
79
|
+
/** A new flight starts: the ideas it brings in get families of their own. */
|
|
80
|
+
startFlight(): void;
|
|
81
|
+
/** Takes a node's view off the map. */
|
|
82
|
+
removeView(id: string): void;
|
|
83
|
+
/** Takes every node off the map. */
|
|
84
|
+
clear(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Turns the layers of the planets and moons with the orbit (see
|
|
87
|
+
* `OrbitTurn`). Returns the turn (degrees) its bodies are drawn in, or
|
|
88
|
+
* undefined when each is drawn where it is.
|
|
89
|
+
*/
|
|
90
|
+
paintTurn(display: Display): number | undefined;
|
|
91
|
+
paintNodes(display: Display, turn: number | undefined): void;
|
|
92
|
+
/**
|
|
93
|
+
* The on-screen radius (px) below which flat bodies are specks, for this
|
|
94
|
+
* screen's pixels; the stylesheet sizes specks' rims from it.
|
|
95
|
+
*/
|
|
96
|
+
private speckRadius;
|
|
97
|
+
/**
|
|
98
|
+
* A family whose members don't all move alike in this flight (some travel
|
|
99
|
+
* on, the rest leave) splits in two, the fewer of them moving to a group of
|
|
100
|
+
* their own, so each part moves as one.
|
|
101
|
+
*/
|
|
102
|
+
private splitIfMixed;
|
|
103
|
+
/**
|
|
104
|
+
* The group a node is drawn in: its family's, in the layer of its role. A
|
|
105
|
+
* node stays in its group while its parent and role do, so nothing moves
|
|
106
|
+
* between groups when a flight lands; the ideas a flight brings in get a
|
|
107
|
+
* group of their own, so they can move as one while their siblings travel.
|
|
108
|
+
*/
|
|
109
|
+
private placeInFamily;
|
|
110
|
+
/** A new family's group; one that starts hidden (newcomers yet to appear) is hidden before it joins the map, so its members aren't styled until they show. */
|
|
111
|
+
private createFamily;
|
|
112
|
+
private moveIntoFamily;
|
|
113
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The renderer's options: the caller's merged over the document's over the
|
|
3
|
+
* defaults, and the values Orbit works out from them (insets, spin settings).
|
|
4
|
+
*/
|
|
5
|
+
import type { Insets } from '../engine/camera.js';
|
|
6
|
+
import { type SpinSettings } from '../engine/spin.js';
|
|
7
|
+
import type { OrbitInsets, OrbitSpinOptions, RendererOptions } from '../types.js';
|
|
8
|
+
export type ResolvedRendererOptions = RendererOptions & Required<Pick<RendererOptions, 'viewMode' | 'showRings' | 'interactive' | 'orbitAnimation' | 'orbitSpeed' | 'showControls'>>;
|
|
9
|
+
export declare const spinSettings: (options: OrbitSpinOptions | undefined) => SpinSettings;
|
|
10
|
+
export declare const mergeRendererOptions: (base: RendererOptions, overrides: RendererOptions) => ResolvedRendererOptions;
|
|
11
|
+
/** The room the page's controls take at the map's edges, as numbers of px (none for anything else). */
|
|
12
|
+
export declare const resolveInsets: (insets: OrbitInsets | undefined) => Insets;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rings around orbits and the lines between nodes in the overview, kept
|
|
3
|
+
* in step with each frame's display: one view each, written only when what it
|
|
4
|
+
* shows changed.
|
|
5
|
+
*/
|
|
6
|
+
import type { Display } from '../engine/display.js';
|
|
7
|
+
/** The layers rings and links are drawn in, below the nodes. */
|
|
8
|
+
export interface RingAndLinkLayers {
|
|
9
|
+
rings: SVGGElement;
|
|
10
|
+
links: SVGGElement;
|
|
11
|
+
}
|
|
12
|
+
export declare class RingsAndLinks {
|
|
13
|
+
private readonly layers;
|
|
14
|
+
private readonly rings;
|
|
15
|
+
private readonly links;
|
|
16
|
+
constructor(layers: RingAndLinkLayers);
|
|
17
|
+
/** Draws the display's rings (unless `showRings` is off) and links. */
|
|
18
|
+
paint(display: Display, showRings: boolean): void;
|
|
19
|
+
/** Takes every ring and link off the map. */
|
|
20
|
+
clear(): void;
|
|
21
|
+
private paintRings;
|
|
22
|
+
private paintLinks;
|
|
23
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Views of a scene the renderer works out: where its orbit starts, its planets
|
|
3
|
+
* in order, what of a display shows, where a view lands inside another, and a
|
|
4
|
+
* flight's display with a new or renamed node in it.
|
|
5
|
+
*/
|
|
6
|
+
import type { Camera, Similarity, Viewport } from '../engine/camera.js';
|
|
7
|
+
import { type Display } from '../engine/display.js';
|
|
8
|
+
import type { Scene, SceneNode } from '../engine/scene.js';
|
|
9
|
+
/** Resizes within this share of the size a view was laid out for keep its layout: no one sees 2% in a node's size. */
|
|
10
|
+
export declare const RELAYOUT_THRESHOLD = 0.02;
|
|
11
|
+
/** A node an edit just added, and where it was typed: its first frame is there. */
|
|
12
|
+
export interface Arrival {
|
|
13
|
+
id: string;
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
radius: number;
|
|
17
|
+
}
|
|
18
|
+
/** Whether `size` is within `RELAYOUT_THRESHOLD` of `laidOut` in both directions. */
|
|
19
|
+
export declare const closeInSize: (size: Viewport, laidOut: Viewport) => boolean;
|
|
20
|
+
/** How far the nearest planet's edge (or the +'s) is from the sun, in world units: the room around the sun. */
|
|
21
|
+
export declare const innerEdges: WeakMap<Scene, number>;
|
|
22
|
+
export declare const innerOrbitEdge: (scene: Scene) => number;
|
|
23
|
+
/** Planets clockwise from the top. */
|
|
24
|
+
export declare const orderedPlanets: (scene: Scene) => SceneNode[];
|
|
25
|
+
export declare const clockwiseFromTop: (angle: number) => number;
|
|
26
|
+
/** Places `target` so its fitted view matches `camera`: the views cross-fade without the camera moving. */
|
|
27
|
+
export declare const overlayPlacement: (target: Scene, camera: Camera) => Similarity;
|
|
28
|
+
/** Drops what has already faded out, so it isn't carried into the next flight. */
|
|
29
|
+
export declare const visiblePart: (display: Display) => Display;
|
|
30
|
+
/** `display` with a node an edit just added already where it was typed, so it stays there as the others make room. */
|
|
31
|
+
export declare const withArrival: (display: Display, arrival: Arrival | null, target: Scene) => Display;
|
|
32
|
+
/** `display` with the nodes an edit gave new ids under the new ones, so they move rather than leave and arrive. */
|
|
33
|
+
export declare const renameNodes: (display: Display, renamed: ReadonlyMap<string, string>) => Display;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Maps as the renderer takes them: documents or trees, compared, checked and carried over between renders. */
|
|
2
|
+
import { OrbitWords } from '../languages.js';
|
|
3
|
+
import type { OrbitDocument, OrbitNode } from '../types.js';
|
|
4
|
+
import type { EditorText } from '../ui/inline-editor.js';
|
|
5
|
+
/** The field's text for a new idea under `parent`. */
|
|
6
|
+
export declare const newIdeaText: (parent: OrbitNode, words: OrbitWords) => EditorText;
|
|
7
|
+
export declare const sameValues: (first: unknown, second: unknown) => boolean;
|
|
8
|
+
/** Says how to call an editing method that got something other than an object. */
|
|
9
|
+
export declare const expectObject: (method: string, value: unknown, example: string) => void;
|
|
10
|
+
/** Whether two trees hold the same map: the same nodes, ids and attributes, wherever their source wrote them. */
|
|
11
|
+
export declare const sameTree: (first: OrbitNode, second: OrbitNode) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Moves where a fresh parse of the same map came from onto the tree as drawn:
|
|
14
|
+
* each node's own place, and the source itself (keyed by node, see
|
|
15
|
+
* `documentSource`), so saving writes the new text against the nodes the map
|
|
16
|
+
* already shows.
|
|
17
|
+
*/
|
|
18
|
+
export declare const transplantSource: (kept: OrbitNode, fresh: OrbitNode) => void;
|
|
19
|
+
/** An object's entries that have a value. */
|
|
20
|
+
export declare const definedEntries: (value: object) => Record<string, unknown>;
|
|
21
|
+
export declare const isOrbitDocument: (input: OrbitNode | OrbitDocument) => input is OrbitDocument;
|
|
22
|
+
export declare const isEmptyTree: (tree: OrbitNode) => boolean;
|