magick-components 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 (173) hide show
  1. package/LICENSE.txt +89 -0
  2. package/README.md +353 -2
  3. package/fonts/FrankRuhlLibre-Bold-letters.woff2 +0 -0
  4. package/fonts/FrankRuhlLibre-OFL.txt +105 -0
  5. package/fonts/NotoSerif-BoldItalic-compass.woff2 +0 -0
  6. package/fonts/NotoSerif-Italic-latin1.woff2 +0 -0
  7. package/fonts/NotoSerif-OFL.txt +93 -0
  8. package/fonts/SOURCES.md +35 -0
  9. package/fonts/gd-hall.css +3 -0
  10. package/lib/astrology/Kamea.d.ts +75 -0
  11. package/lib/astrology/Kamea.js +73 -0
  12. package/lib/astrology/MercuryWidget.d.ts +21 -0
  13. package/lib/astrology/MercuryWidget.js +80 -0
  14. package/lib/astrology/Moon.d.ts +32 -0
  15. package/lib/astrology/Moon.js +39 -0
  16. package/lib/astrology/MoonWidget.d.ts +20 -0
  17. package/lib/astrology/MoonWidget.js +63 -0
  18. package/lib/astrology/PlanetarySpirit.d.ts +103 -0
  19. package/lib/astrology/PlanetarySpirit.js +102 -0
  20. package/lib/astrology/mercuryRetrograde.d.ts +20 -0
  21. package/lib/astrology/mercuryRetrograde.js +80 -0
  22. package/lib/astrology/moonPath.d.ts +20 -0
  23. package/lib/astrology/moonPath.js +45 -0
  24. package/lib/chakras/Chakras.d.ts +34 -0
  25. package/lib/chakras/Chakras.js +149 -0
  26. package/lib/cssString.d.ts +5 -0
  27. package/lib/cssString.js +7 -0
  28. package/lib/drawingVersions.d.ts +29 -0
  29. package/lib/drawingVersions.js +15 -0
  30. package/lib/enochian/Tablet.d.ts +17 -0
  31. package/lib/enochian/Tablet.js +24 -0
  32. package/lib/enochian/tabletSigils.d.ts +46 -0
  33. package/lib/enochian/tabletSigils.js +172 -0
  34. package/lib/enochian/tabletSvg.d.ts +85 -0
  35. package/lib/enochian/tabletSvg.js +278 -0
  36. package/lib/gd/FylfotCross.d.ts +60 -0
  37. package/lib/gd/FylfotCross.js +121 -0
  38. package/lib/gd/GradeTree.d.ts +10 -0
  39. package/lib/gd/GradeTree.js +21 -0
  40. package/lib/gd/Lamen.d.ts +31 -0
  41. package/lib/gd/Lamen.js +317 -0
  42. package/lib/gd/RoseSigil.d.ts +31 -0
  43. package/lib/gd/RoseSigil.js +49 -0
  44. package/lib/gd/RoseSigilImage.d.ts +38 -0
  45. package/lib/gd/RoseSigilImage.js +29 -0
  46. package/lib/gd/SevenBranchedCandlestick.d.ts +54 -0
  47. package/lib/gd/SevenBranchedCandlestick.js +269 -0
  48. package/lib/gd/TableOfShewbread.d.ts +19 -0
  49. package/lib/gd/TableOfShewbread.js +120 -0
  50. package/lib/gd/hall/GdHall.d.ts +94 -0
  51. package/lib/gd/hall/GdHall.js +147 -0
  52. package/lib/gd/hall/art/altar.d.ts +8 -0
  53. package/lib/gd/hall/art/altar.js +21 -0
  54. package/lib/gd/hall/art/altarItems.d.ts +20 -0
  55. package/lib/gd/hall/art/altarItems.js +113 -0
  56. package/lib/gd/hall/art/banner.d.ts +23 -0
  57. package/lib/gd/hall/art/banner.js +64 -0
  58. package/lib/gd/hall/art/board.d.ts +9 -0
  59. package/lib/gd/hall/art/board.js +49 -0
  60. package/lib/gd/hall/art/cards.d.ts +11 -0
  61. package/lib/gd/hall/art/cards.js +124 -0
  62. package/lib/gd/hall/art/furnishings.d.ts +12 -0
  63. package/lib/gd/hall/art/furnishings.js +36 -0
  64. package/lib/gd/hall/art/geometry.d.ts +49 -0
  65. package/lib/gd/hall/art/geometry.js +97 -0
  66. package/lib/gd/hall/art/hebrewLetter.d.ts +10 -0
  67. package/lib/gd/hall/art/hebrewLetter.js +38 -0
  68. package/lib/gd/hall/art/index.d.ts +7 -0
  69. package/lib/gd/hall/art/index.js +61 -0
  70. package/lib/gd/hall/art/items.d.ts +12 -0
  71. package/lib/gd/hall/art/items.js +125 -0
  72. package/lib/gd/hall/art/kamea.d.ts +20 -0
  73. package/lib/gd/hall/art/kamea.js +64 -0
  74. package/lib/gd/hall/art/lamen.d.ts +9 -0
  75. package/lib/gd/hall/art/lamen.js +52 -0
  76. package/lib/gd/hall/art/lightning.d.ts +13 -0
  77. package/lib/gd/hall/art/lightning.js +44 -0
  78. package/lib/gd/hall/art/lights.d.ts +13 -0
  79. package/lib/gd/hall/art/lights.js +64 -0
  80. package/lib/gd/hall/art/marker.d.ts +8 -0
  81. package/lib/gd/hall/art/marker.js +19 -0
  82. package/lib/gd/hall/art/pantacle.d.ts +10 -0
  83. package/lib/gd/hall/art/pantacle.js +119 -0
  84. package/lib/gd/hall/art/pillar.d.ts +4 -0
  85. package/lib/gd/hall/art/pillar.js +25 -0
  86. package/lib/gd/hall/art/placeholder.d.ts +8 -0
  87. package/lib/gd/hall/art/placeholder.js +18 -0
  88. package/lib/gd/hall/art/platform.d.ts +13 -0
  89. package/lib/gd/hall/art/platform.js +28 -0
  90. package/lib/gd/hall/art/seals.d.ts +23 -0
  91. package/lib/gd/hall/art/seals.js +151 -0
  92. package/lib/gd/hall/art/shared.d.ts +87 -0
  93. package/lib/gd/hall/art/shared.js +95 -0
  94. package/lib/gd/hall/art/symbols.d.ts +37 -0
  95. package/lib/gd/hall/art/symbols.js +134 -0
  96. package/lib/gd/hall/art/tarotKey.d.ts +34 -0
  97. package/lib/gd/hall/art/tarotKey.js +101 -0
  98. package/lib/gd/hall/art/veil.d.ts +8 -0
  99. package/lib/gd/hall/art/veil.js +22 -0
  100. package/lib/gd/hall/art/vessels.d.ts +19 -0
  101. package/lib/gd/hall/art/vessels.js +74 -0
  102. package/lib/gd/hall/aspect.d.ts +31 -0
  103. package/lib/gd/hall/aspect.js +161 -0
  104. package/lib/gd/hall/attributes.d.ts +52 -0
  105. package/lib/gd/hall/attributes.js +116 -0
  106. package/lib/gd/hall/describe.d.ts +38 -0
  107. package/lib/gd/hall/describe.js +184 -0
  108. package/lib/gd/hall/dimensions.d.ts +39 -0
  109. package/lib/gd/hall/dimensions.js +49 -0
  110. package/lib/gd/hall/editor.d.ts +13 -0
  111. package/lib/gd/hall/editor.js +13 -0
  112. package/lib/gd/hall/fontMetrics.json +177 -0
  113. package/lib/gd/hall/fonts.d.ts +45 -0
  114. package/lib/gd/hall/fonts.js +73 -0
  115. package/lib/gd/hall/hebrewLetters.d.ts +8 -0
  116. package/lib/gd/hall/hebrewLetters.js +40 -0
  117. package/lib/gd/hall/index.d.ts +19 -0
  118. package/lib/gd/hall/index.js +17 -0
  119. package/lib/gd/hall/labels.d.ts +72 -0
  120. package/lib/gd/hall/labels.js +109 -0
  121. package/lib/gd/hall/layout.d.ts +213 -0
  122. package/lib/gd/hall/layout.js +837 -0
  123. package/lib/gd/hall/planets.d.ts +13 -0
  124. package/lib/gd/hall/planets.js +35 -0
  125. package/lib/gd/hall/presets/index.d.ts +13 -0
  126. package/lib/gd/hall/presets/index.js +29 -0
  127. package/lib/gd/hall/presets/neophyte.d.ts +7 -0
  128. package/lib/gd/hall/presets/neophyte.js +74 -0
  129. package/lib/gd/hall/presets/philosophus.d.ts +30 -0
  130. package/lib/gd/hall/presets/philosophus.js +244 -0
  131. package/lib/gd/hall/presets/portal.d.ts +24 -0
  132. package/lib/gd/hall/presets/portal.js +241 -0
  133. package/lib/gd/hall/presets/practicus.d.ts +17 -0
  134. package/lib/gd/hall/presets/practicus.js +181 -0
  135. package/lib/gd/hall/presets/theoricus.d.ts +13 -0
  136. package/lib/gd/hall/presets/theoricus.js +178 -0
  137. package/lib/gd/hall/presets/types.d.ts +72 -0
  138. package/lib/gd/hall/presets/types.js +58 -0
  139. package/lib/gd/hall/presets/zelator.d.ts +12 -0
  140. package/lib/gd/hall/presets/zelator.js +161 -0
  141. package/lib/gd/hall/spec.d.ts +54 -0
  142. package/lib/gd/hall/spec.js +108 -0
  143. package/lib/gd/hall/types.d.ts +131 -0
  144. package/lib/gd/hall/types.js +1 -0
  145. package/lib/gd/hall/validate.d.ts +13 -0
  146. package/lib/gd/hall/validate.js +285 -0
  147. package/lib/gd/hall/vocabulary.d.ts +139 -0
  148. package/lib/gd/hall/vocabulary.js +435 -0
  149. package/lib/gd/lamenGlyphs.d.ts +16 -0
  150. package/lib/gd/lamenGlyphs.js +167 -0
  151. package/lib/gd/lamenGrades.d.ts +29 -0
  152. package/lib/gd/lamenGrades.js +36 -0
  153. package/lib/gd/roseSigilGeometry.d.ts +10 -0
  154. package/lib/gd/roseSigilGeometry.js +10 -0
  155. package/lib/gd/roseSigilInternals.d.ts +85 -0
  156. package/lib/gd/roseSigilInternals.js +343 -0
  157. package/lib/gd/roseSigilOptimizer.d.ts +15 -0
  158. package/lib/gd/roseSigilOptimizer.js +59 -0
  159. package/lib/gd/roseSigilVersions.d.ts +12 -0
  160. package/lib/gd/roseSigilVersions.js +57 -0
  161. package/lib/hooks/useHydrated.d.ts +9 -0
  162. package/lib/hooks/useHydrated.js +13 -0
  163. package/lib/kabbalah/TreeOfLife.d.ts +135 -0
  164. package/lib/kabbalah/TreeOfLife.js +312 -0
  165. package/lib/kabbalah/fieldPath.d.ts +25 -0
  166. package/lib/kabbalah/fieldPath.js +100 -0
  167. package/lib/kabbalah/treeLabels.d.ts +30 -0
  168. package/lib/kabbalah/treeLabels.js +32 -0
  169. package/lib/kabbalah/treeOfLifeFigure.d.ts +59 -0
  170. package/lib/kabbalah/treeOfLifeFigure.js +151 -0
  171. package/lib/svgCoordinate.d.ts +12 -0
  172. package/lib/svgCoordinate.js +16 -0
  173. package/package.json +162 -3
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ITEM_DETAIL, ITEM_OUTLINE, original, PALETTE, sameForEveryNode, } from "./shared.js";
3
+ export const gongProvenance = original("A gong on its frame, drawn from geometry: two posts and a bar, the " +
4
+ "disc hanging from two cords, its rings and boss.");
5
+ export const brazierProvenance = original("A brazier drawn from geometry: a bowl on three legs with flames.");
6
+ export const candleProvenance = original("A candle on a candlestick, drawn from geometry, its flame lit.");
7
+ /** Every art module exports its provenance; these three share a module. */
8
+ export const provenance = [gongProvenance, brazierProvenance, candleProvenance];
9
+ const ink = PALETTE.ink;
10
+ /** A gong (`item(kind="gong")`), the Portal's, 100 × 100. */
11
+ export const gongArt = {
12
+ Component: () => (_jsxs(_Fragment, { children: [_jsx("path", { d: "M-40,46V-42M40,46V-42M-46,-42H46M-48,46H-32M32,46H48", stroke: ink, strokeWidth: 6, strokeLinecap: "round", fill: "none" }), _jsx("path", { d: "M-12,-42L-10,-25M12,-42L10,-25", stroke: ink, strokeWidth: ITEM_DETAIL, fill: "none" }), _jsx("circle", { cy: 4, r: 30, fill: PALETTE.bronze, stroke: ink, strokeWidth: ITEM_OUTLINE.strokeWidth }), _jsx("circle", { cy: 4, r: 20, fill: "none", stroke: ink, strokeWidth: ITEM_DETAIL }), _jsx("circle", { cy: 4, r: 8, fill: PALETTE.gold, stroke: ink, strokeWidth: ITEM_DETAIL })] })),
13
+ box: { width: 100, height: 100 },
14
+ variant: sameForEveryNode,
15
+ provenance: gongProvenance,
16
+ };
17
+ /** Three tongues of flame, outer red and inner yellow. */
18
+ const FLAMES = [
19
+ [-22, 0.8],
20
+ [0, 1],
21
+ [22, 0.8],
22
+ ];
23
+ /** A brazier (`item(kind="brazier")`): a bowl of fire on legs, 100 × 100. */
24
+ export const brazierArt = {
25
+ Component: () => (_jsxs(_Fragment, { children: [_jsx("path", { d: "M-26,14L-34,46M0,20V46M26,14L34,46", stroke: ink, strokeWidth: 4, strokeLinecap: "round" }), FLAMES.map(([x, k]) => (_jsxs("g", { transform: `translate(${x} -8) scale(${k})`, children: [_jsx("path", { d: "M0,-42C14,-24 14,-8 0,0C-14,-8 -14,-24 0,-42Z", fill: PALETTE.fire, stroke: ink, strokeWidth: ITEM_DETAIL }), _jsx("path", { d: "M0,-24C7,-14 7,-6 0,-2C-7,-6 -7,-14 0,-24Z", fill: PALETTE.flame })] }, x))), _jsx("path", { d: "M-44,-8H44A44,28 0 0 1 -44,-8Z", fill: PALETTE.bronze, ...ITEM_OUTLINE })] })),
26
+ box: { width: 100, height: 100 },
27
+ variant: sameForEveryNode,
28
+ provenance: brazierProvenance,
29
+ };
30
+ /** A candle (`item(kind="candle")`) on its stick, 40 × 100. */
31
+ export const candleArt = {
32
+ Component: () => (_jsxs(_Fragment, { children: [_jsx("rect", { x: -18, y: 40, width: 36, height: 8, fill: PALETTE.bronze, stroke: ink, strokeWidth: ITEM_OUTLINE.strokeWidth }), _jsx("rect", { x: -11, y: 30, width: 22, height: 10, fill: PALETTE.bronze, stroke: ink, strokeWidth: ITEM_OUTLINE.strokeWidth }), _jsx("rect", { x: -7, y: -22, width: 14, height: 52, fill: PALETTE.wax, stroke: ink, strokeWidth: ITEM_OUTLINE.strokeWidth }), _jsx("path", { d: "M0,-22V-28", stroke: ink, strokeWidth: ITEM_DETAIL }), _jsx("path", { d: "M0,-50C8,-38 7,-30 0,-27C-7,-30 -8,-38 0,-50Z", fill: PALETTE.flame, stroke: PALETTE.fire, strokeWidth: ITEM_DETAIL })] })),
33
+ box: { width: 40, height: 100 },
34
+ variant: sameForEveryNode,
35
+ provenance: candleProvenance,
36
+ };
@@ -0,0 +1,49 @@
1
+ /** SVG `points` for a polygon, rounded so server and browser agree. */
2
+ export declare function points(list: readonly (readonly [number, number])[]): string;
3
+ /**
4
+ * An equilateral triangle of circumradius `r` with its centroid on the
5
+ * origin, pointing up or down.
6
+ */
7
+ export declare function triangle(r: number, dir: "up" | "down"): string;
8
+ /** A point in an art's units. */
9
+ export type Point = readonly [x: number, y: number];
10
+ /**
11
+ * One segment of a profile: a line, a cubic (`c1`, `c2`) or a quadratic
12
+ * (`q`) Bézier to `to`.
13
+ */
14
+ export type Segment = {
15
+ to: Point;
16
+ } | {
17
+ c1: Point;
18
+ c2: Point;
19
+ to: Point;
20
+ } | {
21
+ q: Point;
22
+ to: Point;
23
+ };
24
+ /**
25
+ * A closed outline symmetric about the vertical axis, from its right half
26
+ * as a lathe profile: `start` and the last point lie on the axis, and the
27
+ * left half is the right one mirrored and walked back. Vessels are drawn
28
+ * this way.
29
+ */
30
+ export declare function mirrored(start: Point, segments: readonly Segment[]): string;
31
+ /**
32
+ * A smooth open path through points (Catmull–Rom as cubic Béziers), to
33
+ * `decimals` places (two unless a small glyph needs fewer bytes). With
34
+ * `from` and `to`, only that stretch of it, between those points, along
35
+ * exactly the same curve as the whole path.
36
+ */
37
+ export declare function smoothPath(list: readonly Point[], decimals?: number, from?: number, to?: number): string;
38
+ /**
39
+ * The point `r` from `centre` at `degrees`, measured clockwise from East
40
+ * on the screen (y down).
41
+ */
42
+ export declare function polar(r: number, degrees: number, center?: Point): readonly [number, number];
43
+ /** A point as path data (`x,y`), to two decimals. */
44
+ export declare const pathPoint: ([x, y]: Point) => string;
45
+ /**
46
+ * A path's x coordinates negated: the drawing mirrored left to right. Only
47
+ * for absolute commands whose numbers come in `x,y` pairs (M, L, C, Q).
48
+ */
49
+ export declare function flipped(d: string): string;
@@ -0,0 +1,97 @@
1
+ import { svgCoordinate } from "../../../svgCoordinate.js";
2
+ /** SVG `points` for a polygon, rounded so server and browser agree. */
3
+ export function points(list) {
4
+ return list
5
+ .map(([x, y]) => `${svgCoordinate(x)},${svgCoordinate(y)}`)
6
+ .join(" ");
7
+ }
8
+ /**
9
+ * An equilateral triangle of circumradius `r` with its centroid on the
10
+ * origin, pointing up or down.
11
+ */
12
+ export function triangle(r, dir) {
13
+ const s = dir === "up" ? -1 : 1;
14
+ const half = r * Math.sin(Math.PI / 3);
15
+ return points([
16
+ [0, s * r],
17
+ [-half, (-s * r) / 2],
18
+ [half, (-s * r) / 2],
19
+ ]);
20
+ }
21
+ /** A coordinate to two decimals: enough for a 100-unit drawing, and short. */
22
+ const short = (value) => Math.round(value * 100) / 100 + 0;
23
+ const pair = ([x, y]) => `${short(x)},${short(y)}`;
24
+ const mirror = ([x, y]) => [-x, y];
25
+ function command(segment) {
26
+ if ("c1" in segment)
27
+ return `C${pair(segment.c1)} ${pair(segment.c2)} ${pair(segment.to)}`;
28
+ if ("q" in segment)
29
+ return `Q${pair(segment.q)} ${pair(segment.to)}`;
30
+ return `L${pair(segment.to)}`;
31
+ }
32
+ /**
33
+ * A closed outline symmetric about the vertical axis, from its right half
34
+ * as a lathe profile: `start` and the last point lie on the axis, and the
35
+ * left half is the right one mirrored and walked back. Vessels are drawn
36
+ * this way.
37
+ */
38
+ export function mirrored(start, segments) {
39
+ const from = [start, ...segments.map((segment) => segment.to)];
40
+ const left = segments
41
+ .map((segment, index) => {
42
+ const back = mirror(from[index]);
43
+ if ("c1" in segment)
44
+ return `C${pair(mirror(segment.c2))} ${pair(mirror(segment.c1))} ${pair(back)}`;
45
+ if ("q" in segment)
46
+ return `Q${pair(mirror(segment.q))} ${pair(back)}`;
47
+ return `L${pair(back)}`;
48
+ })
49
+ .reverse();
50
+ return `M${pair(start)}${segments.map(command).join("")}${left.join("")}Z`;
51
+ }
52
+ /**
53
+ * A smooth open path through points (Catmull–Rom as cubic Béziers), to
54
+ * `decimals` places (two unless a small glyph needs fewer bytes). With
55
+ * `from` and `to`, only that stretch of it, between those points, along
56
+ * exactly the same curve as the whole path.
57
+ */
58
+ export function smoothPath(list, decimals = 2, from = 0, to = list.length - 1) {
59
+ const at = (index) => list[Math.min(list.length - 1, Math.max(0, index))];
60
+ const scale = 10 ** decimals;
61
+ const round = (value) => Math.round(value * scale) / scale + 0;
62
+ const pair = ([x, y]) => `${round(x)},${round(y)}`;
63
+ let d = `M${pair(list[from])}`;
64
+ for (let i = from; i < to; i++) {
65
+ const [p0, p1, p2, p3] = [at(i - 1), at(i), at(i + 1), at(i + 2)];
66
+ const c1 = [
67
+ p1[0] + (p2[0] - p0[0]) / 6,
68
+ p1[1] + (p2[1] - p0[1]) / 6,
69
+ ];
70
+ const c2 = [
71
+ p2[0] - (p3[0] - p1[0]) / 6,
72
+ p2[1] - (p3[1] - p1[1]) / 6,
73
+ ];
74
+ d += `C${pair(c1)} ${pair(c2)} ${pair(p2)}`;
75
+ }
76
+ return d;
77
+ }
78
+ /**
79
+ * The point `r` from `centre` at `degrees`, measured clockwise from East
80
+ * on the screen (y down).
81
+ */
82
+ export function polar(r, degrees, center = [0, 0]) {
83
+ const angle = (degrees * Math.PI) / 180;
84
+ return [
85
+ center[0] + r * Math.cos(angle),
86
+ center[1] + r * Math.sin(angle),
87
+ ];
88
+ }
89
+ /** A point as path data (`x,y`), to two decimals. */
90
+ export const pathPoint = pair;
91
+ /**
92
+ * A path's x coordinates negated: the drawing mirrored left to right. Only
93
+ * for absolute commands whose numbers come in `x,y` pairs (M, L, C, Q).
94
+ */
95
+ export function flipped(d) {
96
+ return d.replace(/(-?[\d.]+),(-?[\d.]+)/g, (_, x, y) => `${short(-x)},${y}`);
97
+ }
@@ -0,0 +1,10 @@
1
+ import type { HallArt } from "../types.ts";
2
+ export declare const provenance: {
3
+ origin: "original" | "thirdParty";
4
+ author: string;
5
+ license: string;
6
+ source?: string;
7
+ notes?: string;
8
+ };
9
+ /** A Hebrew-letter banner, 100 × 92 units. */
10
+ export declare const hebrewLetterArt: HallArt;
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { svgCoordinate } from "../../../svgCoordinate.js";
3
+ import { stringAttr } from "../attributes.js";
4
+ import { GD_HALL_FONT_STACKS } from "../fonts.js";
5
+ import { hebrewLetter } from "../hebrewLetters.js";
6
+ import { hebrewLetterBody } from "../labels.js";
7
+ import { pennantPath, Rod } from "./banner.js";
8
+ import { original, PALETTE, variantOf } from "./shared.js";
9
+ export const provenance = {
10
+ ...original("Gadi Cohen's own letter banner design: a light pennant on a rod " +
11
+ "with knobs, the letter " +
12
+ "set in Frank Ruhl Libre Bold (SIL OFL 1.1) by the browser; no glyph " +
13
+ "outlines are copied into the code."),
14
+ };
15
+ const TOP = -38;
16
+ /** The letter's size, and where the middle of its body stands. */
17
+ const LETTER_SIZE = 62;
18
+ const LETTER_MIDDLE = 1;
19
+ /** The baseline that centres the letter's body (from the font) there. */
20
+ const BASELINE = LETTER_MIDDLE +
21
+ (LETTER_SIZE * (hebrewLetterBody.top - hebrewLetterBody.bottom)) / 2;
22
+ /** The letter drawn: one of the 22, whatever spelling named it. */
23
+ const letterOf = (node) => {
24
+ const name = stringAttr(node, "letter", 40);
25
+ return name === undefined ? undefined : hebrewLetter(name);
26
+ };
27
+ function HebrewLetter({ node, defId }) {
28
+ const letter = letterOf(node);
29
+ const fill = defId("fill");
30
+ return (_jsxs(_Fragment, { children: [_jsx("defs", { children: _jsxs("linearGradient", { id: fill, x1: -38, x2: 38, y1: 0, y2: 0, gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { offset: 0, stopColor: PALETTE.bannerLightFrom }), _jsx("stop", { offset: 1, stopColor: PALETTE.bannerLightTo })] }) }), _jsx(Rod, { y: TOP }), _jsx("path", { d: pennantPath(TOP, 26, 45), fill: `url(#${fill})`, stroke: PALETTE.ink, strokeWidth: 0.8 }), letter && (_jsx("text", { x: 0, y: svgCoordinate(BASELINE), fontSize: LETTER_SIZE, fontFamily: GD_HALL_FONT_STACKS.hebrew, fontWeight: 700, textAnchor: "middle", fill: PALETTE.ink, children: letter }))] }));
31
+ }
32
+ /** A Hebrew-letter banner, 100 × 92 units. */
33
+ export const hebrewLetterArt = {
34
+ Component: HebrewLetter,
35
+ box: { width: 100, height: 92 },
36
+ variant: (node) => variantOf(letterOf(node)),
37
+ provenance,
38
+ };
@@ -0,0 +1,7 @@
1
+ import type { HallArtRegistry } from "../types.ts";
2
+ /**
3
+ * The package's own art, all original (MIT). The app composes its art over
4
+ * this — `new Map([...DEFAULT_HALL_ART, ["tablet", tabletArt(font)]])` — and
5
+ * anything still missing draws as a placeholder.
6
+ */
7
+ export declare const DEFAULT_HALL_ART: HallArtRegistry;
@@ -0,0 +1,61 @@
1
+ import { altarArt } from "./altar.js";
2
+ import { breadArt, fanArt, roseArt, saltArt } from "./altarItems.js";
3
+ import { bannerArt } from "./banner.js";
4
+ import { boardArt } from "./board.js";
5
+ import { cardArt } from "./cards.js";
6
+ import { brazierArt, candleArt, gongArt } from "./furnishings.js";
7
+ import { hebrewLetterArt } from "./hebrewLetter.js";
8
+ import { crossArt, pentagramArt, triangleArt } from "./items.js";
9
+ import { kameaArt, sealArt } from "./kamea.js";
10
+ import { lamenArt } from "./lamen.js";
11
+ import { lightningArt } from "./lightning.js";
12
+ import { lampArt, lanternArt } from "./lights.js";
13
+ import { markerArt } from "./marker.js";
14
+ import { pantacleArt } from "./pantacle.js";
15
+ import { pillarArt } from "./pillar.js";
16
+ import { platformArt, throneArt } from "./platform.js";
17
+ import { candlestickArt, shewbreadArt, tabletArt } from "./symbols.js";
18
+ import { tarotKeyArt } from "./tarotKey.js";
19
+ import { veilArt } from "./veil.js";
20
+ import { censerArt, chaliceArt, cupArt } from "./vessels.js";
21
+ /**
22
+ * The package's own art, all original (MIT). The app composes its art over
23
+ * this — `new Map([...DEFAULT_HALL_ART, ["tablet", tabletArt(font)]])` — and
24
+ * anything still missing draws as a placeholder.
25
+ */
26
+ export const DEFAULT_HALL_ART = new Map([
27
+ ["altar", altarArt],
28
+ ["platform", platformArt],
29
+ ["throne", throneArt],
30
+ ["board", boardArt],
31
+ ["pillar", pillarArt],
32
+ ["banner", bannerArt],
33
+ ["hebrewLetter", hebrewLetterArt],
34
+ ["marker", markerArt],
35
+ ["lamen", lamenArt],
36
+ ["item:cross", crossArt],
37
+ ["item:triangle", triangleArt],
38
+ ["item:pentagram", pentagramArt],
39
+ ["item:pantacle", pantacleArt],
40
+ ["item:lightning", lightningArt],
41
+ ["item:gong", gongArt],
42
+ ["item:brazier", brazierArt],
43
+ ["item:candle", candleArt],
44
+ ["item:cup", cupArt],
45
+ ["item:chalice", chaliceArt],
46
+ ["item:censer", censerArt],
47
+ ["item:lamp", lampArt],
48
+ ["item:lantern", lanternArt],
49
+ ["item:rose", roseArt],
50
+ ["item:salt", saltArt],
51
+ ["item:bread", breadArt],
52
+ ["item:fan", fanArt],
53
+ ["tarotKey", tarotKeyArt],
54
+ ["card", cardArt],
55
+ ["tablet", tabletArt()],
56
+ ["shewbread", shewbreadArt],
57
+ ["candlestick", candlestickArt],
58
+ ["veil", veilArt],
59
+ ["kamea", kameaArt],
60
+ ["seal", sealArt],
61
+ ]);
@@ -0,0 +1,12 @@
1
+ import type { HallArt } from "../types.ts";
2
+ export declare const crossProvenance: import("../types.ts").HallArtProvenance;
3
+ export declare const triangleProvenance: import("../types.ts").HallArtProvenance;
4
+ export declare const pentagramProvenance: import("../types.ts").HallArtProvenance;
5
+ /** Every art module exports its provenance; the items share these. */
6
+ export declare const provenance: import("../types.ts").HallArtProvenance[];
7
+ /** A cross; `form` picks the shape, `fill` and `stroke` its colours. */
8
+ export declare const crossArt: HallArt;
9
+ /** A triangle pointing up or down (`dir`), outlined white by default. */
10
+ export declare const triangleArt: HallArt;
11
+ /** A pentagram, point up unless `dir="down"`. */
12
+ export declare const pentagramArt: HallArt;
@@ -0,0 +1,125 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { enumAttr } from "../attributes.js";
3
+ import { CROSS_FORMS, HALL_COLOR_NAMES, HALL_COLORS, hallColor, } from "../vocabulary.js";
4
+ import { points } from "./geometry.js";
5
+ import { original, variantOf } from "./shared.js";
6
+ /** A named colour from the node, or the art's default; never raw CSS. */
7
+ const color = (node, name, fallback) => HALL_COLORS.get(hallColor(enumAttr(node, name, HALL_COLOR_NAMES)) ?? fallback);
8
+ const direction = (node) => enumAttr(node, "dir", ["up", "down"]) ?? "up";
9
+ export const crossProvenance = original("Crosses drawn from geometry: Latin, Calvary (on three steps), Greek, " +
10
+ "Greek of five squares, and of four triangles.");
11
+ export const triangleProvenance = original("An equilateral triangle.");
12
+ export const pentagramProvenance = original("A five-pointed star polygon.");
13
+ /** Every art module exports its provenance; the items share these. */
14
+ export const provenance = [
15
+ crossProvenance,
16
+ triangleProvenance,
17
+ pentagramProvenance,
18
+ ];
19
+ const CROSS_BOXES = new Map([
20
+ ["latin", { width: 60, height: 100 }],
21
+ ["calvary", { width: 60, height: 100 }],
22
+ ["greek", { width: 100, height: 100 }],
23
+ ["greekFiveSquares", { width: 100, height: 100 }],
24
+ ["fourTriangles", { width: 100, height: 100 }],
25
+ ]);
26
+ const crossForm = (node) => enumAttr(node, "form", CROSS_FORMS) ?? "latin";
27
+ const CROSS_PATHS = new Map([
28
+ ["latin", ["M-8,-50H8V-28H30V-12H8V50H-8V-12H-30V-28H-8Z"]],
29
+ [
30
+ "calvary",
31
+ [
32
+ "M-7,-50H7V-34H22V-20H7V14H-7V-20H-22V-34H-7Z",
33
+ "M-14,14H14V26H-14Z",
34
+ "M-22,26H22V38H-22Z",
35
+ "M-30,38H30V50H-30Z",
36
+ ],
37
+ ],
38
+ ["greek", ["M-15,-50H15V-15H50V15H15V50H-15V15H-50V-15H-15Z"]],
39
+ [
40
+ "greekFiveSquares",
41
+ [
42
+ [-1, 0],
43
+ [0, -1],
44
+ [0, 0],
45
+ [0, 1],
46
+ [1, 0],
47
+ ].map(([i, j]) => {
48
+ const x = i * 33 - 16.5;
49
+ const y = j * 33 - 16.5;
50
+ return `M${x},${y}h33v33h-33Z`;
51
+ }),
52
+ ],
53
+ [
54
+ "fourTriangles",
55
+ [
56
+ points([
57
+ [-30, -50],
58
+ [30, -50],
59
+ [0, -4],
60
+ ]),
61
+ points([
62
+ [50, -30],
63
+ [50, 30],
64
+ [4, 0],
65
+ ]),
66
+ points([
67
+ [30, 50],
68
+ [-30, 50],
69
+ [0, 4],
70
+ ]),
71
+ points([
72
+ [-50, 30],
73
+ [-50, -30],
74
+ [-4, 0],
75
+ ]),
76
+ ].map((list) => `M${list}Z`),
77
+ ],
78
+ ]);
79
+ function Cross({ node }) {
80
+ return (_jsx(_Fragment, { children: CROSS_PATHS.get(crossForm(node)).map((d) => (_jsx("path", { d: d, fill: color(node, "fill", "red"), stroke: color(node, "stroke", "yellow"), strokeWidth: 3, strokeLinejoin: "miter" }, d))) }));
81
+ }
82
+ /** A cross; `form` picks the shape, `fill` and `stroke` its colours. */
83
+ export const crossArt = {
84
+ Component: Cross,
85
+ box: (node) => CROSS_BOXES.get(crossForm(node)),
86
+ variant: (node) => variantOf(crossForm(node), color(node, "fill", "red"), color(node, "stroke", "yellow")),
87
+ provenance: crossProvenance,
88
+ };
89
+ // The triangle's box is its bounding box; its centre is the box's centre.
90
+ const SIDE = 88;
91
+ const HEIGHT = (SIDE * Math.sqrt(3)) / 2;
92
+ function Triangle({ node }) {
93
+ const up = direction(node) === "up";
94
+ const s = up ? 1 : -1;
95
+ return (_jsx("polygon", { points: points([
96
+ [0, (-s * HEIGHT) / 2],
97
+ [SIDE / 2, (s * HEIGHT) / 2],
98
+ [-SIDE / 2, (s * HEIGHT) / 2],
99
+ ]), fill: color(node, "fill", "none"), stroke: color(node, "stroke", "white"), strokeWidth: 11, strokeLinejoin: "miter" }));
100
+ }
101
+ /** A triangle pointing up or down (`dir`), outlined white by default. */
102
+ export const triangleArt = {
103
+ Component: Triangle,
104
+ box: { width: 100, height: 86.6 },
105
+ variant: (node) => variantOf(direction(node), color(node, "fill", "none"), color(node, "stroke", "white")),
106
+ provenance: triangleProvenance,
107
+ };
108
+ // A pentagram's points lie on a circle of radius 50; its bounding box runs
109
+ // from the top point to 50·cos 36° below the centre, so shift it to centre.
110
+ const STAR_SHIFT = (50 - 50 * Math.cos(Math.PI / 5)) / 2;
111
+ function Pentagram({ node }) {
112
+ const s = direction(node) === "up" ? 1 : -1;
113
+ const star = [0, 2, 4, 1, 3].map((i) => {
114
+ const angle = -Math.PI / 2 + (i * 2 * Math.PI) / 5;
115
+ return [50 * Math.cos(angle), s * (50 * Math.sin(angle) + STAR_SHIFT)];
116
+ });
117
+ return (_jsx("polygon", { points: points(star), fill: color(node, "fill", "none"), stroke: color(node, "stroke", "white"), strokeWidth: 5, strokeLinejoin: "miter" }));
118
+ }
119
+ /** A pentagram, point up unless `dir="down"`. */
120
+ export const pentagramArt = {
121
+ Component: Pentagram,
122
+ box: { width: 95.1, height: 90.5 },
123
+ variant: (node) => variantOf(direction(node), color(node, "fill", "none"), color(node, "stroke", "white")),
124
+ provenance: pentagramProvenance,
125
+ };
@@ -0,0 +1,20 @@
1
+ import type { HallArt, HallAttrSpec } from "../types.ts";
2
+ import { sealProvenance } from "./seals.tsx";
3
+ export declare const kameaProvenance: import("../types.ts").HallArtProvenance;
4
+ export { sealProvenance };
5
+ /** Every art module exports its provenance; these two share a module. */
6
+ export declare const provenance: import("../types.ts").HallArtProvenance[];
7
+ /** `planet`: one of the seven. */
8
+ export declare const PLANET_SPEC: HallAttrSpec;
9
+ /**
10
+ * A planet's kamea (`kamea(planet="moon")`), 100 × 100: the square of
11
+ * its order, Saturn 3 × 3 to the Moon 9 × 9. Without a planet, an empty
12
+ * frame.
13
+ */
14
+ export declare const kameaArt: HallArt;
15
+ /**
16
+ * A planet's seals (`seal(planet="moon")`), 100 × 100: the Moon's and
17
+ * Venus' seals after Agrippa (`seals.tsx`); for the other planets, until
18
+ * theirs are drawn, a dashed ring with "Seals of Sol" in it.
19
+ */
20
+ export declare const sealArt: HallArt;
@@ -0,0 +1,64 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { KameaFigure } from "../../../astrology/Kamea.js";
3
+ import { svgCoordinate } from "../../../svgCoordinate.js";
4
+ import { enumAttr } from "../attributes.js";
5
+ import { GD_HALL_FONT_STACKS } from "../fonts.js";
6
+ import { wrapText } from "../labels.js";
7
+ import { HALL_KAMEA_PLANET_IDS, HALL_PLANET_NAMES, HALL_PLANETS, } from "../planets.js";
8
+ import { SEALS, sealProvenance } from "./seals.js";
9
+ import { original, PALETTE, variantOf } from "./shared.js";
10
+ export const kameaProvenance = original("A planet's magic square drawn from its numbers, which magick-data " +
11
+ "computes (astrology/kameas): the shared Kamea component's figure, a " +
12
+ "grid with each number in its cell.");
13
+ export { sealProvenance };
14
+ /** Every art module exports its provenance; these two share a module. */
15
+ export const provenance = [kameaProvenance, sealProvenance];
16
+ /** `planet`: one of the seven. */
17
+ export const PLANET_SPEC = { kind: "enum", values: HALL_PLANETS };
18
+ const planetOf = (node) => enumAttr(node, "planet", HALL_PLANETS);
19
+ /**
20
+ * The shared `KameaFigure` in the hall's fonts and palette. Its square is
21
+ * 96 units across, inside the art's 100 × 100 box.
22
+ */
23
+ function Kamea({ node }) {
24
+ const planet = planetOf(node);
25
+ return (_jsx(KameaFigure, { planet: planet && HALL_KAMEA_PLANET_IDS.get(planet), fontFamily: GD_HALL_FONT_STACKS.serif, paper: PALETTE.paper, ink: PALETTE.ink }));
26
+ }
27
+ /**
28
+ * A planet's kamea (`kamea(planet="moon")`), 100 × 100: the square of
29
+ * its order, Saturn 3 × 3 to the Moon 9 × 9. Without a planet, an empty
30
+ * frame.
31
+ */
32
+ export const kameaArt = {
33
+ Component: Kamea,
34
+ box: { width: 100, height: 100 },
35
+ attributes: new Map([["planet", PLANET_SPEC]]),
36
+ // One of seven squares, or the empty frame.
37
+ variant: (node) => variantOf(planetOf(node)),
38
+ provenance: kameaProvenance,
39
+ };
40
+ const SEAL_SIZE = 13;
41
+ const SEAL_WIDTH = 64;
42
+ function Seal({ node }) {
43
+ const planet = planetOf(node);
44
+ const Drawn = planet && SEALS.get(planet);
45
+ if (Drawn)
46
+ return _jsx(Drawn, {});
47
+ const name = planet && HALL_PLANET_NAMES.get(planet);
48
+ const lines = name ? wrapText(`Seals of ${name}`, SEAL_WIDTH, SEAL_SIZE) : [];
49
+ const advance = SEAL_SIZE * 1.2;
50
+ const first = SEAL_SIZE * 0.36 - ((lines.length - 1) * advance) / 2;
51
+ return (_jsxs(_Fragment, { children: [_jsx("circle", { r: 47, fill: PALETTE.paper, stroke: PALETTE.placeholder, strokeWidth: 2.5, strokeDasharray: "7 5" }), _jsx("circle", { r: 39, fill: "none", stroke: PALETTE.placeholder, strokeWidth: 1 }), _jsx("g", { fill: PALETTE.placeholder, fontFamily: GD_HALL_FONT_STACKS.serif, fontStyle: "italic", fontSize: SEAL_SIZE, textAnchor: "middle", style: { fontVariantLigatures: "none", fontKerning: "normal" }, children: lines.map((line, index) => (_jsx("text", { y: svgCoordinate(first + index * advance), children: line.text }, index))) })] }));
52
+ }
53
+ /**
54
+ * A planet's seals (`seal(planet="moon")`), 100 × 100: the Moon's and
55
+ * Venus' seals after Agrippa (`seals.tsx`); for the other planets, until
56
+ * theirs are drawn, a dashed ring with "Seals of Sol" in it.
57
+ */
58
+ export const sealArt = {
59
+ Component: Seal,
60
+ box: { width: 100, height: 100 },
61
+ attributes: new Map([["planet", PLANET_SPEC]]),
62
+ variant: (node) => variantOf(planetOf(node)),
63
+ provenance: sealProvenance,
64
+ };
@@ -0,0 +1,9 @@
1
+ import type { HallArt, HallAttrSpec } from "../types.ts";
2
+ export declare const provenance: import("../types.ts").HallArtProvenance;
3
+ /**
4
+ * `grade`: the grade whose lamen an officer wears, for the officers who
5
+ * wear another in it (the Portal's Hiereus and Hegemon, stage H, part 2).
6
+ */
7
+ export declare const GRADE_SPEC: HallAttrSpec;
8
+ /** The officers' lamens (plan 061, decision 9). */
9
+ export declare const lamenArt: HallArt;
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Lamen, { LAMEN_OFFICERS } from "../../Lamen.js";
3
+ import { hasGradeLamen, LAMEN_GRADES } from "../../lamenGrades.js";
4
+ import { enumAttr, stringAttr } from "../attributes.js";
5
+ import { original, PALETTE } from "./shared.js";
6
+ export const provenance = original("The officers' lamens, drawn by `Lamen` (gd/Lamen.tsx): " +
7
+ "the collar's ring, the disc and the officer's glyph; a plain circle " +
8
+ "for an officer without a role.");
9
+ /**
10
+ * Whether a node draws the plain circle: without a role, as the validator
11
+ * promises. Every hall role has its lamen since stage H, part 2 (the
12
+ * adepts' were labelled circles before); any other role draws through
13
+ * `Lamen` as its plain lamen.
14
+ */
15
+ const plainCircle = (role) => role === undefined || role === "";
16
+ const roleOf = (node) => stringAttr(node, "role", 200);
17
+ /**
18
+ * `grade`: the grade whose lamen an officer wears, for the officers who
19
+ * wear another in it (the Portal's Hiereus and Hegemon, stage H, part 2).
20
+ */
21
+ export const GRADE_SPEC = { kind: "enum", values: LAMEN_GRADES };
22
+ /** The grade a node's lamen is drawn for: only one that changes it. */
23
+ const gradeOf = (node, role) => {
24
+ const grade = enumAttr(node, "grade", LAMEN_GRADES);
25
+ return grade !== undefined && hasGradeLamen(role, grade) ? grade : undefined;
26
+ };
27
+ /** An officer's lamen in its 100 × 100 box, centred, or the plain circle. */
28
+ function HallLamen({ node }) {
29
+ const role = roleOf(node);
30
+ if (plainCircle(role))
31
+ return (_jsx("circle", { r: 47, fill: PALETTE.paper, stroke: PALETTE.ink, strokeWidth: 6 }));
32
+ return (_jsx("g", { transform: "translate(-50 -50)", children: _jsx(Lamen, { officer: role, grade: gradeOf(node, role), width: 100, height: 100 }) }));
33
+ }
34
+ /** The officers' lamens (plan 061, decision 9). */
35
+ export const lamenArt = {
36
+ Component: HallLamen,
37
+ box: { width: 100, height: 100 },
38
+ // 1.6 squares in an officer's 2-square cell (layout.ts, DEFAULT_SCALES).
39
+ inset: 0.8,
40
+ attributes: new Map([["grade", GRADE_SPEC]]),
41
+ // A role `Lamen` does not know draws its plain lamen, whatever the name.
42
+ variant: (node) => {
43
+ const role = roleOf(node);
44
+ if (plainCircle(role))
45
+ return "";
46
+ if (!LAMEN_OFFICERS.has(role))
47
+ return "?";
48
+ const grade = gradeOf(node, role);
49
+ return grade ? `${grade}:${role}` : role;
50
+ },
51
+ provenance,
52
+ };
@@ -0,0 +1,13 @@
1
+ import type { HallArt } from "../types.ts";
2
+ export declare const provenance: {
3
+ origin: "original" | "thirdParty";
4
+ author: string;
5
+ license: string;
6
+ source?: string;
7
+ notes?: string;
8
+ };
9
+ /**
10
+ * The Flaming Sword, the lightning flash down the Tree
11
+ * (`item(kind="lightning")`), black unless `stroke` names a colour.
12
+ */
13
+ export declare const lightningArt: HallArt;
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { enumAttr } from "../attributes.js";
3
+ import { HALL_COLOR_NAMES, HALL_COLORS, hallColor } from "../vocabulary.js";
4
+ import { points } from "./geometry.js";
5
+ import { original, PALETTE, variantOf } from "./shared.js";
6
+ export const provenance = {
7
+ ...original("The Flaming Sword as a zig-zag, after Gadi Cohen's own design, with " +
8
+ "the arrowhead drawn as a triangle instead of an SVG marker."),
9
+ };
10
+ const STROKE = 3.8;
11
+ const ZIGZAG = [
12
+ [0.1, -48.1],
13
+ [20.4, -36.3],
14
+ [-20.6, -36.4],
15
+ [20.4, -13.4],
16
+ [-20.6, -13.8],
17
+ [20.6, 10],
18
+ [-19.9, 9.9],
19
+ [1.1, 21.6],
20
+ [1.4, 40.2],
21
+ ];
22
+ /** `stroke` names a colour, so the flash shows on the black altar too. */
23
+ const inkOf = (node) => {
24
+ const name = hallColor(enumAttr(node, "stroke", HALL_COLOR_NAMES));
25
+ return name === undefined ? PALETTE.ink : HALL_COLORS.get(name);
26
+ };
27
+ function Lightning({ node }) {
28
+ const ink = inkOf(node);
29
+ return (_jsxs("g", { stroke: ink, strokeWidth: STROKE, fill: "none", children: [_jsx("polyline", { points: points(ZIGZAG), strokeLinejoin: "miter" }), _jsx("line", { x1: 11, y1: -47.8, x2: 5.8, y2: -38.6 }), _jsx("polygon", { points: points([
30
+ [1.5, 50],
31
+ [-4.3, 40.3],
32
+ [7, 40.1],
33
+ ]), fill: ink, stroke: "none" })] }));
34
+ }
35
+ /**
36
+ * The Flaming Sword, the lightning flash down the Tree
37
+ * (`item(kind="lightning")`), black unless `stroke` names a colour.
38
+ */
39
+ export const lightningArt = {
40
+ Component: Lightning,
41
+ box: { width: 45.1, height: 100 },
42
+ variant: (node) => variantOf(inkOf(node)),
43
+ provenance,
44
+ };