@morphemeris/armilla-core 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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/dist/armilla.d.ts +41 -0
  4. package/dist/armilla.js +98 -0
  5. package/dist/armilla.test.d.ts +1 -0
  6. package/dist/armilla.test.js +160 -0
  7. package/dist/basemap.generated.d.ts +8 -0
  8. package/dist/basemap.generated.js +9 -0
  9. package/dist/basemap.test.d.ts +1 -0
  10. package/dist/basemap.test.js +21 -0
  11. package/dist/index.d.ts +11 -0
  12. package/dist/index.js +11 -0
  13. package/dist/index.test.d.ts +1 -0
  14. package/dist/index.test.js +14 -0
  15. package/dist/index.web.d.ts +3 -0
  16. package/dist/index.web.js +24 -0
  17. package/dist/runtime.d.ts +13 -0
  18. package/dist/runtime.js +20 -0
  19. package/dist/surface.d.ts +10 -0
  20. package/dist/surface.js +9 -0
  21. package/dist/types.d.ts +55 -0
  22. package/dist/types.generated.d.ts +1274 -0
  23. package/dist/types.generated.js +4 -0
  24. package/dist/types.js +24 -0
  25. package/dist/vocabulary.generated.d.ts +8 -0
  26. package/dist/vocabulary.generated.js +9 -0
  27. package/dist/vocabulary.test.d.ts +1 -0
  28. package/dist/vocabulary.test.js +36 -0
  29. package/dist/wasm-types.d.ts +19 -0
  30. package/dist/wasm-types.js +1 -0
  31. package/dist/wasm.d.ts +2 -0
  32. package/dist/wasm.js +16 -0
  33. package/dist/web.test.d.ts +1 -0
  34. package/dist/web.test.js +34 -0
  35. package/dist/workspace.test.d.ts +1 -0
  36. package/dist/workspace.test.js +43 -0
  37. package/docs/changelog.md +37 -0
  38. package/docs/coordinates.md +52 -0
  39. package/docs/themes.md +111 -0
  40. package/docs/vocabulary.json +1501 -0
  41. package/docs/vocabulary.md +86 -0
  42. package/package.json +73 -0
  43. package/wasm/README.md +21 -0
  44. package/wasm/armilla_wasm.d.ts +104 -0
  45. package/wasm/armilla_wasm.js +497 -0
  46. package/wasm/armilla_wasm_bg.wasm +0 -0
  47. package/wasm/armilla_wasm_bg.wasm.d.ts +21 -0
  48. package/wasm/package.json +23 -0
  49. package/wasm-web/README.md +21 -0
  50. package/wasm-web/armilla_wasm.d.ts +150 -0
  51. package/wasm-web/armilla_wasm.js +583 -0
  52. package/wasm-web/armilla_wasm_bg.wasm +0 -0
  53. package/wasm-web/armilla_wasm_bg.wasm.d.ts +21 -0
  54. package/wasm-web/package.json +27 -0
