@openephemeris/mcp-server 3.12.0 → 3.13.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.
@@ -0,0 +1,633 @@
1
+ /**
2
+ * bodygraph-app.ts — MCP App tool registration for the Human Design Bodygraph Explorer.
3
+ *
4
+ * Registers 4 tools:
5
+ * • explore_human_design — primary entry point, returns data + UI resource [model]
6
+ * • hd_on_center_click — center click handler [app-only]
7
+ * • hd_on_gate_click — gate click handler [app-only]
8
+ * • hd_on_channel_click — channel click handler [app-only]
9
+ *
10
+ * The bodygraph is rendered client-side from structured JSON — no SVG endpoint
11
+ * is called, keeping latency at zero and the architecture consistent with
12
+ * the chart-wheel-app approach.
13
+ *
14
+ * Also exports resource helpers (getBodygraphBundle, etc.) for use in
15
+ * index.ts and server-sse.ts.
16
+ */
17
+ import fs from "node:fs";
18
+ import path from "node:path";
19
+ import { fileURLToPath } from "node:url";
20
+ import { registerTool } from "../index.js";
21
+ import { getActiveClient } from "../../backend/client.js";
22
+ // ── Constants ─────────────────────────────────────────────────────────────
23
+ export const BODYGRAPH_RESOURCE_URI = "ui://openephemeris/bodygraph";
24
+ export const BODYGRAPH_MIME_TYPE = "text/html;profile=mcp-app";
25
+ const here = path.dirname(fileURLToPath(import.meta.url));
26
+ const BUNDLE_PATHS = [
27
+ path.resolve(here, "..", "..", "..", "dist", "ui", "bodygraph.html"),
28
+ ];
29
+ function findBundlePath() {
30
+ for (const p of BUNDLE_PATHS) {
31
+ if (fs.existsSync(p))
32
+ return p;
33
+ }
34
+ return null;
35
+ }
36
+ let cachedBundle = null;
37
+ /** Read the pre-built HTML bundle. Returns null if not yet built. */
38
+ export function getBodygraphBundle() {
39
+ if (cachedBundle)
40
+ return cachedBundle;
41
+ const bundlePath = findBundlePath();
42
+ if (!bundlePath)
43
+ return null;
44
+ try {
45
+ cachedBundle = fs.readFileSync(bundlePath, "utf-8");
46
+ return cachedBundle;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ /** Reset cache (useful in dev watch mode or tests). */
53
+ export function clearBodygraphBundleCache() {
54
+ cachedBundle = null;
55
+ }
56
+ // ── Helpers ──────────────────────────────────────────────────────────────
57
+ function capitalize(s) {
58
+ return s.charAt(0).toUpperCase() + s.slice(1);
59
+ }
60
+ /** Ensure datetime has a UTC offset for Go time.Time parsing. */
61
+ function ensureTimezone(dt) {
62
+ if (!dt)
63
+ return dt;
64
+ if (/[Zz]$/.test(dt) || /[+-]\d{2}:\d{2}$/.test(dt))
65
+ return dt;
66
+ return dt + "Z";
67
+ }
68
+ const CENTER_ORDER = [
69
+ "Head", "Ajna", "Throat", "G", "Sacral",
70
+ "Heart", "Spleen", "Solar Plexus", "Root",
71
+ ];
72
+ // Alternative center name spellings the API might return
73
+ const CENTER_NAME_ALIASES = {
74
+ "self": "G",
75
+ "g center": "G",
76
+ "g-center": "G",
77
+ "ego": "Heart",
78
+ "heart": "Heart",
79
+ "will": "Heart",
80
+ "solar plexus": "Solar Plexus",
81
+ "emotional": "Solar Plexus",
82
+ "sp": "Solar Plexus",
83
+ "spleen": "Spleen",
84
+ "splenic": "Spleen",
85
+ "esp": "Solar Plexus",
86
+ "root": "Root",
87
+ "sacral": "Sacral",
88
+ "throat": "Throat",
89
+ "ajna": "Ajna",
90
+ "head": "Head",
91
+ };
92
+ function normalizeCenterName(raw) {
93
+ const lower = raw.toLowerCase().trim();
94
+ return CENTER_NAME_ALIASES[lower] ?? capitalize(raw.trim());
95
+ }
96
+ /**
97
+ * Extract valid gate numbers (1–64) from any gate-array shape the API might return.
98
+ * Hoisted to module scope to avoid per-call function allocation.
99
+ */
100
+ function extractGateNums(arr) {
101
+ if (!Array.isArray(arr))
102
+ return [];
103
+ return arr
104
+ .map((g) => typeof g === "number" ? g : Number(g?.gate ?? g?.number ?? g))
105
+ .filter((n) => Number.isInteger(n) && n >= 1 && n <= 64);
106
+ }
107
+ /**
108
+ * Extract a lean HD model payload (< 2 KB) from the full API response.
109
+ * Strips raw planetary gate arrays; keeps only structural data needed by the UI.
110
+ */
111
+ function buildHdModelPayload(data, birthParams) {
112
+ const type = String((data.type ?? data.hd_type ?? data.energy_type ?? "Unknown"));
113
+ const profile = String(data.profile ?? "");
114
+ const authority = String(data.authority ?? data.inner_authority ?? "");
115
+ const definition = String(data.definition ?? data.definition_type ?? "");
116
+ const incarnation_cross = String(data.incarnation_cross ?? data.cross ?? "");
117
+ // Normalize centers — API may return array or keyed object
118
+ let centers = [];
119
+ const rawCenters = data.centers;
120
+ if (Array.isArray(rawCenters)) {
121
+ centers = rawCenters.map((c) => ({
122
+ name: normalizeCenterName(String(c.name ?? c.center ?? "")),
123
+ defined: Boolean(c.defined ?? c.is_defined),
124
+ }));
125
+ }
126
+ else if (rawCenters && typeof rawCenters === "object") {
127
+ centers = Object.entries(rawCenters).map(([name, val]) => ({
128
+ name: normalizeCenterName(name),
129
+ defined: typeof val === "object" && val !== null
130
+ ? Boolean(val.defined ?? val.is_defined)
131
+ : Boolean(val),
132
+ }));
133
+ }
134
+ // Sort centers by canonical HD order
135
+ centers.sort((a, b) => {
136
+ const ai = CENTER_ORDER.indexOf(a.name);
137
+ const bi = CENTER_ORDER.indexOf(b.name);
138
+ if (ai !== -1 && bi !== -1)
139
+ return ai - bi;
140
+ if (ai !== -1)
141
+ return -1;
142
+ if (bi !== -1)
143
+ return 1;
144
+ return a.name.localeCompare(b.name);
145
+ });
146
+ // Compact active gate list — just gate numbers, no planets
147
+ const rawGates = data.active_gates ?? data.gates ?? data.defined_gates ?? [];
148
+ let active_gates = [];
149
+ if (Array.isArray(rawGates)) {
150
+ active_gates = rawGates
151
+ .map((g) => {
152
+ const n = typeof g === "number" ? g : Number(g?.gate ?? g?.number ?? g);
153
+ return Number.isInteger(n) && n >= 1 && n <= 64 ? n : null;
154
+ })
155
+ .filter((n) => n !== null)
156
+ .filter((n, i, arr) => arr.indexOf(n) === i) // unique
157
+ .sort((a, b) => a - b);
158
+ }
159
+ // Active channels as "gate1-gate2" strings
160
+ const rawChannels = data.active_channels ?? data.channels ?? data.defined_channels ?? [];
161
+ let active_channels = [];
162
+ if (Array.isArray(rawChannels)) {
163
+ active_channels = rawChannels.map((ch) => {
164
+ if (typeof ch === "string")
165
+ return ch;
166
+ const g1 = ch.gate1 ?? ch.from ?? ch.gates?.[0];
167
+ const g2 = ch.gate2 ?? ch.to ?? ch.gates?.[1];
168
+ return g1 != null && g2 != null ? `${g1}-${g2}` : String(ch);
169
+ });
170
+ }
171
+ // Personality / Design gate extraction (API may return multiple field name variants)
172
+ const rawP = data.personality_gates ?? data.personality ?? data.conscious_gates ?? [];
173
+ const rawD = data.design_gates ?? data.unconscious_gates ?? [];
174
+ const personality_gates = [...new Set(extractGateNums(rawP))].sort((a, b) => a - b);
175
+ const design_gates = [...new Set(extractGateNums(rawD))].sort((a, b) => a - b);
176
+ return {
177
+ type,
178
+ profile,
179
+ authority,
180
+ definition,
181
+ incarnation_cross,
182
+ centers,
183
+ active_gates,
184
+ active_channels,
185
+ personality_gates,
186
+ design_gates,
187
+ _birth_params: birthParams,
188
+ };
189
+ }
190
+ /**
191
+ * Format a human-readable summary from a pre-built HdModelPayload.
192
+ * Accepts the payload directly to avoid a redundant buildHdModelPayload call.
193
+ */
194
+ function buildHdSummary(payload, location) {
195
+ const definedList = payload.centers.filter((c) => c.defined).map((c) => c.name);
196
+ const undefinedList = payload.centers.filter((c) => !c.defined).map((c) => c.name);
197
+ return (`**Human Design Chart \u2014 ${location}**\n\n` +
198
+ `Type: **${payload.type}** | Profile: **${payload.profile}** | Authority: **${payload.authority}**\n` +
199
+ `Definition: ${payload.definition} | Cross: ${payload.incarnation_cross}\n\n` +
200
+ `Defined Centers: ${definedList.length > 0 ? definedList.join(", ") : "None"}\n` +
201
+ `Undefined Centers: ${undefinedList.length > 0 ? undefinedList.join(", ") : "None"}\n\n` +
202
+ "Click any center, gate, or channel on the bodygraph for interpretation.");
203
+ }
204
+ // ── Tool: explore_human_design ────────────────────────────────────────────
205
+ registerTool({
206
+ name: "explore_human_design",
207
+ description: "Generate an interactive Human Design Bodygraph with clickable centers, gates, and channels. " +
208
+ "Returns an embedded visual bodygraph explorer that lets you click any center or gate " +
209
+ "for instant Human Design interpretation. " +
210
+ "Shows defined/undefined centers, active gates, channels, Type, Profile, Authority, " +
211
+ "and Incarnation Cross. " +
212
+ "The chart is calculated using NASA JPL DE440 ephemerides for both Personality and Design positions. " +
213
+ "Use this for a rich, interactive HD experience in MCP Apps-capable hosts (Claude Desktop). " +
214
+ "Falls back to a text summary in other hosts.",
215
+ inputSchema: {
216
+ type: "object",
217
+ properties: {
218
+ datetime: {
219
+ type: "string",
220
+ description: "ISO 8601 birth datetime in UTC, e.g. '1990-04-15T19:30:00Z'. " +
221
+ "Human Design is time-sensitive — accuracy to the minute matters. " +
222
+ "Include 'Z' or a timezone offset.",
223
+ },
224
+ latitude: {
225
+ type: "number",
226
+ description: "Birth latitude in decimal degrees (positive = North). Optional for HD charts.",
227
+ },
228
+ longitude: {
229
+ type: "number",
230
+ description: "Birth longitude in decimal degrees (positive = East). Optional for HD charts.",
231
+ },
232
+ location: {
233
+ type: "string",
234
+ description: "Location name for display only (e.g. 'New York, NY').",
235
+ },
236
+ },
237
+ required: ["datetime"],
238
+ },
239
+ annotations: {
240
+ title: "Interactive Human Design Bodygraph Explorer",
241
+ readOnlyHint: true,
242
+ destructiveHint: false,
243
+ idempotentHint: true,
244
+ openWorldHint: false,
245
+ },
246
+ handler: async (args) => {
247
+ const client = getActiveClient();
248
+ const datetime = ensureTimezone(String(args.datetime));
249
+ const location = String(args.location ?? (args.latitude != null ? `${args.latitude}, ${args.longitude}` : "Unknown")).slice(0, 120);
250
+ const body = {
251
+ birth_datetime_utc: datetime,
252
+ };
253
+ if (args.latitude != null)
254
+ body.latitude = args.latitude;
255
+ if (args.longitude != null)
256
+ body.longitude = args.longitude;
257
+ const chartData = await client.request("POST", "/human-design/chart", {
258
+ data: body,
259
+ });
260
+ // Build payload once \u2014 summary and model data both derive from the same object
261
+ const modelPayload = buildHdModelPayload(chartData, {
262
+ datetime,
263
+ location: args.location ?? null,
264
+ });
265
+ const summary = buildHdSummary(modelPayload, location);
266
+ const bundleAvailable = Boolean(getBodygraphBundle());
267
+ if (bundleAvailable) {
268
+ return {
269
+ content: [
270
+ { type: "text", text: summary },
271
+ { type: "text", text: JSON.stringify(modelPayload) },
272
+ {
273
+ type: "resource",
274
+ resource: {
275
+ uri: BODYGRAPH_RESOURCE_URI,
276
+ mimeType: BODYGRAPH_MIME_TYPE,
277
+ text: "[Human Design Bodygraph Explorer UI]",
278
+ },
279
+ },
280
+ ],
281
+ _meta: {
282
+ ui: { resourceUri: BODYGRAPH_RESOURCE_URI },
283
+ },
284
+ };
285
+ }
286
+ // Fallback: text summary only
287
+ return { content: [{ type: "text", text: summary }] };
288
+ },
289
+ });
290
+ // ── Tool: hd_on_center_click ──────────────────────────────────────────────
291
+ registerTool({
292
+ name: "hd_on_center_click",
293
+ description: "Event handler called when the user clicks a center in the Human Design Bodygraph. " +
294
+ "Returns the center's defined or undefined themes, keynotes, biological correlates, " +
295
+ "and circuit associations. " +
296
+ "This tool is called automatically by the bodygraph UI; you do not need to call it directly.",
297
+ inputSchema: {
298
+ type: "object",
299
+ properties: {
300
+ center: {
301
+ type: "string",
302
+ description: "Center name (e.g. 'Head', 'Ajna', 'Throat', 'G', 'Sacral', 'Heart', 'Spleen', 'Solar Plexus', 'Root')",
303
+ },
304
+ defined: {
305
+ type: "boolean",
306
+ description: "Whether the center is defined (colored) or undefined (open/white).",
307
+ },
308
+ },
309
+ required: ["center", "defined"],
310
+ },
311
+ annotations: { title: "Center Interpretation", readOnlyHint: true, openWorldHint: false },
312
+ _meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
313
+ handler: async (args) => {
314
+ const center = String(args.center);
315
+ const defined = Boolean(args.defined);
316
+ const info = HD_CENTER_DATA[center] ?? HD_CENTER_DATA[normalizeCenterName(center)];
317
+ if (!info) {
318
+ return {
319
+ content: [{ type: "text", text: `**${center} Center**\n\nNo interpretation data available for this center.` }],
320
+ };
321
+ }
322
+ const defLine = defined
323
+ ? `**Defined** — ${info.defined_theme}`
324
+ : `**Undefined (Open)** — ${info.undefined_theme}`;
325
+ return {
326
+ content: [{
327
+ type: "text",
328
+ text: `**${center} Center** ${defined ? "🔴" : "⬜"}\n\n` +
329
+ `${defLine}\n\n` +
330
+ `**Keynote:** ${info.keynote}\n\n` +
331
+ `**Biological Correlate:** ${info.biology}\n\n` +
332
+ `**Circuit:** ${info.circuit}\n\n` +
333
+ (defined
334
+ ? `*Defined centers broadcast their energy consistently and reliably into the world.*`
335
+ : `*Open centers receive and amplify external conditioning. They are areas of learning, not weakness.*`),
336
+ }],
337
+ };
338
+ },
339
+ });
340
+ // ── Tool: hd_on_gate_click ────────────────────────────────────────────────
341
+ registerTool({
342
+ name: "hd_on_gate_click",
343
+ description: "Event handler called when the user clicks an active gate in the Human Design Bodygraph. " +
344
+ "Returns the gate's name, I Ching hexagram reference, keynote, and gift/shadow spectrum. " +
345
+ "This tool is called automatically by the bodygraph UI; you do not need to call it directly.",
346
+ inputSchema: {
347
+ type: "object",
348
+ properties: {
349
+ gate: {
350
+ type: "number",
351
+ description: "Gate number (1–64).",
352
+ },
353
+ line: {
354
+ type: "number",
355
+ description: "I Ching line number (1–6). Optional.",
356
+ },
357
+ planet: {
358
+ type: "string",
359
+ description: "Planet activating this gate (e.g. 'sun', 'moon'). Optional.",
360
+ },
361
+ conscious: {
362
+ type: "boolean",
363
+ description: "True if Personality (conscious/black), false if Design (unconscious/red).",
364
+ },
365
+ },
366
+ required: ["gate"],
367
+ },
368
+ annotations: { title: "Gate Interpretation", readOnlyHint: true, openWorldHint: false },
369
+ _meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
370
+ handler: async (args) => {
371
+ const gate = Number(args.gate);
372
+ const line = args.line != null ? Number(args.line) : null;
373
+ const planet = args.planet ? String(args.planet) : null;
374
+ const conscious = args.conscious != null ? Boolean(args.conscious) : null;
375
+ const info = HD_GATE_DATA[gate];
376
+ const lineRef = line ? `.${line}` : "";
377
+ const planetNote = planet ? ` (activated by ${capitalize(planet)})` : "";
378
+ const consciousNote = conscious === true ? " — **Personality** (conscious)" : conscious === false ? " — **Design** (unconscious)" : "";
379
+ if (!info) {
380
+ return {
381
+ content: [{ type: "text", text: `**Gate ${gate}${lineRef}**${planetNote}${consciousNote}\n\nGate data not available.` }],
382
+ };
383
+ }
384
+ return {
385
+ content: [{
386
+ type: "text",
387
+ text: `**Gate ${gate}${lineRef} — ${info.name}**${planetNote}${consciousNote}\n\n` +
388
+ `**I Ching Hexagram:** ${info.hexagram}\n\n` +
389
+ `**Keynote:** ${info.keynote}\n\n` +
390
+ `**Gift:** ${info.gift}\n\n` +
391
+ `**Shadow:** ${info.shadow}\n\n` +
392
+ `**Circuit:** ${info.circuit}` +
393
+ (line ? `\n\n**Line ${line} Theme:** ${info.lines?.[line] ?? "Integration through lived experience."}` : ""),
394
+ }],
395
+ };
396
+ },
397
+ });
398
+ // ── Tool: hd_on_channel_click ─────────────────────────────────────────────
399
+ registerTool({
400
+ name: "hd_on_channel_click",
401
+ description: "Event handler called when the user clicks an active channel in the Human Design Bodygraph. " +
402
+ "Returns the channel's name, the two gates it connects, its circuit, and energy type. " +
403
+ "This tool is called automatically by the bodygraph UI; you do not need to call it directly.",
404
+ inputSchema: {
405
+ type: "object",
406
+ properties: {
407
+ channel: {
408
+ type: "string",
409
+ description: "Channel identifier string (e.g. '1-8', '20-34').",
410
+ },
411
+ gate1: {
412
+ type: "number",
413
+ description: "First gate number.",
414
+ },
415
+ gate2: {
416
+ type: "number",
417
+ description: "Second gate number.",
418
+ },
419
+ },
420
+ required: ["channel"],
421
+ },
422
+ annotations: { title: "Channel Interpretation", readOnlyHint: true, openWorldHint: false },
423
+ _meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
424
+ handler: async (args) => {
425
+ const channelStr = String(args.channel);
426
+ const g1 = args.gate1 != null ? Number(args.gate1) : null;
427
+ const g2 = args.gate2 != null ? Number(args.gate2) : null;
428
+ // Normalise lookup key — try both gate orderings
429
+ const key = channelStr.includes("-") ? channelStr : g1 != null && g2 != null ? `${g1}-${g2}` : channelStr;
430
+ const info = HD_CHANNEL_DATA[key] ?? HD_CHANNEL_DATA[key.split("-").reverse().join("-")];
431
+ if (!info) {
432
+ return {
433
+ content: [{
434
+ type: "text",
435
+ text: `**Channel ${channelStr}**\n\n` +
436
+ `Gates ${g1 ?? "?"} and ${g2 ?? "?"} form a channel when both are active in the chart, ` +
437
+ `connecting two centers and creating a defined circuit of energy flow.\n\n` +
438
+ `Detailed channel data not available for this pairing.`,
439
+ }],
440
+ };
441
+ }
442
+ const ENERGY_TYPE_DESCRIPTIONS = {
443
+ manifested: "This is a **Manifesting** channel — it can initiate and impact the world directly.",
444
+ generated: "This is a **Generated** channel — powered by sacral life-force, it sustains and builds.",
445
+ projected: "This is a **Projected** channel — it guides and directs rather than generates energy.",
446
+ reflected: "This is a **Reflected** channel — it samples and mirrors the whole.",
447
+ };
448
+ const energyDesc = ENERGY_TYPE_DESCRIPTIONS[info.energy_type.toLowerCase()] ?? `Energy type: ${info.energy_type}`;
449
+ return {
450
+ content: [{
451
+ type: "text",
452
+ text: `**Channel ${channelStr} — ${info.name}**\n\n` +
453
+ `**Gates:** ${g1 ?? channelStr.split("-")[0]} ↔ ${g2 ?? channelStr.split("-")[1]}\n\n` +
454
+ `**Circuit:** ${info.circuit}\n\n` +
455
+ `${energyDesc}\n\n` +
456
+ `${info.description}`,
457
+ }],
458
+ };
459
+ },
460
+ });
461
+ const HD_CENTER_DATA = {
462
+ Head: {
463
+ keynote: "Inspiration, mental pressure, questioning",
464
+ biology: "Pineal gland, crown of skull",
465
+ circuit: "Knowing and Logic circuits",
466
+ defined_theme: "Consistent mental pressure to question, inspire, and seek answers. A fixed set of questions drives the mind.",
467
+ undefined_theme: "Amplifies others' mental pressure and questions. Wisdom comes from knowing which questions are worth answering — not every pressure needs resolution.",
468
+ },
469
+ Ajna: {
470
+ keynote: "Conceptualization, certainty/doubt, mental processing",
471
+ biology: "Pituitary/pineal gland complex, prefrontal cortex",
472
+ circuit: "Individual, Collective, and Tribal circuits",
473
+ defined_theme: "Consistent way of thinking and processing information. Opinionated and certain; thoughts have a reliable flavour.",
474
+ undefined_theme: "Open to many perspectives and ways of processing. The wisdom is in mental flexibility — not needing to be certain.",
475
+ },
476
+ Throat: {
477
+ keynote: "Communication, manifestation, action",
478
+ biology: "Thyroid and parathyroid glands, throat, metabolism",
479
+ circuit: "All circuits converge here",
480
+ defined_theme: "Consistent, reliable voice. Words carry predictable tone and impact. Can initiate speech and manifestation.",
481
+ undefined_theme: "Voice adapts to others and context. Language style shifts depending on who is around. Not designed to speak first.",
482
+ },
483
+ G: {
484
+ keynote: "Identity, love, direction, self",
485
+ biology: "Liver, blood, immune system",
486
+ circuit: "Individual Knowing circuit",
487
+ defined_theme: "Fixed sense of direction and identity. Love, magnetic attraction, and life direction are reliable and self-directed.",
488
+ undefined_theme: "Identity and direction shift with environment and the people around. Sensitive to place — geography matters profoundly for finding the right people.",
489
+ },
490
+ Heart: {
491
+ keynote: "Willpower, ego, material world, value",
492
+ biology: "Heart, stomach, thymus, gallbladder",
493
+ circuit: "Tribal circuit",
494
+ defined_theme: "Consistent willpower and ability to make and keep promises. Strong sense of personal value and what is worth fighting for.",
495
+ undefined_theme: "Willpower is not consistent — rest after exertion is essential. May prove worth unnecessarily. Nothing to prove.",
496
+ },
497
+ Sacral: {
498
+ keynote: "Life-force, sexuality, work, response",
499
+ biology: "Reproductive system, ovaries, testes",
500
+ circuit: "Individual, Collective, and Tribal circuits",
501
+ defined_theme: "Consistent, powerful life-force energy that replenishes daily. Designed to work sustainably and respond gut-first. The motor of Generators and Manifesting Generators.",
502
+ undefined_theme: "No consistent life-force motor. Amplifies sacral energy of defined-sacral beings when around them. Must honour when energy is done — sacral is not a reliable source.",
503
+ },
504
+ Spleen: {
505
+ keynote: "Intuition, instinct, fear, immune system, survival",
506
+ biology: "Spleen, lymphatic system, immune system, skin",
507
+ circuit: "Individual and Tribal circuits",
508
+ defined_theme: "Consistent intuition and immune awareness. Instincts are reliable; the body knows. Fear signals can be a guide rather than a trap.",
509
+ undefined_theme: "Splenic intuition is inconsistent — amplifies others' instincts. May hold on to things out of fear (relationships, jobs) rather than intuitive knowing.",
510
+ },
511
+ "Solar Plexus": {
512
+ keynote: "Emotions, feelings, desires, spirit, moods",
513
+ biology: "Solar plexus nerve cluster, kidneys, lungs, pancreas, prostate",
514
+ circuit: "Tribal and Individual circuits",
515
+ defined_theme: "Consistent emotional wave that cycles through highs and lows. Emotional authority: truth emerges over time, not in the moment. Waiting for clarity before deciding is essential.",
516
+ undefined_theme: "Amplifies and absorbs the emotional states of others. May mistake others' feelings for their own. The wisdom: emotional transparency without drama.",
517
+ },
518
+ Root: {
519
+ keynote: "Stress, pressure, adrenaline, momentum",
520
+ biology: "Adrenal glands, lower back, knees",
521
+ circuit: "Individual, Collective, and Tribal circuits",
522
+ defined_theme: "Consistent adrenal pressure that pulses rhythmically. Reliable source of drive and momentum. Healthy stress fuels accomplishment.",
523
+ undefined_theme: "Root pressure amplifies from others and environment. May rush to release pressure (buying things, making decisions too fast) instead of feeling it and letting it pass.",
524
+ },
525
+ };
526
+ const HD_GATE_DATA = {
527
+ 1: { name: "The Creative", hexagram: "Hex 1 — Creative Power", keynote: "Self-expression as a creative force", gift: "Freshness — original self-expression that inspires", shadow: "Entropy — creative block from fear of not being unique", circuit: "Individual (Centering)" },
528
+ 2: { name: "The Receptive", hexagram: "Hex 2 — Receptive Power", keynote: "The direction of the self", gift: "Orientation — knowing where to go", shadow: "Dislocation — living without inner compass", circuit: "Individual (Centering)" },
529
+ 3: { name: "Ordering", hexagram: "Hex 3 — Difficulty at the Beginning", keynote: "Innovation from chaos", gift: "Innovation — bringing order from initial confusion", shadow: "Chaos — stuck in mutation, unable to stabilise", circuit: "Individual (Centering)" },
530
+ 4: { name: "Formulization", hexagram: "Hex 4 — Youthful Folly", keynote: "Mental solutions that benefit humanity", gift: "Understanding — solutions that help the collective", shadow: "Incompetence — mental answers that cause harm", circuit: "Collective (Logic)" },
531
+ 5: { name: "Fixed Rhythms", hexagram: "Hex 5 — Waiting", keynote: "Universal patterns and timing", gift: "Patience — trusting the correct timing", shadow: "Impatience — forcing outcomes", circuit: "Collective (Logic)" },
532
+ 6: { name: "Friction", hexagram: "Hex 6 — Conflict", keynote: "The role model through experience", gift: "Diplomacy — conflict resolved through right relationship", shadow: "Conflict — isolation and withdrawal", circuit: "Collective (Logic)" },
533
+ 7: { name: "The Role of the Self", hexagram: "Hex 7 — The Army", keynote: "Leadership in the direction of the future", gift: "Guidance — leading through personal example", shadow: "Division — leadership without authority", circuit: "Collective (Logic)" },
534
+ 8: { name: "Contribution", hexagram: "Hex 8 — Holding Together", keynote: "Contribution to the collective through individual creativity", gift: "Style — unique contribution that inspires others", shadow: "Mediocrity — hiding unique self to fit in", circuit: "Individual (Centering)" },
535
+ 9: { name: "Focus", hexagram: "Hex 9 — The Taming Power of the Small", keynote: "Determination and focus on detail", gift: "Determination — laser focus on what matters", shadow: "Inertia — scattered, unable to concentrate", circuit: "Collective (Logic)" },
536
+ 10: { name: "Behaviour of the Self", hexagram: "Hex 10 — Treading", keynote: "Love of self, self-empowerment", gift: "Naturalness — authentic behaviour without self-consciousness", shadow: "Self-obsession — behaviour driven by approval-seeking", circuit: "Individual (Centering)" },
537
+ 11: { name: "Ideas", hexagram: "Hex 11 — Peace", keynote: "The harmony of ideas", gift: "Idealism — ideas that envision greater harmony", shadow: "Obscurity — inability to ground and communicate visions", circuit: "Collective (Abstract)" },
538
+ 12: { name: "Caution", hexagram: "Hex 12 — Standstill", keynote: "Active caution in social interaction", gift: "Discrimination — grace in social engagement", shadow: "Vanity — withdrawing emotionally from genuine connection", circuit: "Individual (Centering)" },
539
+ 13: { name: "Fellowship of Man", hexagram: "Hex 13 — The Fellowship", keynote: "Universal listening", gift: "Empathy — the ear that holds others' stories", shadow: "Discord — secrets and betrayal", circuit: "Individual (Centering)" },
540
+ 14: { name: "Power Skills", hexagram: "Hex 14 — Possession in Great Measure", keynote: "Accumulation of resources for collective good", gift: "Competence — using resources masterfully", shadow: "Compromise — accumulating for the wrong reasons", circuit: "Individual (Centering)" },
541
+ 15: { name: "Extremes", hexagram: "Hex 15 — Modesty", keynote: "Extremes flow into the universal", gift: "Magnetism — extreme rhythms that attract the right others", shadow: "Dullness — inability to embrace natural extremes", circuit: "Individual (Centering)" },
542
+ 16: { name: "Skills", hexagram: "Hex 16 — Enthusiasm", keynote: "Expressing talent with zeal", gift: "Versatility — enthusiastic expression of many skills", shadow: "Indifference — talent wasted by lack of drive", circuit: "Collective (Logic)" },
543
+ 17: { name: "Opinions", hexagram: "Hex 17 — Following", keynote: "Opinions that help the collective move forward", gift: "Far-sightedness — opinions that serve the future", shadow: "Opinion — opinionating without wisdom", circuit: "Collective (Logic)" },
544
+ 18: { name: "Correction", hexagram: "Hex 18 — Work on What Has Been Spoilt", keynote: "Judgment to find perfection", gift: "Integrity — correction that restores wholeness", shadow: "Judgment — criticism that wounds rather than heals", circuit: "Collective (Logic)" },
545
+ 19: { name: "Wanting", hexagram: "Hex 19 — Approach", keynote: "Sensitivity to spirit and material needs", gift: "Sensitivity — awareness of unspoken needs", shadow: "Co-dependence — needs driving all decisions", circuit: "Tribal (Defence)" },
546
+ 20: { name: "Contemplation", hexagram: "Hex 20 — Contemplation", keynote: "Presence in the now", gift: "Self-assurance — expressing truth in the moment", shadow: "Superficiality — words without depth", circuit: "Individual (Centering)" },
547
+ 21: { name: "The Treasurer", hexagram: "Hex 21 — Biting Through", keynote: "Self-regulation and control in the material world", gift: "Authority — control exercised with integrity", shadow: "Control — possessiveness and domination", circuit: "Tribal (Ego)" },
548
+ 22: { name: "Openness", hexagram: "Hex 22 — Grace", keynote: "The quality of emotional grace", gift: "Graciousness — emotional openness that transforms", shadow: "Dishonour — emotional withdrawal and defence", circuit: "Individual (Centering)" },
549
+ 23: { name: "Splitting Apart", hexagram: "Hex 23 — Splitting Apart", keynote: "Translating the unique into language others can receive", gift: "Simplicity — the gift of making the complex clear", shadow: "Complexity — information without context or timing", circuit: "Individual (Centering)" },
550
+ 24: { name: "Rationalisation", hexagram: "Hex 24 — Return", keynote: "The blessings of mental return and review", gift: "Invention — turning contemplation into breakthrough", shadow: "Addiction — mental looping without resolution", circuit: "Individual (Knowing)" },
551
+ 25: { name: "Innocence", hexagram: "Hex 25 — Innocence", keynote: "The wisdom of innocence and universalising love", gift: "Acceptance — love without conditions or agenda", shadow: "Cruelty — the pain of love withheld", circuit: "Individual (Centering)" },
552
+ 26: { name: "The Taming Power of the Great", hexagram: "Hex 26 — Taming", keynote: "Skilful transmitting of information", gift: "Artfulness — the gift of efficient, compelling communication", shadow: "Covetousness — ego-driven manipulation", circuit: "Tribal (Ego)" },
553
+ 27: { name: "Caring", hexagram: "Hex 27 — Nourishment", keynote: "Preservation and nurturing", gift: "Altruism — sustaining others from genuine care", shadow: "Selfishness — nurturing only what benefits the self", circuit: "Tribal (Defence)" },
554
+ 28: { name: "The Game Player", hexagram: "Hex 28 — Preponderance of the Great", keynote: "Finding purpose in struggle", gift: "Totality — fully committing to what gives life meaning", shadow: "Purposelessness — gambling with life's purpose", circuit: "Individual (Knowing)" },
555
+ 29: { name: "The Abysmal", hexagram: "Hex 29 — The Abysmal", keynote: "Commitment and perseverance", gift: "Commitment — deep yes to what the sacral confirms", shadow: "Half-heartedness — over-committed without response", circuit: "Collective (Abstract)" },
556
+ 30: { name: "Feelings", hexagram: "Hex 30 — The Clinging", keynote: "Recognition and feeling of experience", gift: "Lightness — riding the wave without being swept away", shadow: "Desire — driven by emotional craving", circuit: "Collective (Abstract)" },
557
+ 31: { name: "Influence", hexagram: "Hex 31 — Influence", keynote: "Leading through democratic means", gift: "Leadership — influence through example and invitation", shadow: "Arrogance — influence through position rather than merit", circuit: "Collective (Logic)" },
558
+ 32: { name: "Continuity", hexagram: "Hex 32 — Duration", keynote: "Intuitive assessment of what endures", gift: "Preservation — knowing what is worth preserving", shadow: "Failure — fear of failure blocking right assessment", circuit: "Tribal (Defence)" },
559
+ 33: { name: "Privacy", hexagram: "Hex 33 — Retreat", keynote: "Knowing when to retreat and share later wisdom", gift: "Revelation — wisdom shared at the right time", shadow: "Forgetting — retreat without integration", circuit: "Collective (Abstract)" },
560
+ 34: { name: "Power", hexagram: "Hex 34 — The Power of the Great", keynote: "Manifestation of power through response", gift: "Strength — responsive power that transforms", shadow: "Force — power without direction or response", circuit: "Individual (Centering)" },
561
+ 35: { name: "Change", hexagram: "Hex 35 — Progress", keynote: "The hunger for experience", gift: "Adventure — embracing change for collective growth", shadow: "Hunger — chasing experience to fill an inner void", circuit: "Collective (Abstract)" },
562
+ 36: { name: "Crisis", hexagram: "Hex 36 — Darkening of the Light", keynote: "The need for emotional experience as teacher", gift: "Humanity — finding compassion through crisis survived", shadow: "Turbulence — emotionally driven chaos and drama", circuit: "Collective (Abstract)" },
563
+ 37: { name: "Friendship", hexagram: "Hex 37 — The Family", keynote: "Harmony through clear agreements in relationship", gift: "Equality — friendship built on mutual respect", shadow: "Inequality — bargaining and conditional love", circuit: "Tribal (Ego)" },
564
+ 38: { name: "The Fighter", hexagram: "Hex 38 — Opposition", keynote: "Struggle in the search for purpose", gift: "Perseverance — fighting for what is meaningful", shadow: "Struggle — fighting against everything without purpose", circuit: "Individual (Knowing)" },
565
+ 39: { name: "Provocation", hexagram: "Hex 39 — Obstruction", keynote: "Freeing the spirit through provocation", gift: "Dynamism — provocateur that liberates", shadow: "Provocation — stirring trouble unconsciously", circuit: "Individual (Knowing)" },
566
+ 40: { name: "Aloneness", hexagram: "Hex 40 — Deliverance", keynote: "The demand for aloneness as restoration", gift: "Resolve — willpower renewed in solitude", shadow: "Exhaustion — depleted by giving without replenishment", circuit: "Tribal (Ego)" },
567
+ 41: { name: "Contraction", hexagram: "Hex 41 — Decrease", keynote: "The beginning of all experience — fantasy and desire", gift: "Fantasy — imagination that seeds new experience", shadow: "Fantasy misused — escapism", circuit: "Collective (Abstract)" },
568
+ 42: { name: "Growth", hexagram: "Hex 42 — Increase", keynote: "The ability to perpetuate and complete growth cycles", gift: "Detachment — completing cycles with grace", shadow: "Incompletion — abandoning cycles before they end", circuit: "Collective (Abstract)" },
569
+ 43: { name: "Insight", hexagram: "Hex 43 — Breakthrough", keynote: "Breakthrough from within", gift: "Insight — inner knowing that arrives as genius", shadow: "Deafness — genius unrecognised or unheard", circuit: "Individual (Knowing)" },
570
+ 44: { name: "Alertness", hexagram: "Hex 44 — Coming to Meet", keynote: "Instinctive memory and pattern recognition", gift: "Teamwork — bringing the right people together", shadow: "Interference — driven by karmic patterns from the past", circuit: "Tribal (Defence)" },
571
+ 45: { name: "The Gatherer", hexagram: "Hex 45 — Gathering Together", keynote: "Ruling and gathering resources for the tribe", gift: "Synergy — the king/queen who gathers and empowers", shadow: "Dominance — ruling through control", circuit: "Tribal (Ego)" },
572
+ 46: { name: "The Serendipitous", hexagram: "Hex 46 — Pushing Upward", keynote: "Love of the body and serendipity", gift: "Delight — inhabiting the body fully", shadow: "Seriousness — disconnected from physical joy", circuit: "Individual (Centering)" },
573
+ 47: { name: "Realisation", hexagram: "Hex 47 — Oppression", keynote: "The realisation that transforms oppression", gift: "Realisation — finding the gem in difficult experience", shadow: "Oppression — trapped in mental suffering", circuit: "Collective (Abstract)" },
574
+ 48: { name: "Well", hexagram: "Hex 48 — The Well", keynote: "The depth that provides solutions", gift: "Resourcefulness — drawing from a depth of wisdom", shadow: "Inadequacy — fear of not being deep enough", circuit: "Collective (Logic)" },
575
+ 49: { name: "Revolution", hexagram: "Hex 49 — Revolution", keynote: "Sensitivity to right principles", gift: "Revolution — principled transformation", shadow: "Reaction — rejection driven by fear", circuit: "Tribal (Defence)" },
576
+ 50: { name: "Values", hexagram: "Hex 50 — The Cauldron", keynote: "Values for humanity's nourishment", gift: "Responsibility — holding values that sustain the tribe", shadow: "Corruption — values compromised for survival", circuit: "Tribal (Defence)" },
577
+ 51: { name: "The Arousing", hexagram: "Hex 51 — The Arousing", keynote: "The shock that awakens spirit", gift: "Initiative — shock as awakening force", shadow: "Agitation — disruption without purpose", circuit: "Individual (Centering)" },
578
+ 52: { name: "Concentration", hexagram: "Hex 52 — Keeping Still", keynote: "Concentration and stillness as a power", gift: "Restraint — focused stillness that creates mastery", shadow: "Stress — adrenal pressure without direction", circuit: "Collective (Logic)" },
579
+ 53: { name: "Beginnings", hexagram: "Hex 53 — Development", keynote: "Pressure to start new cycles", gift: "Expansion — initiating growth cycles", shadow: "Immaturity — starting without completing", circuit: "Collective (Abstract)" },
580
+ 54: { name: "Ambition", hexagram: "Hex 54 — The Marrying Maiden", keynote: "The transformative fuel of ambition", gift: "Aspiration — ambition that elevates all", shadow: "Greed — reaching for position at others' expense", circuit: "Tribal (Defence)" },
581
+ 55: { name: "Abundance", hexagram: "Hex 55 — Abundance", keynote: "Emotional abundance and spirit", gift: "Freedom — emotional richness surrendered to spirit", shadow: "Victimisation — emotional suffering without spirit", circuit: "Individual (Knowing)" },
582
+ 56: { name: "Stimulation", hexagram: "Hex 56 — The Wanderer", keynote: "Stimulating stories and beliefs", gift: "Enrichment — stories that expand perspective", shadow: "Distraction — stories that mislead", circuit: "Collective (Abstract)" },
583
+ 57: { name: "Intuitive Insight", hexagram: "Hex 57 — The Gentle", keynote: "Intuitive insight in the now", gift: "Clarity — penetrating intuition that clears confusion", shadow: "Unease — anxiety from ignoring the body's signals", circuit: "Individual (Knowing)" },
584
+ 58: { name: "Vitality", hexagram: "Hex 58 — The Joyous", keynote: "Vitality and the joy of life", gift: "Vitality — life-force expressed as joy", shadow: "Dissatisfaction — criticism of what is imperfect", circuit: "Collective (Logic)" },
585
+ 59: { name: "Sexuality", hexagram: "Hex 59 — Dispersion", keynote: "Intimacy and aura penetration", gift: "Intimacy — dissolving the aura safely into union", shadow: "Dishonesty — seduction without regard for truth", circuit: "Tribal (Defence)" },
586
+ 60: { name: "Acceptance", hexagram: "Hex 60 — Limitation", keynote: "Acceptance of limitation as the basis for transcendence", gift: "Realism — working within constraints creatively", shadow: "Conservatism — clinging to limitation as identity", circuit: "Individual (Knowing)" },
587
+ 61: { name: "Mystery", hexagram: "Hex 61 — Inner Truth", keynote: "The pressure to understand the unknowable", gift: "Inspiration — inner knowing beyond logic", shadow: "Psychosis — consumed by the search for unknowable truths", circuit: "Individual (Knowing)" },
588
+ 62: { name: "Detail", hexagram: "Hex 62 — Preponderance of the Small", keynote: "The precision of detail and naming", gift: "Precision — detail that serves communication", shadow: "Intellectualism — detail without substance", circuit: "Collective (Logic)" },
589
+ 63: { name: "Doubt", hexagram: "Hex 63 — After Completion", keynote: "Logical doubt as a mental pressure", gift: "Inquiry — questioning that leads to new solutions", shadow: "Doubt — anxiety about an unknowable future", circuit: "Collective (Logic)" },
590
+ 64: { name: "Confusion", hexagram: "Hex 64 — Before Completion", keynote: "The inspiration pressure before clarity", gift: "Imagination — holding confusion long enough for illumination", shadow: "Confusion — overwhelmed by unresolved mental images", circuit: "Collective (Abstract)" },
591
+ };
592
+ const HD_CHANNEL_DATA = {
593
+ "1-8": { name: "Inspiration", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of creative inspiration — a unique individual frequency that inspires others through authentic self-expression. Not designed to broadcast; waits for recognition." },
594
+ "2-14": { name: "The Beat", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of the keeper of keys — a powerful sacral motor connected to the G center's direction. Attracts others magnetically toward purposeful resource accumulation." },
595
+ "3-60": { name: "Mutation", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of mutation — energy that transforms through accepted limitation. Initiates new patterns in a discontinuous, pulse-like fashion that disrupts the old." },
596
+ "4-63": { name: "Logic", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of mental logic — pressure and solutions meeting in a cycle of questioning and formulizing. Mental energy that must wait to be asked before offering answers." },
597
+ "5-15": { name: "Rhythm", circuit: "Collective (Logic)", energy_type: "generated", description: "The channel of fixed rhythms — humanity's flow and fixed patterns. Sacral motor powering universal timing; key to humanity's biological health rhythms." },
598
+ "6-59": { name: "Intimacy", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of intimacy — penetrating auras for mating and reproduction. Emotional authority governing who is let past one's auric boundaries." },
599
+ "7-31": { name: "The Alpha", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of the leader — democratic leadership providing direction to the collective. Recognition and invitation are essential; leadership must be elected, not seized." },
600
+ "9-52": { name: "Concentration", circuit: "Collective (Logic)", energy_type: "generated", description: "The channel of the focused mind — detail and concentration driving sacral response. Sustains attention on a single thread of logic until it resolves." },
601
+ "10-20": { name: "Awakening", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of awakening — the behaviour of the self expressed in the now. Presence and authenticity expressed without self-consciousness; a love of life in motion." },
602
+ "10-34": { name: "Exploration", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of following one's convictions — sacral power directed toward authentic self-expression and exploration. Highly independent." },
603
+ "10-57": { name: "Perfected Form", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of perfected form — survival instinct guided by intuition. Body awareness at its most refined; may produce physical beauty or extraordinary physical gifts." },
604
+ "11-56": { name: "Curiosity", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of the storyteller — abstract ideas turned into stimulating stories that expand others' perspectives. Conceptual awareness awaiting recognition." },
605
+ "12-22": { name: "Openness", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of openness — emotional grace in social engagement. When the wave is right, this channel opens conversations that can transform others profoundly." },
606
+ "13-33": { name: "The Prodigal", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of witness — listening to humanity's stories and retreating to share crystallised wisdom at the right time. The therapist channel." },
607
+ "16-48": { name: "The Wavelength", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of talent — depth of skill expressed as enthusiasm. Natural mastery that appears effortless; awakens when talents are recognised and invited." },
608
+ "17-62": { name: "Acceptance", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of organised activity — opinions formulated into detailed plans and frameworks. Facts and logic turned into workable systems." },
609
+ "18-58": { name: "Judgement", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of judgement — passionate criticism in service of joy and vitality. The desire to perfect what is alive; driven by love of life." },
610
+ "19-49": { name: "Synthesis", circuit: "Tribal (Defence)", energy_type: "projected", description: "The channel of synthesis — sensitivity to the tribe's emotional and material needs, combined with the power to revolutionise through principle. Resources and revolution." },
611
+ "20-34": { name: "Charisma", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of charisma — sacral response expressed in the now with extraordinary presence. Manifesting Generators often carry this channel; built for busy, impactful lives." },
612
+ "20-57": { name: "The Brain Wave", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of the brain wave — penetrating intuitive insight expressed without hesitation. A frequency that can inform the now with body-level knowing." },
613
+ "21-45": { name: "Money Line", circuit: "Tribal (Ego)", energy_type: "projected", description: "The channel of the money line — material world governance. Control over resources in the tribal hierarchy; the king/queen and the treasurer aligned." },
614
+ "23-43": { name: "Structuring", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of structuring — translating individual genius into language that others can hear. The key is timing; genius shared before recognition falls on deaf ears." },
615
+ "24-61": { name: "Awareness", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of awareness — mental pressure toward inner truth. Contemplative awareness cycling through questions until a genuine breakthrough arrives." },
616
+ "25-51": { name: "Initiation", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of initiation — innocence meeting the shock of the new. The shamanic channel; moves through crisis into universalising love." },
617
+ "26-44": { name: "Surrender", circuit: "Tribal (Defence)", energy_type: "projected", description: "The channel of surrender — ego memory and the transmission of the tribe's past patterns. Alert to what has and has not worked; a natural business channel." },
618
+ "27-50": { name: "Preservation", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of preservation — nurturing and values sustaining the tribe across generations. The channel of the mother/father archetype; keeping what is valuable alive." },
619
+ "28-38": { name: "Struggle", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of struggle — the game player meets the fighter in a search for purpose. Life is the game; the question is what is worth the fight." },
620
+ "29-46": { name: "Discovery", circuit: "Collective (Abstract)", energy_type: "generated", description: "The channel of discovery — sacral commitment to embodied experience. The body as the vehicle for serendipitous encounter; the great 'yes' to life." },
621
+ "30-41": { name: "Recognition", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of recognition — the beginning of all human experience. Emotional desire and fantasy that ignites new experiential cycles." },
622
+ "32-54": { name: "Transformation", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of transformation — instinct to transform ambition into material continuity. What endures; which ambitions serve the tribe's long-term survival." },
623
+ "34-57": { name: "Power", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of power — sacral life-force guided by intuition. Raw responsive power with in-the-moment instinctive awareness; self-sufficient and magnetic." },
624
+ "35-36": { name: "Transitoriness", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of transitoriness — the hunger for experience and the emotional crisis of each encounter. Rich emotional lessons through fully-felt experience." },
625
+ "37-40": { name: "Community", circuit: "Tribal (Ego)", energy_type: "projected", description: "The channel of community — bargain and agreement sustaining the family/tribe. Willpower renewed through rest; clear deals that make community sustainable." },
626
+ "39-55": { name: "Emoting", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of emoting — the provocateur meeting the spirit of abundance. Gate 39 stirs the emotional wave; gate 55 determines whether spirit or suffering answers." },
627
+ "42-53": { name: "Maturation", circuit: "Collective (Abstract)", energy_type: "generated", description: "The channel of maturation — beginning and completing cycles of growth. The channel of sustainability; sacral energy that completes what it starts." },
628
+ "47-64": { name: "Abstraction", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of abstraction — confusion ripening into realisation. Mental pressure from the past meeting images from the future; the alchemy of wisdom." },
629
+ "57-20": { name: "The Brain Wave", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of the brain wave — penetrating intuitive insight expressed without hesitation. A frequency that can inform the now with body-level knowing." },
630
+ "58-18": { name: "Judgement", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of judgement — vitality and correction. Joy arising from the pursuit of perfection in what is living and alive." },
631
+ "59-6": { name: "Intimacy", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of intimacy — penetrating auras for mating and reproduction. Emotional authority governing who is let past one's auric boundaries." },
632
+ "60-3": { name: "Mutation", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of mutation — energy that transforms through accepted limitation. Initiates new patterns in a discontinuous, pulse-like fashion." },
633
+ };