@restless-dreams/orbit 0.0.0-stage → 0.1.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.
Files changed (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -2
  3. package/dist/bin/orbit.js +8907 -0
  4. package/dist/bin/orbit.js.map +48 -0
  5. package/dist/chunk-0gwh723s.js +408 -0
  6. package/dist/chunk-0gwh723s.js.map +10 -0
  7. package/dist/chunk-7n00wx0t.js +82 -0
  8. package/dist/chunk-7n00wx0t.js.map +10 -0
  9. package/dist/chunk-mtrnm0yc.js +16993 -0
  10. package/dist/chunk-mtrnm0yc.js.map +63 -0
  11. package/dist/core/auto-render.d.ts +85 -0
  12. package/dist/core/browser.d.ts +23 -0
  13. package/dist/core/create.d.ts +23 -0
  14. package/dist/core/diagnostics.d.ts +40 -0
  15. package/dist/core/dispatch.d.ts +23 -0
  16. package/dist/core/document-options.d.ts +18 -0
  17. package/dist/core/document-source.d.ts +128 -0
  18. package/dist/core/editing.d.ts +63 -0
  19. package/dist/core/engine/animation-clock.d.ts +40 -0
  20. package/dist/core/engine/camera.d.ts +70 -0
  21. package/dist/core/engine/colors.d.ts +51 -0
  22. package/dist/core/engine/display.d.ts +125 -0
  23. package/dist/core/engine/export.d.ts +32 -0
  24. package/dist/core/engine/glide.d.ts +34 -0
  25. package/dist/core/engine/labels.d.ts +106 -0
  26. package/dist/core/engine/node-drag.d.ts +49 -0
  27. package/dist/core/engine/scene.d.ts +159 -0
  28. package/dist/core/engine/spin.d.ts +62 -0
  29. package/dist/core/engine/surface-pattern.d.ts +20 -0
  30. package/dist/core/engine/text-measure.d.ts +116 -0
  31. package/dist/core/engine/views.d.ts +353 -0
  32. package/dist/core/extensions.d.ts +155 -0
  33. package/dist/core/format-upgrades.d.ts +33 -0
  34. package/dist/core/index.d.ts +36 -0
  35. package/dist/core/input-controller.d.ts +109 -0
  36. package/dist/core/languages.d.ts +199 -0
  37. package/dist/core/layout.d.ts +61 -0
  38. package/dist/core/map-tools/definitions.d.ts +71 -0
  39. package/dist/core/map-tools/input.d.ts +62 -0
  40. package/dist/core/map-tools/reading.d.ts +40 -0
  41. package/dist/core/map-tools/tools.d.ts +51 -0
  42. package/dist/core/markdown-writing.d.ts +87 -0
  43. package/dist/core/material.d.ts +25 -0
  44. package/dist/core/media.d.ts +42 -0
  45. package/dist/core/node-attributes.d.ts +31 -0
  46. package/dist/core/node-links.d.ts +25 -0
  47. package/dist/core/parser-markdown.d.ts +42 -0
  48. package/dist/core/parser-yaml.d.ts +8 -0
  49. package/dist/core/render-to-svg.d.ts +57 -0
  50. package/dist/core/serializer-markdown.d.ts +18 -0
  51. package/dist/core/serializer-yaml.d.ts +2 -0
  52. package/dist/core/source-patch.d.ts +24 -0
  53. package/dist/core/source.d.ts +27 -0
  54. package/dist/core/styles.d.ts +6 -0
  55. package/dist/core/suggest.d.ts +8 -0
  56. package/dist/core/svg-renderer.d.ts +729 -0
  57. package/dist/core/text-layout.d.ts +54 -0
  58. package/dist/core/themes.d.ts +62 -0
  59. package/dist/core/types.d.ts +463 -0
  60. package/dist/core/ui/actions.d.ts +75 -0
  61. package/dist/core/ui/controls.d.ts +61 -0
  62. package/dist/core/ui/detail-sheet.d.ts +88 -0
  63. package/dist/core/ui/frames.d.ts +11 -0
  64. package/dist/core/ui/icons.d.ts +14 -0
  65. package/dist/core/ui/inline-editor.d.ts +79 -0
  66. package/dist/core/ui/media-players.d.ts +65 -0
  67. package/dist/core/ui/media-viewer.d.ts +169 -0
  68. package/dist/core/ui/media-zoom.d.ts +51 -0
  69. package/dist/core/ui/note-markdown.d.ts +19 -0
  70. package/dist/core/ui/outline.d.ts +44 -0
  71. package/dist/core/url-guard.d.ts +40 -0
  72. package/dist/core/utils.d.ts +23 -0
  73. package/dist/core/web-page/page.d.ts +58 -0
  74. package/dist/core/web-page/runtime.d.ts +13 -0
  75. package/dist/core/web-page/start.d.ts +1 -0
  76. package/dist/core/yaml-mini.d.ts +54 -0
  77. package/dist/index.d.ts +1 -0
  78. package/dist/index.js +1448 -0
  79. package/dist/index.js.map +17 -0
  80. package/dist/marked/index.d.ts +31 -0
  81. package/dist/marked/index.js +110 -0
  82. package/dist/marked/index.js.map +10 -0
  83. package/dist/react/index.d.ts +55 -0
  84. package/dist/react/index.js +352 -0
  85. package/dist/react/index.js.map +1 -0
  86. package/dist/web-page.d.ts +2 -0
  87. package/dist/web-page.js +130 -0
  88. package/llms-full.txt +2585 -0
  89. package/llms.txt +35 -0
  90. package/package.json +118 -4
  91. package/skills/orbit/SKILL.md +140 -0
  92. package/skills/orbit/references/editing.md +194 -0
  93. package/skills/orbit/references/extending.md +247 -0
  94. package/skills/orbit/references/format.md +303 -0
  95. package/skills/orbit/references/guide.md +522 -0
  96. package/skills/orbit/references/languages.md +159 -0
  97. package/skills/orbit/references/map-tools.md +188 -0
  98. package/skills/orbit/references/media.md +160 -0
  99. package/skills/orbit/references/recipes.md +227 -0
  100. package/skills/orbit/references/theming.md +184 -0
@@ -0,0 +1,729 @@
1
+ /**
2
+ * OrbitSVGRenderer draws a map into a container element and makes it
3
+ * explorable.
4
+ *
5
+ * Each view (a node in focus, or the overview) is a scene in world
6
+ * coordinates (engine/scene.ts), seen through one camera. Moving between
7
+ * views flies the camera along a smooth zoom path while the nodes both views
8
+ * share move into place; when the flight lands, the world is re-rooted on
9
+ * the new scene. In focus mode the orbit spins with momentum when flicked,
10
+ * zooming far enough into a planet enters it, and zooming out leaves.
11
+ *
12
+ * Nodes, rings and links are SVG under one camera transform. Labels, badges,
13
+ * controls and the detail sheet are HTML on top, so text stays sharp and
14
+ * readable at any zoom.
15
+ */
16
+ import type { OrbitDocument, OrbitEventMap, OrbitEventName, OrbitMediaOptions, OrbitNode, OrbitNewNode, OrbitNodeInput, RendererOptions, ViewMode } from './types.js';
17
+ export declare class OrbitSVGRenderer {
18
+ private static registry;
19
+ private static instanceCounter;
20
+ /** Destroys the renderer drawing into `target`, if there is one. Returns whether there was. */
21
+ static unmount(target: HTMLElement): boolean;
22
+ private readonly container;
23
+ private readonly root;
24
+ private readonly svg;
25
+ private readonly world;
26
+ private readonly definitions;
27
+ /** The camera as last written to the world: a spin repaints every frame without moving it. */
28
+ private worldTransform;
29
+ /** The orbit's turn as last written to the layers of its planets and moons (see `paintTurn`). */
30
+ private turnTransform;
31
+ /** The theme the shading was last placed for (see `placeShading`). */
32
+ private shadingTheme;
33
+ /** The turn the shading of specks is turned back by (see `turnShading`). */
34
+ private speckLighting;
35
+ /** The on-screen radius (px) below which bodies were last drawn as specks (see `speckRadius`). */
36
+ private specksBelow;
37
+ /**
38
+ * The nodes as last painted at rest, with what they were drawn for: while
39
+ * only the camera or the orbit's turn changes, they hold still, all but
40
+ * the bodies turned back upright (see `paintNodes`).
41
+ */
42
+ private stillNodes;
43
+ private readonly layers;
44
+ private readonly labelLayer;
45
+ /** The fonts the labels are drawn with, which names are measured and fitted in. */
46
+ private readonly labelFonts;
47
+ /** Stops listening for fonts that finish loading. */
48
+ private readonly stopWatchingFonts;
49
+ /** What node types draw inside their nodes, between the nodes and the labels. */
50
+ private readonly contentLayer;
51
+ private readonly contents;
52
+ /** This map's node types, actions and status words, then the registered ones. */
53
+ private extensions;
54
+ /** The words the map speaks, in its language, and the language and words they were made for. */
55
+ private words;
56
+ private requestedLanguage;
57
+ private requestedStrings;
58
+ private readonly overlayLayer;
59
+ private readonly emptyState;
60
+ private readonly actionBar;
61
+ private readonly tooltip;
62
+ private readonly controls;
63
+ private readonly outline;
64
+ private readonly sheet;
65
+ private readonly viewer;
66
+ private readonly input;
67
+ private readonly clock;
68
+ private readonly spinPhysics;
69
+ private readonly spinTracker;
70
+ private readonly panTracker;
71
+ private readonly glide;
72
+ private readonly ids;
73
+ private resizeObserver;
74
+ private visibilityObserver;
75
+ /** Every node's color, from `getNodeColor`'s first call until the map or its options change. */
76
+ private nodeColors;
77
+ private taskTokens;
78
+ /** Whether any of the map is on screen; off screen, the drift rests. */
79
+ private onScreen;
80
+ /** The reduced-motion query, asked once: the drift checks it every frame. */
81
+ private reducedMotionQuery;
82
+ private options;
83
+ /** Options from the caller (constructor and setOptions); they win over the document's. */
84
+ private userOptions;
85
+ /** Options from the rendered document's frontmatter or YAML keys. */
86
+ private documentOptions;
87
+ /** Those options as the document wrote them, for `getDocument()` and `toMarkdown()`. */
88
+ private sourceOptions;
89
+ /** The document's keys Orbit doesn't read, written back on save. */
90
+ private sourceExtra;
91
+ private themeProperties;
92
+ private tree;
93
+ private focusPath;
94
+ private viewMode;
95
+ private viewport;
96
+ /** The size the views were last laid out for: resizes close to it keep the layout. */
97
+ private layoutSize;
98
+ /** The map was resized while flying: lay the view out again once it lands. */
99
+ private relayoutOnArrival;
100
+ /** The page's controls moved while flying (see `insets`): fit the view again once it lands. */
101
+ private refitOnArrival;
102
+ private scene;
103
+ private camera;
104
+ private transition;
105
+ /** Where a flight between two branches goes after passing through their common ancestor. */
106
+ private nextScene;
107
+ /** The camera a flight ends on, when it isn't the scene's fitted view. */
108
+ private landingCamera;
109
+ private cameraFlight;
110
+ private wheelZoom;
111
+ private display;
112
+ private restingDisplay;
113
+ /**
114
+ * Nodes in the order their labels are placed, for one display, and their
115
+ * ids for a scene at rest: the order holds while the orbit spins, only the
116
+ * entries are new each frame.
117
+ */
118
+ private labelOrder;
119
+ private readonly nodeViews;
120
+ /** The family group each node's element is in (see `Family`). */
121
+ private readonly nodeGroups;
122
+ private readonly families;
123
+ /** Counts flights, so each one's arrivals get groups of their own. */
124
+ private flightCount;
125
+ private familyCount;
126
+ private readonly labels;
127
+ private readonly ringViews;
128
+ /** Each view keeps what it last wrote, so the elements of a map that didn't move aren't touched. */
129
+ private readonly linkViews;
130
+ private readonly counts;
131
+ /** The camera labels and counts were last placed for, and the nodes they were placed for. */
132
+ private labelsPlaced;
133
+ /** Names planned to show that wait for a later frame (see `LABELS_SHOWN_PER_FRAME`), placed for `labelsPlaced`'s camera, and whether the map moved then. */
134
+ private waitingLabels;
135
+ private labelLayerTransform;
136
+ private readonly lightText;
137
+ /** The theme's label colors, resolved when first needed after each theme change. */
138
+ private textColors;
139
+ /** The node that holds the map's single tab stop. */
140
+ private activeId;
141
+ private tabStopsChanged;
142
+ private hoveredId;
143
+ private keyboardFocusId;
144
+ private topPlanetId;
145
+ private userSpun;
146
+ /** Put keyboard focus back on the map when a flight lands (its node may have left). */
147
+ private returnFocusToMap;
148
+ private dragging;
149
+ /** The last node a long press, right click or context menu key reported, and whether someone took it. */
150
+ private lastContext;
151
+ /** Nodes whose ids an edit changed, old to new, so the next redraw moves them rather than replacing them. */
152
+ private renamedIds;
153
+ /** Nodes an edit changed in place (the node itself, or a parent's children): the next paint draws them again. */
154
+ private readonly changedIds;
155
+ /** The + in the orbit, and the field for typing on the map. */
156
+ private readonly addSlotView;
157
+ /** The place held in the orbit for a planet being dragged: like the +, but nothing to press. */
158
+ private readonly heldPlaceView;
159
+ private readonly editor;
160
+ private editing;
161
+ private arrival;
162
+ /** A node held up to be dragged somewhere else. */
163
+ private nodeDrag;
164
+ /** The frame a dragged node was let go in: the flight that follows starts from it. */
165
+ private dropFrom;
166
+ /** A long press no one took a menu for, on a node it lifts: let go without moving, the node is typed into. */
167
+ private editOnLift;
168
+ /** The lifted node and the drop target last drawn, so a change draws every node again. */
169
+ private dragMarks;
170
+ private ambientRunning;
171
+ /** Drift not painted yet, in degrees: less than a `DRIFT_STEP`. */
172
+ private pendingDrift;
173
+ /** How far the current view's spinning bodies reach from the sun (world units). */
174
+ private spinReach;
175
+ private pageScrollCheck;
176
+ private readonly listeners;
177
+ private destroyed;
178
+ private warnedFlat;
179
+ private warnedTheme;
180
+ constructor(container: HTMLElement, options?: RendererOptions);
181
+ /**
182
+ * Draws a map: markdown or YAML source (parsed forgivingly), a parsed
183
+ * document, or a node tree. A document's frontmatter options apply, though
184
+ * options given to the renderer win. Drawing a new version of the same map
185
+ * keeps the reader's place: the focused node, or its closest ancestor that
186
+ * still exists.
187
+ */
188
+ render(input: string | OrbitNode | OrbitDocument): void;
189
+ setOptions(options: RendererOptions): void;
190
+ /**
191
+ * Listens for a map event; returns a function that stops listening. The
192
+ * same events are dispatched on the container as `orbit-<name>` DOM events.
193
+ */
194
+ on<Name extends OrbitEventName>(name: Name, listener: (detail: OrbitEventMap[Name]) => void): () => void;
195
+ getSVGElement(): SVGSVGElement;
196
+ /**
197
+ * The current view as a standalone SVG document: colors resolved, labels
198
+ * as SVG text, nothing that depends on the page's stylesheet.
199
+ */
200
+ toSVGString(): string;
201
+ getViewMode(): ViewMode;
202
+ /** Switches between focus mode and the overview (fires onViewModeChange). */
203
+ setViewMode(mode: ViewMode): void;
204
+ /** Ids from the root to the focused node. */
205
+ getFocusPath(): string[];
206
+ /** The node focused in focus mode (the sun). */
207
+ getFocusedNode(): OrbitNode | null;
208
+ /**
209
+ * Focuses a node by id and flies to it (fires onFocusChange). In the
210
+ * overview, the camera moves to the node instead. Returns false when the
211
+ * id isn't in the map.
212
+ */
213
+ focusNode(id: string): boolean;
214
+ /**
215
+ * Flies to a node by id, switching to focus mode if needed (fires
216
+ * onFocusChange and onViewModeChange). Returns false when there's no such node.
217
+ */
218
+ flyTo(id: string): boolean;
219
+ /** Flies out to the overview of the whole map (fires onViewModeChange). */
220
+ overview(): void;
221
+ /** Zooms by `factor` around the middle of the map (above 1 zooms in). */
222
+ zoomBy(factor: number): void;
223
+ /** Returns the camera to the fitted view. */
224
+ fit(): void;
225
+ /**
226
+ * Flicks the orbit at `speed` degrees per second; negative speeds turn it
227
+ * counterclockwise. Only in focus mode.
228
+ */
229
+ spin(speed: number): void;
230
+ /**
231
+ * Shows a node's picture or video in the media viewer, over the whole
232
+ * window, opening it if it's closed: to show a picture big, or play a
233
+ * video, from your own controls. A node with both shows its picture
234
+ * unless `kind` is `video`, and a video starts playing unless `autoplay`
235
+ * is `false`, from the start or `startAt` seconds in. It opens whatever
236
+ * `mediaViewer`, `showDetailSheet` and `interactive` say; on a map that
237
+ * isn't interactive, the viewer takes no input of its own and has no
238
+ * buttons. Fires `media-open`. Returns false when the map has no such
239
+ * node, or the node no such picture or video.
240
+ */
241
+ openMedia(nodeId: string, options?: OrbitMediaOptions): boolean;
242
+ /** Closes the media viewer, if it's open (fires `media-close`). */
243
+ closeMedia(): void;
244
+ /**
245
+ * Plays the video in the media viewer. Returns false when it shows no
246
+ * video, or one on a site Orbit has no player for. Files, YouTube and
247
+ * Vimeo play.
248
+ */
249
+ playMedia(): boolean;
250
+ /** Pauses the video in the media viewer. Returns false when it shows no video it can pause. */
251
+ pauseMedia(): boolean;
252
+ /** Moves the video in the media viewer to `seconds` from its start. Returns false when it shows no video it can move. */
253
+ seekMedia(seconds: number): boolean;
254
+ /**
255
+ * Turns on the sound of the video in the media viewer: one a browser
256
+ * started muted, say. Browsers allow sound only once the reader has
257
+ * interacted with the page, so call it from a press, such as a "Tap for
258
+ * sound" button's. Returns false when it shows no video it can drive.
259
+ */
260
+ unmuteMedia(): boolean;
261
+ /**
262
+ * The color a node is drawn with: its own, its type's, or its branch's
263
+ * from the palette and theme. For lists and legends next to the map. A hex
264
+ * color, or the CSS color as written when Orbit can't read it; `null` when
265
+ * the id isn't in the map.
266
+ */
267
+ getNodeColor(id: string): string | null;
268
+ /**
269
+ * The theme's tokens as the page resolves them, read once per task:
270
+ * reading them asks the browser for every token, and a list next to a big
271
+ * map asks for hundreds of colors at once.
272
+ */
273
+ private tokensForThisTask;
274
+ /**
275
+ * The map as a document: its tree, and the options its source set in
276
+ * frontmatter. Edits change this tree in place.
277
+ */
278
+ getDocument(): OrbitDocument | null;
279
+ /**
280
+ * The map as orbit-md, frontmatter included: what to save after an edit.
281
+ * A map read from markdown comes back as it was written, with only what
282
+ * the edits changed written again, so a file written by hand or by
283
+ * another app keeps its formatting and everything Orbit doesn't read.
284
+ */
285
+ toMarkdown(): string;
286
+ /**
287
+ * Adds a node under `parentId`, at `index` among its children (default:
288
+ * last), with any `children` it lists under it; it flies out of its parent
289
+ * into place. Ids come from the text, as when the map is read from
290
+ * markdown. Fires `edit` once. Returns the new node, or null when there's
291
+ * no such parent.
292
+ */
293
+ addNode(parentId: string, input: OrbitNewNode, index?: number): OrbitNode | null;
294
+ /**
295
+ * Changes a node's text or attributes: `{ text: 'Budget' }`, `{ status:
296
+ * 'done' }`, or `{ color: undefined }` to remove one. New text gives the
297
+ * node a new id when its id came from its text and no link points at it,
298
+ * so the saved map needs no id attribute. Fires `edit`. Returns the
299
+ * node, or null when there's no such node.
300
+ */
301
+ updateNode(id: string, changes: OrbitNodeInput): OrbitNode | null;
302
+ /**
303
+ * Removes a node and everything under it. When the node in focus goes,
304
+ * the nearest node left takes the focus. The root stays. Fires `edit`.
305
+ * Returns the removed node, or null.
306
+ */
307
+ removeNode(id: string): OrbitNode | null;
308
+ /**
309
+ * Moves a node, with everything under it, under `parentId` at `index`
310
+ * among its children (default: last). Fires `edit`. Returns the node,
311
+ * or null when either node is missing, the node is the root, or
312
+ * `parentId` is inside the node.
313
+ */
314
+ moveNode(id: string, parentId: string, index?: number): OrbitNode | null;
315
+ /**
316
+ * Opens a field over a node to type its text where it is: Enter saves,
317
+ * Escape cancels, and leaving the field saves. A moon, or a node out of
318
+ * view, flies into view first. Fires `editor-open`, then `editor-close`.
319
+ * Returns false when there's no such node.
320
+ */
321
+ editNode(id: string): boolean;
322
+ /**
323
+ * Adds an idea by typing it on the map: a field opens in the orbit of
324
+ * `parentId` (default: the node in focus), at `index` among its children
325
+ * (default: after the last), flying there first. Enter adds the idea
326
+ * where it was typed and opens the next one after it; Escape, or Enter
327
+ * with nothing typed, stops. Fires `editor-open`, `edit` for each idea,
328
+ * then `editor-close`. Returns false when there's no such node.
329
+ */
330
+ editNewNode(parentId?: string, index?: number): boolean;
331
+ /** Closes the field for typing on the map, keeping what was typed unless `save` is false. */
332
+ stopEditing(save?: boolean): void;
333
+ destroy(): void;
334
+ /** Draws `tree`, keeping the reader's place in it. */
335
+ private showTree;
336
+ /** Whether `tree`, with the document's `options`, is the map as drawn now, in another object. */
337
+ private isSameMap;
338
+ /**
339
+ * Takes a copy of the map as drawn without drawing it again, so a flight or
340
+ * an edit's animation carries on. The copy proved equal to the drawn tree
341
+ * (see `isSameMap`): the drawn nodes stay, so their views, labels and
342
+ * outline entries carry on too; the copy lends only its places in the source.
343
+ */
344
+ private adoptTree;
345
+ /** Shows an edit, keeping the reader's place, and reports it. */
346
+ private afterEdit;
347
+ /** Adds a node; `arrival`, where a new idea was typed, is where it first shows. */
348
+ private insertNode;
349
+ /** Whether Tab, Shift+Enter and Delete edit the map (see `editingKeys`). */
350
+ private get editingKeys();
351
+ /** Shift+Enter: a new idea beside `id`, right after it. Beside the root, which has no orbit around it, is under it. */
352
+ private addBeside;
353
+ /** Delete: removes `id`, and keyboard focus moves on to the node after it, or before it, or up to its parent. */
354
+ private removeWithKey;
355
+ /**
356
+ * Tab and Shift+Tab in the field (see `editingKeys`). Tab goes on a level
357
+ * down: under the idea just typed, or with nothing typed, under the idea
358
+ * before. Shift+Tab goes on a level up, beside the parent. What was typed
359
+ * is kept first. Returns whether the key was used.
360
+ */
361
+ private tabFromEditor;
362
+ /** Keeps what was typed: new text for a node, or a new idea (and, after Enter, the field moves on to the next). */
363
+ private saveEdit;
364
+ /**
365
+ * Closes the field. `returnFocus` puts keyboard focus back on the node
366
+ * (or the +) when it was in the field; `refresh` moves the + back to its
367
+ * place, unless an edit is about to redraw the map anyway.
368
+ */
369
+ private finishEditing;
370
+ /** Redraws the view when the + should show, move or go. */
371
+ private refreshSlot;
372
+ /** Where the + goes in the focused node's orbit: where a new idea is being typed, else after its children on editable maps. */
373
+ private slotPlace;
374
+ private emitEditor;
375
+ /** Keeps the view's place on a node whose id an edit changed. */
376
+ private renameView;
377
+ /** Defaults, then the document's options, then the caller's. `undefined` means "not set". */
378
+ private resolveOptions;
379
+ private createExtensions;
380
+ /**
381
+ * Speaks the language the options ask for, or else the one the map's
382
+ * element is in now, and writes the map's words again if that changed.
383
+ */
384
+ private syncLanguage;
385
+ /** Applies the current options. With `previous`, also updates the map for what changed. */
386
+ private applyOptionEffects;
387
+ /** Whether the camera shows the view as it's fitted, not zoomed or panned away from it. */
388
+ private isFitted;
389
+ /** The theme object to apply, with a registered theme's name replaced by its tokens. */
390
+ private themeOption;
391
+ private themePreset;
392
+ private applyTheme;
393
+ /** A token as the page resolves it (its CSS can set any), or as the theme sets it while the map isn't on a page. */
394
+ private themeValue;
395
+ /** Concrete theme values for exports: the preset, then the theme object, then the page's CSS. */
396
+ private exportTokens;
397
+ private syncInteractivity;
398
+ private get focusId();
399
+ private get rotation();
400
+ private sceneOptions;
401
+ /**
402
+ * The scene for the current view, or null while there is nothing to draw
403
+ * or no room to draw it. `withSlot: false` leaves out the + (for exports).
404
+ */
405
+ private buildScene;
406
+ /**
407
+ * The focus view of `focusId`. Where the focused node's buttons have no
408
+ * place around the sun, it's fitted to leave room for them under the orbit.
409
+ */
410
+ private focusScene;
411
+ /**
412
+ * The room (px) a focus view needs under its orbit for the focused node's
413
+ * buttons: none where they have a place in the view as it's fitted.
414
+ */
415
+ private roomForActions;
416
+ private showsActions;
417
+ /**
418
+ * Where the focused node's buttons go, or null where every place would
419
+ * cover something: under the sun where its planets leave room at every
420
+ * turn of the orbit, else on its lower rim under its name, else under the
421
+ * orbit (`focusScene` fits views to leave room there).
422
+ */
423
+ private actionsPlace;
424
+ /**
425
+ * How `count` buttons lay out under the orbit with their top `top` px down
426
+ * the map (by default, as low as they go): between the sides of the map
427
+ * that `insets` leave, or short of the zoom buttons where they come down
428
+ * beside them, on more lines if they must.
429
+ */
430
+ private rowsUnderOrbit;
431
+ /**
432
+ * Moves to a view: `nodeId` in focus, or the overview. Fires
433
+ * onFocusChange and onViewModeChange unless `notify` is false.
434
+ */
435
+ private navigate;
436
+ private flyToCurrentView;
437
+ /**
438
+ * Where to put `target` in today's world so the flight has a fixed point:
439
+ * a node both views show stays put while the camera moves.
440
+ */
441
+ private placeTarget;
442
+ private commonAncestorScene;
443
+ private startTransition;
444
+ /** Reduced motion: fade the current view out and the next one in, without moving anything. */
445
+ private startFade;
446
+ private flightDuration;
447
+ private readonly transitionTask;
448
+ private finishTransition;
449
+ /** Jumps to the end of any flight in progress. */
450
+ private completeTransition;
451
+ /** Shows `scene` at rest, fitted. */
452
+ private restOn;
453
+ private afterArrival;
454
+ /**
455
+ * Builds the view again: `enter` animates it in, `morph` moves today's
456
+ * nodes into their new places, `instant` just shows it.
457
+ */
458
+ private rebuild;
459
+ /** Rebuilds the current view in place (new colors, same layout). */
460
+ private refreshScene;
461
+ private currentDisplay;
462
+ /** Stops every camera and orbit motion except a flight between views. */
463
+ private stopMotion;
464
+ private paint;
465
+ private paintRings;
466
+ private paintLinks;
467
+ /**
468
+ * Turns the layers of the planets and moons with the orbit (see
469
+ * `OrbitTurn`). Returns the turn (degrees) its bodies are drawn in, or
470
+ * undefined when each is drawn where it is.
471
+ */
472
+ private paintTurn;
473
+ private paintNodes;
474
+ /**
475
+ * The on-screen radius (px) below which flat bodies are specks, for this
476
+ * screen's pixels; the stylesheet sizes specks' rims from it.
477
+ */
478
+ private speckRadius;
479
+ /**
480
+ * A family whose members don't all move alike in this flight (some travel
481
+ * on, the rest leave) splits in two, the fewer of them moving to a group of
482
+ * their own, so each part moves as one.
483
+ */
484
+ private splitIfMixed;
485
+ /**
486
+ * The group a node is drawn in: its family's, in the layer of its role. A
487
+ * node stays in its group while its parent and role do, so nothing moves
488
+ * between groups when a flight lands; the ideas a flight brings in get a
489
+ * group of their own, so they can move as one while their siblings travel.
490
+ */
491
+ private placeInFamily;
492
+ /** 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. */
493
+ private createFamily;
494
+ private moveIntoFamily;
495
+ /** The node whose text is being typed on the map, if any. */
496
+ private editedId;
497
+ private paintAddSlot;
498
+ /** The place held for a planet being dragged: an empty ring where it's laid out, under the press's way. */
499
+ private paintHeldPlace;
500
+ /** Lays the field for typing over its node, or the +, wherever they are this frame. */
501
+ private placeEditor;
502
+ /**
503
+ * The field's place and size: the label's, inside the node; a node too
504
+ * small to hold it gets a field floating over it at a readable size. Over a
505
+ * node with a "+N" (`hiddenChildren` it doesn't draw), the field rises as
506
+ * it grows, as names do, to keep clear of the count.
507
+ */
508
+ private editorPlacement;
509
+ private removeNodeView;
510
+ /**
511
+ * While only the camera moves (a pan, a pinch, a zoom, a glide), labels and counts ride along
512
+ * as one layer instead of being placed again on every frame, which for a big view means
513
+ * restyling hundreds of them. They're placed again once the camera rests, or has gone far
514
+ * enough that they'd be too big or too small, or missing for nodes coming into view. Returns
515
+ * the layer's transform from where they were placed, or null to place them now.
516
+ */
517
+ private labelRide;
518
+ /** Fits and places every label again, where it is (the fonts changed). */
519
+ private fitLabelsAgain;
520
+ /** Whether the labels were placed for this very view: the same nodes, the camera where it was, nothing changed. */
521
+ private labelsStill;
522
+ private setLabelLayerTransform;
523
+ private paintLabels;
524
+ /** Shows a planned label: its view (made when it has none yet) placed and fitted as planned. */
525
+ private showLabel;
526
+ /**
527
+ * While the labels ride along with the camera, shows the next names
528
+ * waiting to: placed as planned, for the camera the labels were placed
529
+ * at, so they ride along with the rest.
530
+ */
531
+ private showWaitingLabels;
532
+ /** Whether the node shows a picture or its type's own content, so its label goes outside. */
533
+ private showsImage;
534
+ /**
535
+ * Draws what node types render inside their nodes: a 100 × 100 px box per
536
+ * node, moved and scaled with it each frame, created when the node comes
537
+ * on the map and cleaned up when it leaves.
538
+ */
539
+ private paintContents;
540
+ private removeContent;
541
+ /** Whether the theme's light text has more contrast on this node's color than its dark text. Measured once per node and color. */
542
+ private usesLightText;
543
+ /** The theme's label colors as plain values. */
544
+ private resolveTextColors;
545
+ private paintOverlay;
546
+ /** 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. */
547
+ private paintCounts;
548
+ private clearViews;
549
+ /** One tab stop for the whole map (roving tabindex); arrow keys move between nodes. */
550
+ private updateTabStops;
551
+ private focusNodeElement;
552
+ private updateControls;
553
+ /** The outline, and the pictures and videos the viewer steps through, follow the map. */
554
+ private updateOutline;
555
+ private toggleOutline;
556
+ private selectFromOutline;
557
+ private announceView;
558
+ private updateTooltip;
559
+ private positionTooltip;
560
+ private tooltipAnchor;
561
+ private readonly handleClick;
562
+ /** A right click, or the browser's own long press or context menu key, on a node. */
563
+ private readonly handleContextMenu;
564
+ /**
565
+ * Where a context menu event points on the map: the pointer when it is on
566
+ * the node, otherwise the node's center (menus opened from the keyboard
567
+ * report the element's corner, or nothing).
568
+ */
569
+ private contextPoint;
570
+ /** A node's center on the map. */
571
+ private nodeOnScreen;
572
+ /**
573
+ * Reports a long press, right click or context menu key on a node.
574
+ * Returns whether someone took it: an `onNodeContext` callback, a
575
+ * `node-context` listener, or a DOM listener that called
576
+ * `preventDefault()`. A press someone took doesn't open the node, and the
577
+ * browser's menu stays closed.
578
+ */
579
+ private openNodeContext;
580
+ /** Whether a press held on node `id` lifts it: on an editable map at rest, any node but the root and the sun. */
581
+ private canLift;
582
+ /** A press held still on node `id`: it lifts, to be dragged somewhere else. Returns whether it did. */
583
+ private liftNode;
584
+ /** The press holding a lifted node moved, was let go, or was taken away. */
585
+ private dragNode;
586
+ /**
587
+ * The lifted node leaves its place to follow the press. A planet of the
588
+ * focused orbit keeps its place held, so nothing moves and nothing slides
589
+ * under the press; anything else leaves an empty place behind.
590
+ */
591
+ private startCarrying;
592
+ /** Whether the node being dragged is one of the focused orbit's planets, laid out at the place held for it. */
593
+ private carriesPlanet;
594
+ /**
595
+ * Where the dragged node would go if let go now: into the node under the
596
+ * press, at the place in the orbit under it, or else at the place held for
597
+ * it. Null when there's none of those.
598
+ */
599
+ private dropPlaceAt;
600
+ /**
601
+ * Follows where the dragged node would go, and tells the page when that
602
+ * changes. The orbit is laid out again only when the place held in it
603
+ * moves: hovering a node leaves the planets where they are, so the node
604
+ * stays under the press.
605
+ */
606
+ private updateDropPlace;
607
+ /**
608
+ * Lays the view out again around the node being dragged, with the place
609
+ * held for it where it would land in the orbit, the planets making room.
610
+ * They glide from wherever they are this frame, and the camera holds still.
611
+ */
612
+ private relayoutForDrag;
613
+ /** Lets the dragged node go at `place`: it moves there (an `edit`), and flies from where it was let go. */
614
+ private dropNode;
615
+ /**
616
+ * Puts the dragged node back where it was: it flies back from where it
617
+ * was let go. One only lifted goes back down; `released` without moving
618
+ * after a long press no one took, it's typed into.
619
+ */
620
+ private putBack;
621
+ private emitDrag;
622
+ /**
623
+ * `display` with the node being dragged, and its moons, under the press:
624
+ * over a node it would go into, smaller, nearer the press and without its
625
+ * name, as if about to go inside.
626
+ */
627
+ private withCarried;
628
+ /** A click (or Enter) on a node: the sun goes back up, anything else is entered. */
629
+ private activate;
630
+ /** Up a level in focus mode; from the overview, back to focus mode. */
631
+ private goBack;
632
+ private readonly handleKeyDown;
633
+ /**
634
+ * Arrow-key movement. Focus mode: left and right step through the planets
635
+ * (turning the orbit so the chosen one sits on top), down enters the
636
+ * orbit, up returns to the sun. Overview: the tree, as in a tree view.
637
+ */
638
+ private moveFocus;
639
+ /** Turns the orbit so `planet` sits at the top. */
640
+ private turnToTop;
641
+ /** Pans the overview so a node that has keyboard focus is on screen. */
642
+ private keepInView;
643
+ private readonly handlePointerOver;
644
+ private readonly handlePointerOut;
645
+ private readonly handleFocusIn;
646
+ private readonly handleFocusOut;
647
+ private dragGestureAt;
648
+ private sunOnScreen;
649
+ private releaseSpin;
650
+ private readonly spinTask;
651
+ private spinSettled;
652
+ private planetNearestTop;
653
+ /** A short vibration each time a planet passes the top, like the detents of a dial. */
654
+ private tickHaptics;
655
+ /** The slow drift of `orbitAnimation`; it pauses while the reader is pointing at, holding or tabbing through the map. */
656
+ private syncAmbientMotion;
657
+ private shouldDrift;
658
+ private readonly ambientTask;
659
+ /** How far the bodies that spin with the orbit reach from the sun, in world units. */
660
+ private spinningReach;
661
+ private zoomLevel;
662
+ private zoomRange;
663
+ private viewportCenter;
664
+ /**
665
+ * Keeps the content reachable. The overview can pan until its edge meets
666
+ * the middle of the map; focus mode stays centered on the sun when fitted
667
+ * and gains room to pan the further it zooms in.
668
+ */
669
+ private clampCamera;
670
+ private panCamera;
671
+ private readonly glideTask;
672
+ /** Zooms immediately by `factor` around `anchor`, within the zoom range. */
673
+ private zoomAt;
674
+ /** Zooming into a planet or moon enters it; zooming out of a view leaves it. */
675
+ private checkZoomNavigation;
676
+ /** The planet or moon under `point` at least `minimumRadius` px on screen, preferring the smallest (most specific). */
677
+ private bodyAt;
678
+ /** After a pinch or wheel zoom: focus mode springs back from a partial zoom-out. */
679
+ private settleZoom;
680
+ private handleWheel;
681
+ private readonly wheelTask;
682
+ private handleDoubleTap;
683
+ /** An animated zoom step (buttons, keys, double taps). */
684
+ private zoomStep;
685
+ private flyCamera;
686
+ private readonly cameraFlightTask;
687
+ private afterCameraFlight;
688
+ /** Whether the page around the map scrolls; if so, a plain wheel scrolls the page instead of zooming. */
689
+ private pageScrolls;
690
+ private updateEmbedding;
691
+ private emitFocusChange;
692
+ /**
693
+ * Calls the `on()` listeners, then dispatches `orbit-<name>` on the
694
+ * container. Returns false when a DOM listener cancelled the event.
695
+ */
696
+ private emit;
697
+ /** Runs a button: one of Orbit's, or one of your actions, after `onAction` and the `action` event let it. */
698
+ private runAction;
699
+ /** Whether a button may do what it does: `onAction` didn't return `false` and no listener called the `action` event's `preventDefault()`. */
700
+ private allowAction;
701
+ /**
702
+ * A picture or video pressed in the detail sheet: a press of "View image"
703
+ * or "Play video". The viewer opens over the sheet; a page that takes the
704
+ * press gets the sheet closed, so what it opens is in front.
705
+ */
706
+ private viewFromSheet;
707
+ private openDetails;
708
+ /** The media viewer opened, stepped, or closed: the drift rests behind it, and the page hears of it. */
709
+ private mediaShown;
710
+ private mediaPlayed;
711
+ /** The node a `#id` link points at, in this map. */
712
+ private findLinked;
713
+ /** Where a node's link button goes: a page, or another node of the map ("Go to Research"). */
714
+ private describeLink;
715
+ /** Flies to the node a `#id` link points at, from a link button, the detail sheet or a note. */
716
+ private followNodeLink;
717
+ private observeResize;
718
+ /** Rests the drift while the map is scrolled out of sight, so a page of maps only moves the ones in view. */
719
+ private observeVisibility;
720
+ /** A map in a container without a height is invisible; say so once, in the console, where it gets noticed. */
721
+ private warnIfFlat;
722
+ private handleResize;
723
+ private setViewport;
724
+ private readContainerSize;
725
+ /** Flights and camera moves animate unless reduced motion is on or `transitionDuration` is 0. */
726
+ private animationsEnabled;
727
+ private prefersReducedMotion;
728
+ private now;
729
+ }