@@ -0,0 +1,1274 @@
1
+ export type TrackKind = "wheel" | "dial" | "strip" | "declination" | "grid" | "tally" | "timeline" | "midpoints" | "dispositors" | "calendar" | "ephemeris" | "cycles" | "periods" | "map";
2
+ export type Space = {
3
+ /**
4
+ * Width in abstract units.
5
+ */
6
+ width: number;
7
+ /**
8
+ * Height in abstract units.
9
+ */
10
+ height: number;
11
+ };
12
+ export type SceneTypography = {
13
+ /**
14
+ * Font family.
15
+ */
16
+ family: string;
17
+ /**
18
+ * Fallback families, in order.
19
+ */
20
+ fallback: ReadonlyArray<string>;
21
+ };
22
+ export type BandInfo = {
23
+ /**
24
+ * Band role.
25
+ */
26
+ role: string;
27
+ /**
28
+ * The chart in this band, for chart bands.
29
+ */
30
+ chart: string | null;
31
+ /**
32
+ * Inner radius (polar) or top (linear).
33
+ */
34
+ inner: number;
35
+ /**
36
+ * Outer radius (polar) or bottom (linear).
37
+ */
38
+ outer: number;
39
+ /**
40
+ * Lane count.
41
+ */
42
+ lanes: number;
43
+ };
44
+ export type TrackInfo = {
45
+ /**
46
+ * The layout kind id (`wheel`, `dial`, ..., `grid`, `tally`).
47
+ */
48
+ kind: TrackKind;
49
+ /**
50
+ * Center of a polar track in scene units.
51
+ */
52
+ center: [number, number];
53
+ /**
54
+ * Outer radius of the outermost band (polar tracks).
55
+ */
56
+ outer_radius: number;
57
+ /**
58
+ * Periodic modulus in degrees; `None` on the declination graph.
59
+ */
60
+ modulus: number | null;
61
+ /**
62
+ * The longitude at the reference angle.
63
+ */
64
+ origin_lon: number;
65
+ /**
66
+ * Degrees, screen-counterclockwise from 3 o'clock, of axis parameter 0.
67
+ */
68
+ reference_angle: number;
69
+ /**
70
+ * `ccw` or `cw` (polar) — the direction of increasing longitude.
71
+ */
72
+ sense: string;
73
+ /**
74
+ * Bands outermost first.
75
+ */
76
+ bands: ReadonlyArray<BandInfo>;
77
+ };
78
+ export type Treatment = "normal" | "dim" | "emphasize";
79
+ export type MarkKind = "glyph" | "text" | "line" | "path" | "arc" | "sector" | "circle";
80
+ export type Anchor = "start" | "middle" | "end";
81
+ export type Baseline = "alphabetic" | "middle";
82
+ export type Segment = {
83
+ "op": "move";
84
+ /**
85
+ * X.
86
+ */
87
+ x: number;
88
+ /**
89
+ * Y.
90
+ */
91
+ y: number;
92
+ } | {
93
+ "op": "line";
94
+ /**
95
+ * X.
96
+ */
97
+ x: number;
98
+ /**
99
+ * Y.
100
+ */
101
+ y: number;
102
+ } | {
103
+ "op": "arc";
104
+ /**
105
+ * X radius.
106
+ */
107
+ rx: number;
108
+ /**
109
+ * Y radius.
110
+ */
111
+ ry: number;
112
+ /**
113
+ * Axis rotation in degrees.
114
+ */
115
+ rotation: number;
116
+ /**
117
+ * Large-arc flag.
118
+ */
119
+ large: boolean;
120
+ /**
121
+ * Sweep flag.
122
+ */
123
+ sweep: boolean;
124
+ /**
125
+ * End X.
126
+ */
127
+ x: number;
128
+ /**
129
+ * End Y.
130
+ */
131
+ y: number;
132
+ } | {
133
+ "op": "cubic";
134
+ /**
135
+ * First control X.
136
+ */
137
+ x1: number;
138
+ /**
139
+ * First control Y.
140
+ */
141
+ y1: number;
142
+ /**
143
+ * Second control X.
144
+ */
145
+ x2: number;
146
+ /**
147
+ * Second control Y.
148
+ */
149
+ y2: number;
150
+ /**
151
+ * End X.
152
+ */
153
+ x: number;
154
+ /**
155
+ * End Y.
156
+ */
157
+ y: number;
158
+ } | {
159
+ "op": "close";
160
+ };
161
+ export type Geometry = {
162
+ /**
163
+ * Glyph id.
164
+ */
165
+ glyph: string;
166
+ /**
167
+ * Variant actually served.
168
+ */
169
+ variant: string;
170
+ /**
171
+ * Origin X.
172
+ */
173
+ x: number;
174
+ /**
175
+ * Origin Y.
176
+ */
177
+ y: number;
178
+ /**
179
+ * Scene units per pack unit.
180
+ */
181
+ scale: number;
182
+ /**
183
+ * Rotation in degrees.
184
+ */
185
+ rotation: number;
186
+ } | {
187
+ /**
188
+ * The text.
189
+ */
190
+ text: string;
191
+ /**
192
+ * X.
193
+ */
194
+ x: number;
195
+ /**
196
+ * Y.
197
+ */
198
+ y: number;
199
+ /**
200
+ * Anchor.
201
+ */
202
+ anchor: Anchor;
203
+ /**
204
+ * Baseline.
205
+ */
206
+ baseline: Baseline;
207
+ /**
208
+ * Rotation in degrees.
209
+ */
210
+ rotation: number;
211
+ } | {
212
+ /**
213
+ * Center X.
214
+ */
215
+ cx: number;
216
+ /**
217
+ * Center Y.
218
+ */
219
+ cy: number;
220
+ /**
221
+ * Inner radius.
222
+ */
223
+ r_inner: number;
224
+ /**
225
+ * Outer radius.
226
+ */
227
+ r_outer: number;
228
+ /**
229
+ * Start angle.
230
+ */
231
+ start_deg: number;
232
+ /**
233
+ * End angle.
234
+ */
235
+ end_deg: number;
236
+ } | {
237
+ /**
238
+ * Center X.
239
+ */
240
+ cx: number;
241
+ /**
242
+ * Center Y.
243
+ */
244
+ cy: number;
245
+ /**
246
+ * Radius.
247
+ */
248
+ r: number;
249
+ /**
250
+ * Start angle.
251
+ */
252
+ start_deg: number;
253
+ /**
254
+ * End angle.
255
+ */
256
+ end_deg: number;
257
+ /**
258
+ * Sweep direction: `true` = counterclockwise on screen.
259
+ */
260
+ sweep: boolean;
261
+ } | {
262
+ /**
263
+ * Center X.
264
+ */
265
+ cx: number;
266
+ /**
267
+ * Center Y.
268
+ */
269
+ cy: number;
270
+ /**
271
+ * Radius.
272
+ */
273
+ r: number;
274
+ } | {
275
+ /**
276
+ * Start X.
277
+ */
278
+ x1: number;
279
+ /**
280
+ * Start Y.
281
+ */
282
+ y1: number;
283
+ /**
284
+ * End X.
285
+ */
286
+ x2: number;
287
+ /**
288
+ * End Y.
289
+ */
290
+ y2: number;
291
+ } | {
292
+ /**
293
+ * Segments, absolute coordinates.
294
+ */
295
+ d: ReadonlyArray<Segment>;
296
+ };
297
+ export type Decoration = "none" | "ring" | "underline" | "glyph";
298
+ export type Style = {
299
+ /**
300
+ * Stroke paint.
301
+ */
302
+ stroke: string;
303
+ /**
304
+ * Fill paint.
305
+ */
306
+ fill: string;
307
+ /**
308
+ * Stroke width in scene units.
309
+ */
310
+ width: number;
311
+ /**
312
+ * Dash array; empty is solid.
313
+ */
314
+ dash: ReadonlyArray<number>;
315
+ /**
316
+ * Opacity in `[0, 1]`.
317
+ */
318
+ opacity: number;
319
+ /**
320
+ * Font size in scene units.
321
+ */
322
+ font_size: number;
323
+ /**
324
+ * Font weight, 100..=900.
325
+ */
326
+ font_weight: number;
327
+ /**
328
+ * Glyph variant name, resolved against the pack later.
329
+ */
330
+ glyph_variant: string;
331
+ /**
332
+ * Decoration.
333
+ */
334
+ decoration: Decoration;
335
+ /**
336
+ * Painters enforce `width = max(width, min_width)`.
337
+ */
338
+ min_width: number;
339
+ /**
340
+ * Set by `shrink`; 1.0 otherwise. Not rule-settable.
341
+ */
342
+ glyph_scale_factor: number;
343
+ /**
344
+ * From the pack. Not rule-settable.
345
+ */
346
+ stroke_only: boolean;
347
+ /**
348
+ * Text template for roles that compose text from data (spec §10.5):
349
+ * `{p}` phase letter, `{d}` degrees, `{m}` zero-padded minutes.
350
+ * Empty means the role's built-in format; consumed by layout, not
351
+ * painters, and omitted from the scene when empty.
352
+ */
353
+ template?: string;
354
+ };
355
+ export type Tag = {
356
+ /**
357
+ * Tag key (spec §7.3).
358
+ */
359
+ key: string;
360
+ /**
361
+ * Tag value.
362
+ */
363
+ value: string;
364
+ };
365
+ export type DivisionKind = "sign" | "modality" | "bounds" | "decan" | "term" | "element" | "month" | "week" | "day" | "weekday" | "year";
366
+ export type Subject = {
367
+ "type": "point";
368
+ /**
369
+ * Chart role (`natal`, `transit`, ...).
370
+ */
371
+ chart: string;
372
+ /**
373
+ * astrologica body id.
374
+ */
375
+ body: string;
376
+ } | {
377
+ "type": "relation";
378
+ /**
379
+ * `chart` for intra-chart; `chart_a+chart_b` for inter-chart.
380
+ */
381
+ chart_part: string;
382
+ /**
383
+ * First body, in upstream order.
384
+ */
385
+ body_a: string;
386
+ /**
387
+ * Second body, in upstream order.
388
+ */
389
+ body_b: string;
390
+ /**
391
+ * Aspect id (`square`, `parallel`, ...).
392
+ */
393
+ aspect: string;
394
+ } | {
395
+ "type": "event";
396
+ /**
397
+ * The target's chart role.
398
+ */
399
+ chart: string;
400
+ /**
401
+ * The moving (transiting/progressed) body id.
402
+ */
403
+ moving: string;
404
+ /**
405
+ * The target body id.
406
+ */
407
+ target: string;
408
+ /**
409
+ * Aspect id.
410
+ */
411
+ aspect: string;
412
+ /**
413
+ * Occurrence index among events sharing the same triple,
414
+ * ordered by enter date — so ids stay stable as events append.
415
+ */
416
+ pass: number;
417
+ } | {
418
+ "type": "almanac";
419
+ /**
420
+ * The composed key (§7.4): `lunation:full:2026-03-03`,
421
+ * `ingress:moon-virgo:2026-03-02`,
422
+ * `station:jupiter-direct:2026-03-11`, `void:{start}`.
423
+ */
424
+ key: string;
425
+ } | {
426
+ "type": "series";
427
+ /**
428
+ * The composed key (§7.4): `series:{body}`,
429
+ * `separation:{a}-{b}`, `index:outer`.
430
+ */
431
+ key: string;
432
+ } | {
433
+ "type": "acg";
434
+ /**
435
+ * The chart role the lines belong to.
436
+ */
437
+ chart: string;
438
+ /**
439
+ * The composed key (§7.4):
440
+ * `acg:{body}:{angle | cusp{value}}:{mode}`, the cusp value per
441
+ * §13.1.
442
+ */
443
+ key: string;
444
+ } | {
445
+ "type": "period";
446
+ /**
447
+ * The chart role the periods belong to.
448
+ */
449
+ chart: string;
450
+ /**
451
+ * The composed key (§7.4):
452
+ * `period:{technique}:{level}:{start}`, start verbatim from the
453
+ * record.
454
+ */
455
+ key: string;
456
+ } | {
457
+ "type": "dispositor";
458
+ /**
459
+ * Chart role.
460
+ */
461
+ chart: string;
462
+ /**
463
+ * The disposed body (the arrow's tail).
464
+ */
465
+ from: string;
466
+ /**
467
+ * Its dispositor (the arrow's head).
468
+ */
469
+ to: string;
470
+ } | {
471
+ "type": "derived";
472
+ /**
473
+ * Chart role.
474
+ */
475
+ chart: string;
476
+ /**
477
+ * Kind id (`midpoint`, `lot`, `antiscion`, `contra_antiscion`).
478
+ */
479
+ kind: string;
480
+ /**
481
+ * Constituent body ids, in upstream order.
482
+ */
483
+ constituents: ReadonlyArray<string>;
484
+ } | {
485
+ "type": "pattern";
486
+ /**
487
+ * Chart role.
488
+ */
489
+ chart: string;
490
+ /**
491
+ * Pattern id (`t_square`, `yod`, ...).
492
+ */
493
+ pattern: string;
494
+ /**
495
+ * Member body ids, in upstream order.
496
+ */
497
+ bodies: ReadonlyArray<string>;
498
+ } | {
499
+ "type": "cusp";
500
+ /**
501
+ * Chart role.
502
+ */
503
+ chart: string;
504
+ /**
505
+ * House number, 1-12.
506
+ */
507
+ house: number;
508
+ } | {
509
+ "type": "division";
510
+ /**
511
+ * What kind of division.
512
+ */
513
+ kind: DivisionKind;
514
+ /**
515
+ * The division's value (`aries`, `cardinal`, `out`, ...).
516
+ */
517
+ value: string;
518
+ } | {
519
+ "type": "frame";
520
+ /**
521
+ * Chart role.
522
+ */
523
+ chart: string;
524
+ } | {
525
+ "type": "track";
526
+ };
527
+ export type Mark = {
528
+ /**
529
+ * Stable id (spec §7.4).
530
+ */
531
+ id: string;
532
+ /**
533
+ * The geometry kind; painters switch on it.
534
+ */
535
+ kind: MarkKind;
536
+ /**
537
+ * Geometry by kind (spec §13.1).
538
+ */
539
+ geometry: Geometry;
540
+ /**
541
+ * Fully resolved style (spec §10.5).
542
+ */
543
+ style: Style;
544
+ /**
545
+ * What the mark is (spec §7.2).
546
+ */
547
+ role: string;
548
+ /**
549
+ * What it depicts (spec §7.1).
550
+ */
551
+ subject: Subject;
552
+ /**
553
+ * Tags, a multiset (spec §7.3); environment tags are not emitted.
554
+ */
555
+ tags: ReadonlyArray<Tag>;
556
+ /**
557
+ * Measures (spec §5.3).
558
+ */
559
+ measures: {
560
+ [key in string]: number;
561
+ };
562
+ /**
563
+ * View-state treatment (spec §11.3).
564
+ */
565
+ treatment: Treatment;
566
+ };
567
+ export type SchemaVersions = {
568
+ /**
569
+ * Chart input.
570
+ */
571
+ chart_input: number;
572
+ /**
573
+ * Theme.
574
+ */
575
+ theme: number;
576
+ /**
577
+ * View state.
578
+ */
579
+ view_state: number;
580
+ /**
581
+ * Environment (fixed by the spec; always 1).
582
+ */
583
+ environment: number;
584
+ /**
585
+ * Scene.
586
+ */
587
+ scene: number;
588
+ };
589
+ export type PackRef = {
590
+ /**
591
+ * Pack id.
592
+ */
593
+ id: string;
594
+ /**
595
+ * Pack version string.
596
+ */
597
+ version: string;
598
+ };
599
+ export type GlyphPackProvenance = {
600
+ /**
601
+ * What the theme asked for.
602
+ */
603
+ requested: PackRef;
604
+ /**
605
+ * What served the theme-pack role.
606
+ */
607
+ used: PackRef;
608
+ };
609
+ export type EnvironmentDoc = {
610
+ /**
611
+ * Output medium.
612
+ */
613
+ medium: Medium;
614
+ /**
615
+ * Light or dark scheme.
616
+ */
617
+ scheme: Scheme;
618
+ /**
619
+ * Contrast preference.
620
+ */
621
+ contrast: Contrast;
622
+ /**
623
+ * Motion preference (consumed by painters; carried for predicates).
624
+ */
625
+ motion: Motion;
626
+ /**
627
+ * Layout density.
628
+ */
629
+ density: Density;
630
+ };
631
+ export type Provenance = {
632
+ /**
633
+ * The core crate version.
634
+ */
635
+ core_version: string;
636
+ /**
637
+ * SHA-256 (hex) of the canonical JSON of the chart input.
638
+ */
639
+ input_digest: string;
640
+ /**
641
+ * Schema versions of every document involved.
642
+ */
643
+ schema_versions: SchemaVersions;
644
+ /**
645
+ * Document to original version, when migration ran.
646
+ */
647
+ migrated_from?: {
648
+ [key in string]: number;
649
+ } | null;
650
+ /**
651
+ * `(id, version)` of every theme in the chain, root first.
652
+ */
653
+ theme_chain: ReadonlyArray<[string, string]>;
654
+ /**
655
+ * `caller` or `default`.
656
+ */
657
+ orb_table: string;
658
+ /**
659
+ * The pack the theme asked for and the one that served it.
660
+ */
661
+ glyph_pack: GlyphPackProvenance;
662
+ /**
663
+ * Glyph ids served from the primitive pack as a fallback.
664
+ */
665
+ glyph_fallbacks: ReadonlyArray<string>;
666
+ /**
667
+ * Degradation notes, sorted (`origin:asc→aries`, `variant:bold→regular`,
668
+ * `collision:overflow:<band>`, ...).
669
+ */
670
+ degraded: ReadonlyArray<string>;
671
+ /**
672
+ * The environment the scene was laid out for.
673
+ */
674
+ environment: EnvironmentDoc;
675
+ };
676
+ export type Scene = {
677
+ /**
678
+ * Always [`SCENE_SCHEMA_VERSION`] for scenes this core emits.
679
+ */
680
+ schema_version: number;
681
+ /**
682
+ * The coordinate space.
683
+ */
684
+ space: Space;
685
+ /**
686
+ * The font stack for text marks (spec §14).
687
+ */
688
+ typography: SceneTypography;
689
+ /**
690
+ * Track geometry for hosts (hit-testing); painters ignore it.
691
+ */
692
+ tracks: ReadonlyArray<TrackInfo>;
693
+ /**
694
+ * Marks in paint order (spec §13.2).
695
+ */
696
+ marks: ReadonlyArray<Mark>;
697
+ /**
698
+ * What happened (spec §13.3).
699
+ */
700
+ provenance: Provenance;
701
+ };
702
+ export type Medium = "screen" | "print" | "export";
703
+ export type Scheme = "light" | "dark";
704
+ export type Contrast = "normal" | "high";
705
+ export type Motion = "full" | "reduced";
706
+ export type Density = "normal" | "compact";
707
+ export type Origin = "asc" | "aries" | "mc";
708
+ export type OriginSpec = Origin | number;
709
+ export type TreatRuleDoc = {
710
+ /**
711
+ * The predicate; accepts the compact string form on input.
712
+ */
713
+ when: string | {
714
+ all: ReadonlyArray<Record<string, unknown>>;
715
+ };
716
+ /**
717
+ * The treatment.
718
+ */
719
+ treat: "hide" | "show" | "dim" | "emphasize";
720
+ /**
721
+ * Spec §3.5 (2026-09-06): a disabled rule rides the document and its
722
+ * bookmark but the treatment cascade skips it — hosts toggle rules
723
+ * for quick comparisons without losing them. Omitted when false.
724
+ */
725
+ disabled?: boolean;
726
+ /**
727
+ * Spec §3.5 (2026-09-06): an optional host-display name — "hide A's
728
+ * intra aspects" reads better than its predicate. Never interpreted.
729
+ */
730
+ name?: string;
731
+ };
732
+ export type Window = {
733
+ /**
734
+ * Start of the visible range (inclusive).
735
+ */
736
+ start: string;
737
+ /**
738
+ * End of the visible range (exclusive).
739
+ */
740
+ end: string;
741
+ };
742
+ export type Region = {
743
+ /**
744
+ * `[min, max]` longitude, within `[-180, 180]`.
745
+ */
746
+ lon: [number, number];
747
+ /**
748
+ * `[min, max]` latitude, within `[-90, 90]`.
749
+ */
750
+ lat: [number, number];
751
+ };
752
+ export type Place = {
753
+ /**
754
+ * Latitude in degrees, north positive, `[-90, 90]`.
755
+ */
756
+ latitude: number;
757
+ /**
758
+ * Longitude in degrees, east positive, `[-180, 180]`.
759
+ */
760
+ longitude: number;
761
+ };
762
+ export type ViewStateDoc = {
763
+ /**
764
+ * Always [`VIEW_STATE_SCHEMA_VERSION`].
765
+ */
766
+ schema_version: number;
767
+ /**
768
+ * Ordered treatment rules; later wins.
769
+ */
770
+ rules?: ReadonlyArray<TreatRuleDoc>;
771
+ /**
772
+ * Whose cusps and angles draw.
773
+ */
774
+ frame?: string | null;
775
+ /**
776
+ * Band role to chart role.
777
+ */
778
+ bands?: {
779
+ [key in string]: string;
780
+ } | null;
781
+ /**
782
+ * Origin override.
783
+ */
784
+ origin?: OriginSpec | null;
785
+ /**
786
+ * Modulus override where the track kind accepts one; an explicit
787
+ * `null` means non-periodic.
788
+ */
789
+ modulus?: number | null | null;
790
+ /**
791
+ * Dial pointer longitude.
792
+ */
793
+ indicator?: number | null;
794
+ /**
795
+ * The time map's visible date range (spec §6.10); absent = the
796
+ * events' extent, snapped outward to month boundaries.
797
+ */
798
+ window?: Window | null;
799
+ /**
800
+ * The time map's now-cursor date (spec §6.10), ISO-8601 UTC.
801
+ */
802
+ cursor?: string | null;
803
+ /**
804
+ * Expanded period subject keys (spec §6.16, 2026-09-20):
805
+ * `period:{technique}:{level}:{start}` entries whose child periods
806
+ * draw. Unknown keys are ignored.
807
+ */
808
+ expanded?: ReadonlyArray<string>;
809
+ /**
810
+ * The map's visible window (spec §6.17); absent = the whole world
811
+ * clipped at ±85°.
812
+ */
813
+ region?: Region | null;
814
+ /**
815
+ * The map's place marker (spec §6.17).
816
+ */
817
+ place?: Place | null;
818
+ /**
819
+ * Hover/selection rules; applied after `rules`, excluded from bookmarks.
820
+ */
821
+ transient?: ReadonlyArray<TreatRuleDoc>;
822
+ };
823
+ export type TimelineEvent = {
824
+ /**
825
+ * The moving (transiting/progressed/directed) body id. Not required
826
+ * to appear in any chart — its positions are a time series upstream.
827
+ */
828
+ moving: string;
829
+ /**
830
+ * The aspect the moving body makes.
831
+ */
832
+ aspect: string;
833
+ /**
834
+ * The target body; must name a position in the target chart.
835
+ */
836
+ target: string;
837
+ /**
838
+ * The target's chart role; defaults to the first chart in input
839
+ * order when absent.
840
+ */
841
+ chart: string | null;
842
+ /**
843
+ * When the moving body enters orb.
844
+ */
845
+ enter: string;
846
+ /**
847
+ * The exact passes, ascending — one, or three across a retrograde
848
+ * loop; may be empty for a span that never perfects in range.
849
+ */
850
+ exacts: ReadonlyArray<string>;
851
+ /**
852
+ * When the moving body leaves orb.
853
+ */
854
+ leave: string;
855
+ /**
856
+ * The moving body's motion at `enter` (spec §6.10). Absent means no
857
+ * motion display: the bar stays one unsegmented mark.
858
+ */
859
+ motion?: StationDirection | null;
860
+ /**
861
+ * Instants the motion flips, ascending within `[enter, leave]`;
862
+ * requires `motion` (spec §6.10). Absent and empty are the same
863
+ * document.
864
+ */
865
+ stations?: ReadonlyArray<string>;
866
+ };
867
+ export type LunationPhase = "new" | "first_quarter" | "full" | "last_quarter";
868
+ export type EclipseKind = "solar" | "lunar";
869
+ export type StationDirection = "retrograde" | "direct";
870
+ export type AlmanacEvent = {
871
+ "kind": "lunation";
872
+ /**
873
+ * When the phase perfects (§6.10 timestamp format).
874
+ */
875
+ timestamp: string;
876
+ /**
877
+ * Which of the four phases.
878
+ */
879
+ phase: LunationPhase;
880
+ /**
881
+ * The lunation's ecliptic longitude, for its sign and degree.
882
+ */
883
+ longitude?: number | null;
884
+ /**
885
+ * Present when the lunation is an eclipse.
886
+ */
887
+ eclipse?: EclipseKind | null;
888
+ } | {
889
+ "kind": "ingress";
890
+ /**
891
+ * When it crosses.
892
+ */
893
+ timestamp: string;
894
+ /**
895
+ * The moving body.
896
+ */
897
+ body: string;
898
+ /**
899
+ * The sign entered.
900
+ */
901
+ sign: string;
902
+ } | {
903
+ "kind": "station";
904
+ /**
905
+ * When the speed crosses zero.
906
+ */
907
+ timestamp: string;
908
+ /**
909
+ * The stationing body.
910
+ */
911
+ body: string;
912
+ /**
913
+ * The motion it turns to.
914
+ */
915
+ station: StationDirection;
916
+ /**
917
+ * The station's ecliptic longitude.
918
+ */
919
+ longitude?: number | null;
920
+ } | {
921
+ "kind": "void";
922
+ /**
923
+ * The last exact aspect before the sign change.
924
+ */
925
+ start: string;
926
+ /**
927
+ * The ingress that ends the void.
928
+ */
929
+ end: string;
930
+ /**
931
+ * The closing aspect that begins the void, when upstream
932
+ * names it.
933
+ */
934
+ aspect?: string | null;
935
+ /**
936
+ * The planet the moon's closing aspect perfects to.
937
+ */
938
+ target?: string | null;
939
+ };
940
+ export type BasemapKind = "land" | "border";
941
+ export type BasemapFeature = {
942
+ /**
943
+ * Land ring or border polyline.
944
+ */
945
+ kind: BasemapKind;
946
+ /**
947
+ * `[longitude, latitude]` pairs; lon `[-180, 180]`, lat `[-90, 90]`,
948
+ * no consecutive jump wider than 180° of longitude.
949
+ */
950
+ points: ReadonlyArray<[number, number]>;
951
+ };
952
+ export type Basemap = {
953
+ /**
954
+ * Names the geography source in the map legend.
955
+ */
956
+ id: string;
957
+ /**
958
+ * The features, drawn in order.
959
+ */
960
+ features: ReadonlyArray<BasemapFeature>;
961
+ };
962
+ export type LayoutOptionsDoc = {
963
+ /**
964
+ * Layout kind.
965
+ */
966
+ kind: TrackKind;
967
+ /**
968
+ * Scene width; the kind's default when absent.
969
+ */
970
+ width?: number;
971
+ /**
972
+ * Scene height.
973
+ */
974
+ height?: number;
975
+ /**
976
+ * Margin.
977
+ */
978
+ margin?: number;
979
+ /**
980
+ * Glyph pack manifest, parsed by the surface.
981
+ */
982
+ pack?: unknown;
983
+ /**
984
+ * Band assignment, band role to chart role.
985
+ */
986
+ bands?: {
987
+ [key in string]: string;
988
+ };
989
+ /**
990
+ * Frame chart role.
991
+ */
992
+ frame?: string;
993
+ };
994
+ export type TableKind = "positions" | "cusps" | "aspects";
995
+ export type TableOptions = {
996
+ /**
997
+ * The listing kind.
998
+ */
999
+ kind: TableKind;
1000
+ /**
1001
+ * Chart role — or, for the aspects kind, an inter-chart pair key
1002
+ * (`"a+b"`). View state `frame` overrides it; absent means the
1003
+ * single chart.
1004
+ */
1005
+ chart?: string;
1006
+ };
1007
+ export type TableCell = {
1008
+ /**
1009
+ * The column this cell fills.
1010
+ */
1011
+ column: string;
1012
+ /**
1013
+ * Formatted text; empty when upstream gave no value.
1014
+ */
1015
+ text: string;
1016
+ /**
1017
+ * Glyph id for body, sign, and aspect cells.
1018
+ */
1019
+ glyph?: string | null;
1020
+ };
1021
+ export type TableColumn = {
1022
+ /**
1023
+ * Column id, referenced by every cell.
1024
+ */
1025
+ id: string;
1026
+ /**
1027
+ * Display heading.
1028
+ */
1029
+ label: string;
1030
+ /**
1031
+ * `start` for names, `end` for numeric columns.
1032
+ */
1033
+ align: string;
1034
+ };
1035
+ export type TableRow = {
1036
+ /**
1037
+ * Stable id (spec §7.4).
1038
+ */
1039
+ id: string;
1040
+ /**
1041
+ * The subject's tags, role and id included.
1042
+ */
1043
+ tags: ReadonlyArray<Tag>;
1044
+ /**
1045
+ * The subject's measures (spec §5.3), for host-side sorting.
1046
+ */
1047
+ measures: {
1048
+ [key in string]: number;
1049
+ };
1050
+ /**
1051
+ * View-state treatment; hidden rows never appear.
1052
+ */
1053
+ treatment: Treatment;
1054
+ /**
1055
+ * Cells in column order.
1056
+ */
1057
+ cells: ReadonlyArray<TableCell>;
1058
+ };
1059
+ export type TableModel = {
1060
+ /**
1061
+ * The listing kind.
1062
+ */
1063
+ kind: string;
1064
+ /**
1065
+ * The chart role, or the inter-chart pair key.
1066
+ */
1067
+ chart: string;
1068
+ /**
1069
+ * Column order is presentation order.
1070
+ */
1071
+ columns: ReadonlyArray<TableColumn>;
1072
+ /**
1073
+ * Rows in input order; hidden rows are already omitted.
1074
+ */
1075
+ rows: ReadonlyArray<TableRow>;
1076
+ };
1077
+ export type MapLine = {
1078
+ /**
1079
+ * Stable id (spec §7.4).
1080
+ */
1081
+ id: string;
1082
+ /**
1083
+ * The §6.17 line vocabulary, role and id included.
1084
+ */
1085
+ tags: ReadonlyArray<Tag>;
1086
+ /**
1087
+ * The body glyph the §6.17 map labels the line with.
1088
+ */
1089
+ glyph: string;
1090
+ /**
1091
+ * `AC` | `DC` | `MC` | `IC` | the cusp value, carrying the raised
1092
+ * mode mark under the same dual-mode rule as the map.
1093
+ */
1094
+ designation: string;
1095
+ /**
1096
+ * View-state treatment; hidden lines never appear.
1097
+ */
1098
+ treatment: Treatment;
1099
+ /**
1100
+ * Upstream segments verbatim: `[longitude, latitude]` pairs, the
1101
+ * §3.1 basemap convention; segment breaks are upstream's
1102
+ * terminations.
1103
+ */
1104
+ segments: ReadonlyArray<ReadonlyArray<[number, number]>>;
1105
+ };
1106
+ export type MapLinesModel = {
1107
+ /**
1108
+ * The chart role the lines belong to.
1109
+ */
1110
+ chart: string;
1111
+ /**
1112
+ * Lines in input order; hidden lines are already omitted.
1113
+ */
1114
+ lines: ReadonlyArray<MapLine>;
1115
+ };
1116
+ export type ErrorCode = "SHAPE" | "VERSION" | "IDENT" | "LIMIT" | "REF" | "ORB_MISSING" | "LINT" | "PACK" | "INTERNAL";
1117
+ export type Document = "chart_input" | "theme" | "view_state" | "environment" | "workspace" | "bookmark" | "pack" | "scene";
1118
+ export type ErrorRecord = {
1119
+ /**
1120
+ * Error category.
1121
+ */
1122
+ code: ErrorCode;
1123
+ /**
1124
+ * JSON pointer into the offending document (e.g. `/charts/natal/aspects/0`).
1125
+ */
1126
+ path: string;
1127
+ /**
1128
+ * Human-readable message. Never echoes more than 64 bytes of input.
1129
+ */
1130
+ message: string;
1131
+ /**
1132
+ * Which document the path points into.
1133
+ */
1134
+ document: Document;
1135
+ };
1136
+ export type LintCode = "L001" | "L002" | "L003" | "L004" | "L005" | "L006" | "L007" | "L008" | "L009";
1137
+ export type Severity = "warning" | "error";
1138
+ export type Finding = {
1139
+ /**
1140
+ * The code.
1141
+ */
1142
+ code: LintCode;
1143
+ /**
1144
+ * Index into the concatenated rule list; `None` for chain-level codes.
1145
+ */
1146
+ rule_index: number | null;
1147
+ /**
1148
+ * Severity.
1149
+ */
1150
+ severity: Severity;
1151
+ /**
1152
+ * Human-readable message; never echoes more than 64 bytes of input.
1153
+ */
1154
+ message: string;
1155
+ };
1156
+ export type Explanation = {
1157
+ /**
1158
+ * Index into the root-first concatenation of the chain's rules — the
1159
+ * same indexing the linter's findings use.
1160
+ */
1161
+ rule_index: number;
1162
+ /**
1163
+ * The `id` of the theme document whose rule it is.
1164
+ */
1165
+ theme_id: string;
1166
+ };
1167
+ export type PanelKind = "wheel" | "dial" | "strip" | "declination" | "grid" | "tally" | "timeline" | "midpoints" | "dispositors" | "calendar" | "ephemeris" | "cycles" | "periods" | "table" | "text";
1168
+ export type LayoutKind = "grid";
1169
+ export type GridLayout = {
1170
+ /**
1171
+ * The layout kind.
1172
+ */
1173
+ kind: LayoutKind;
1174
+ /**
1175
+ * Grid width in cells.
1176
+ */
1177
+ columns: number;
1178
+ /**
1179
+ * Grid height in cells.
1180
+ */
1181
+ rows: number;
1182
+ };
1183
+ export type CellSpec = {
1184
+ /**
1185
+ * Leftmost column, zero-based.
1186
+ */
1187
+ col: number;
1188
+ /**
1189
+ * Topmost row, zero-based.
1190
+ */
1191
+ row: number;
1192
+ /**
1193
+ * Columns spanned, at least 1.
1194
+ */
1195
+ col_span: number;
1196
+ /**
1197
+ * Rows spanned, at least 1.
1198
+ */
1199
+ row_span: number;
1200
+ };
1201
+ export type Panel = {
1202
+ /**
1203
+ * Identifier, unique within the workspace.
1204
+ */
1205
+ id: string;
1206
+ /**
1207
+ * What the panel renders. `grid`, `table`, and `text` are out of the
1208
+ * core's render scope (§1.4); a host renders them by other means.
1209
+ */
1210
+ kind: PanelKind;
1211
+ /**
1212
+ * Default band assignment, band role to chart role; view state
1213
+ * `bands` may override (§11.4).
1214
+ */
1215
+ charts?: {
1216
+ [key in string]: string;
1217
+ };
1218
+ /**
1219
+ * Default frame chart role.
1220
+ */
1221
+ frame?: string | null;
1222
+ /**
1223
+ * The theme this panel resolves, or `inherit` from the workspace host.
1224
+ */
1225
+ theme: string;
1226
+ /**
1227
+ * An independent view state, or membership in a shared group.
1228
+ */
1229
+ view: "own" | {
1230
+ shared: string;
1231
+ };
1232
+ /**
1233
+ * Where the panel sits on the grid.
1234
+ */
1235
+ cell: CellSpec;
1236
+ /**
1237
+ * Per-kind options (e.g. grid `variant`); opaque to the core.
1238
+ */
1239
+ options?: Record<string, unknown>;
1240
+ };
1241
+ export type Workspace = {
1242
+ /**
1243
+ * Always [`WORKSPACE_SCHEMA_VERSION`].
1244
+ */
1245
+ schema_version: number;
1246
+ /**
1247
+ * Identifier.
1248
+ */
1249
+ id: string;
1250
+ /**
1251
+ * Display name.
1252
+ */
1253
+ name: string;
1254
+ /**
1255
+ * What the host must supply — roles, never chart identities: a
1256
+ * workspace is a page design that applies to any chart set that
1257
+ * fills its roles.
1258
+ */
1259
+ chart_roles: ReadonlyArray<string>;
1260
+ /**
1261
+ * The grid panels span.
1262
+ */
1263
+ layout: GridLayout;
1264
+ /**
1265
+ * The panels.
1266
+ */
1267
+ panels: ReadonlyArray<Panel>;
1268
+ /**
1269
+ * Shared view states by group name; panels link by naming a group.
1270
+ */
1271
+ views?: {
1272
+ [key in string]: ViewStateDoc;
1273
+ };
1274
+ };