add iching tarot links
This commit is contained in:
@@ -873,9 +873,20 @@
|
|||||||
justify-items: start;
|
justify-items: start;
|
||||||
}
|
}
|
||||||
.iching-tarot-text {
|
.iching-tarot-text {
|
||||||
white-space: pre-line;
|
white-space: normal;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.iching-tarot-group {
|
||||||
|
display: grid;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.iching-tarot-group-title {
|
||||||
|
color: #a1a1aa;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Kabbalah sections ──────────────────────────────────────────────── */
|
/* ── Kabbalah sections ──────────────────────────────────────────────── */
|
||||||
|
|||||||
@@ -315,6 +315,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearChildren(elements.ichingDetailTarotEl);
|
||||||
|
|
||||||
const upperKey = normalizeSearchValue(entry?.upperTrigram);
|
const upperKey = normalizeSearchValue(entry?.upperTrigram);
|
||||||
const lowerKey = normalizeSearchValue(entry?.lowerTrigram);
|
const lowerKey = normalizeSearchValue(entry?.lowerTrigram);
|
||||||
const upperCards = upperKey ? state.tarotByTrigramName[upperKey] || [] : [];
|
const upperCards = upperKey ? state.tarotByTrigramName[upperKey] || [] : [];
|
||||||
@@ -325,15 +327,79 @@
|
|||||||
const upperLabel = upperTrigram?.element || entry?.upperTrigram || "--";
|
const upperLabel = upperTrigram?.element || entry?.upperTrigram || "--";
|
||||||
const lowerLabel = lowerTrigram?.element || entry?.lowerTrigram || "--";
|
const lowerLabel = lowerTrigram?.element || entry?.lowerTrigram || "--";
|
||||||
|
|
||||||
const lines = [];
|
function buildTarotTarget(cardName) {
|
||||||
if (upperKey) {
|
const label = String(cardName || "").trim();
|
||||||
lines.push(`Upper (${upperLabel}): ${upperCards.length ? upperCards.join(", ") : "--"}`);
|
if (!label) {
|
||||||
}
|
return null;
|
||||||
if (lowerKey) {
|
}
|
||||||
lines.push(`Lower (${lowerLabel}): ${lowerCards.length ? lowerCards.join(", ") : "--"}`);
|
|
||||||
|
const trumpMatch = label.match(/^key\s*(\d{1,2})\s*:/i);
|
||||||
|
if (trumpMatch) {
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
detail: { trumpNumber: Number(trumpMatch[1]) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
detail: { cardName: label }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.ichingDetailTarotEl.textContent = lines.length ? lines.join("\n\n") : "--";
|
function appendTarotGroup(groupLabel, trigramLabel, cards) {
|
||||||
|
const group = document.createElement("div");
|
||||||
|
group.className = "iching-tarot-group";
|
||||||
|
|
||||||
|
const title = document.createElement("div");
|
||||||
|
title.className = "iching-tarot-group-title";
|
||||||
|
title.textContent = `${groupLabel} (${trigramLabel}):`;
|
||||||
|
group.appendChild(title);
|
||||||
|
|
||||||
|
if (!cards.length) {
|
||||||
|
const empty = document.createElement("div");
|
||||||
|
empty.className = "planet-text";
|
||||||
|
empty.textContent = "--";
|
||||||
|
group.appendChild(empty);
|
||||||
|
elements.ichingDetailTarotEl.appendChild(group);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttonRow = document.createElement("div");
|
||||||
|
buttonRow.className = "alpha-nav-btns";
|
||||||
|
|
||||||
|
cards.forEach((cardName) => {
|
||||||
|
const target = buildTarotTarget(cardName);
|
||||||
|
if (!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const button = document.createElement("button");
|
||||||
|
button.type = "button";
|
||||||
|
button.className = "alpha-nav-btn";
|
||||||
|
button.textContent = `${target.label} ↗`;
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
|
||||||
|
detail: target.detail
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
buttonRow.appendChild(button);
|
||||||
|
});
|
||||||
|
|
||||||
|
group.appendChild(buttonRow);
|
||||||
|
elements.ichingDetailTarotEl.appendChild(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upperKey) {
|
||||||
|
appendTarotGroup("Upper", upperLabel, upperCards);
|
||||||
|
}
|
||||||
|
if (lowerKey) {
|
||||||
|
appendTarotGroup("Lower", lowerLabel, lowerCards);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!elements.ichingDetailTarotEl.childElementCount) {
|
||||||
|
elements.ichingDetailTarotEl.textContent = "--";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCalendarMonths(entry, elements) {
|
function renderCalendarMonths(entry, elements) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
buildSmallCardRulershipRelation,
|
buildSmallCardRulershipRelation,
|
||||||
buildSmallCardCourtLinkRelations,
|
buildSmallCardCourtLinkRelations,
|
||||||
buildCubeRelationsForCard,
|
buildCubeRelationsForCard,
|
||||||
|
buildIChingRelationsForCard,
|
||||||
parseMonthDayToken,
|
parseMonthDayToken,
|
||||||
createRelationListItem,
|
createRelationListItem,
|
||||||
findSephirahForMinorCard
|
findSephirahForMinorCard
|
||||||
@@ -131,6 +132,7 @@
|
|||||||
const smallCardCourtLinkRelations = buildSmallCardCourtLinkRelations(card, dedupedRelations);
|
const smallCardCourtLinkRelations = buildSmallCardCourtLinkRelations(card, dedupedRelations);
|
||||||
const mergedCourtDateRelations = [...courtDateRelations, ...smallCardCourtLinkRelations];
|
const mergedCourtDateRelations = [...courtDateRelations, ...smallCardCourtLinkRelations];
|
||||||
const cubeRelations = buildCubeRelationsForCard(card);
|
const cubeRelations = buildCubeRelationsForCard(card);
|
||||||
|
const iChingRelations = buildIChingRelationsForCard(card);
|
||||||
const monthRelations = (getMonthRefsByCardId().get(card.id) || []).map((month, index) => {
|
const monthRelations = (getMonthRefsByCardId().get(card.id) || []).map((month, index) => {
|
||||||
const dateRange = String(month?.dateRange || "").trim();
|
const dateRange = String(month?.dateRange || "").trim();
|
||||||
const context = String(month?.context || "").trim();
|
const context = String(month?.context || "").trim();
|
||||||
@@ -229,6 +231,7 @@
|
|||||||
renderStaticRelationGroup(elements.tarotDetailCourtDateEl, elements.tarotMetaCourtDateCardEl, mergedCourtDateRelations);
|
renderStaticRelationGroup(elements.tarotDetailCourtDateEl, elements.tarotMetaCourtDateCardEl, mergedCourtDateRelations);
|
||||||
renderStaticRelationGroup(elements.tarotDetailHebrewEl, elements.tarotMetaHebrewCardEl, hebrewRelations);
|
renderStaticRelationGroup(elements.tarotDetailHebrewEl, elements.tarotMetaHebrewCardEl, hebrewRelations);
|
||||||
renderStaticRelationGroup(elements.tarotDetailCubeEl, elements.tarotMetaCubeCardEl, cubeRelations);
|
renderStaticRelationGroup(elements.tarotDetailCubeEl, elements.tarotMetaCubeCardEl, cubeRelations);
|
||||||
|
renderStaticRelationGroup(elements.tarotDetailIChingEl, elements.tarotMetaIChingCardEl, iChingRelations);
|
||||||
renderStaticRelationGroup(elements.tarotDetailCalendarEl, elements.tarotMetaCalendarCardEl, mergedMonthRelations);
|
renderStaticRelationGroup(elements.tarotDetailCalendarEl, elements.tarotMetaCalendarCardEl, mergedMonthRelations);
|
||||||
|
|
||||||
const kabPathEl = elements.tarotKabPathEl;
|
const kabPathEl = elements.tarotKabPathEl;
|
||||||
|
|||||||
@@ -190,6 +190,17 @@
|
|||||||
label: `Open ${d.name || monthId} in Calendar`
|
label: `Open ${d.name || monthId} in Calendar`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (t === "ichingHexagram") {
|
||||||
|
const hexagramNumber = Number(d.hexagramNumber || relation?.id);
|
||||||
|
if (!Number.isFinite(hexagramNumber)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
event: "nav:iching",
|
||||||
|
detail: { hexagramNumber },
|
||||||
|
label: `Open Hexagram ${hexagramNumber} in I Ching`
|
||||||
|
};
|
||||||
|
}
|
||||||
if (t === "cubeFace") {
|
if (t === "cubeFace") {
|
||||||
const wallId = d.wallId || relation?.id;
|
const wallId = d.wallId || relation?.id;
|
||||||
if (!wallId) {
|
if (!wallId) {
|
||||||
|
|||||||
@@ -102,6 +102,8 @@
|
|||||||
return String(value || "")
|
return String(value || "")
|
||||||
.trim()
|
.trim()
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
|
.replace(/^key\s+\d+\s*:\s*/g, "")
|
||||||
|
.replace(/\b(pentacles?|coins?)\b/g, "disks")
|
||||||
.replace(/\s+/g, " ");
|
.replace(/\s+/g, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +116,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolveTarotTrumpNumber(cardName) {
|
function resolveTarotTrumpNumber(cardName) {
|
||||||
|
const rawKey = String(cardName || "")
|
||||||
|
.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
const keyMatch = rawKey.match(/\bkey\s*(\d{1,2})\b/);
|
||||||
|
if (keyMatch) {
|
||||||
|
return Number(keyMatch[1]);
|
||||||
|
}
|
||||||
|
|
||||||
const key = normalizeTarotName(cardName);
|
const key = normalizeTarotName(cardName);
|
||||||
if (!key) {
|
if (!key) {
|
||||||
return null;
|
return null;
|
||||||
@@ -724,11 +734,86 @@
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildIChingRelationsForCard(card, referenceData) {
|
||||||
|
const iChing = referenceData?.iChing;
|
||||||
|
const hexagrams = Array.isArray(iChing?.hexagrams) ? iChing.hexagrams : [];
|
||||||
|
const trigrams = Array.isArray(iChing?.trigrams) ? iChing.trigrams : [];
|
||||||
|
const correspondences = Array.isArray(iChing?.correspondences?.tarotToTrigram)
|
||||||
|
? iChing.correspondences.tarotToTrigram
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (!card || !hexagrams.length || !correspondences.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const trigramByKey = new Map(
|
||||||
|
trigrams
|
||||||
|
.map((trigram) => [normalizeRelationId(trigram?.name), trigram])
|
||||||
|
.filter(([key]) => Boolean(key))
|
||||||
|
);
|
||||||
|
|
||||||
|
const matchedTrigramKeys = [...new Set(
|
||||||
|
correspondences
|
||||||
|
.filter((row) => cardMatchesTarotAssociation(card, row?.tarot))
|
||||||
|
.map((row) => normalizeRelationId(row?.trigram))
|
||||||
|
.filter(Boolean)
|
||||||
|
)];
|
||||||
|
|
||||||
|
if (!matchedTrigramKeys.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const relations = [];
|
||||||
|
|
||||||
|
hexagrams.forEach((hexagram) => {
|
||||||
|
const positionsByTrigram = new Map();
|
||||||
|
const upperKey = normalizeRelationId(hexagram?.upperTrigram);
|
||||||
|
const lowerKey = normalizeRelationId(hexagram?.lowerTrigram);
|
||||||
|
|
||||||
|
if (matchedTrigramKeys.includes(upperKey)) {
|
||||||
|
positionsByTrigram.set(upperKey, ["upper"]);
|
||||||
|
}
|
||||||
|
if (matchedTrigramKeys.includes(lowerKey)) {
|
||||||
|
const existing = positionsByTrigram.get(lowerKey) || [];
|
||||||
|
positionsByTrigram.set(lowerKey, [...existing, "lower"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
positionsByTrigram.forEach((positions, trigramKey) => {
|
||||||
|
const trigram = trigramByKey.get(trigramKey) || null;
|
||||||
|
const sideLabel = positions.length === 2
|
||||||
|
? "Upper + Lower"
|
||||||
|
: positions[0] === "upper"
|
||||||
|
? "Upper"
|
||||||
|
: "Lower";
|
||||||
|
const trigramLabel = trigram?.element || trigram?.name || hexagram?.upperTrigram || hexagram?.lowerTrigram || "Trigram";
|
||||||
|
|
||||||
|
relations.push({
|
||||||
|
type: "ichingHexagram",
|
||||||
|
id: String(hexagram?.number || ""),
|
||||||
|
label: `Hexagram ${hexagram.number}: ${hexagram.name || "--"} · ${sideLabel} ${trigramLabel}`,
|
||||||
|
data: {
|
||||||
|
hexagramNumber: Number(hexagram?.number),
|
||||||
|
name: hexagram?.name || "",
|
||||||
|
upperTrigram: hexagram?.upperTrigram || "",
|
||||||
|
lowerTrigram: hexagram?.lowerTrigram || "",
|
||||||
|
trigramName: trigram?.name || "",
|
||||||
|
trigramElement: trigram?.element || "",
|
||||||
|
positions: positions.join(",")
|
||||||
|
},
|
||||||
|
__key: `ichingHexagram|${hexagram?.number}|${trigramKey}|${positions.join(",")}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return relations.sort((left, right) => Number(left?.data?.hexagramNumber || 999) - Number(right?.data?.hexagramNumber || 999));
|
||||||
|
}
|
||||||
|
|
||||||
window.TarotRelationsUi = {
|
window.TarotRelationsUi = {
|
||||||
buildCourtCardByDecanId,
|
buildCourtCardByDecanId,
|
||||||
buildSmallCardCourtLinkRelations,
|
buildSmallCardCourtLinkRelations,
|
||||||
buildMonthReferencesByCard,
|
buildMonthReferencesByCard,
|
||||||
buildCubeRelationsForCard,
|
buildCubeRelationsForCard,
|
||||||
|
buildIChingRelationsForCard,
|
||||||
parseMonthDayToken
|
parseMonthDayToken
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
@@ -236,6 +236,7 @@
|
|||||||
tarotMetaCourtDateCardEl: document.getElementById("tarot-meta-courtdate-card"),
|
tarotMetaCourtDateCardEl: document.getElementById("tarot-meta-courtdate-card"),
|
||||||
tarotMetaHebrewCardEl: document.getElementById("tarot-meta-hebrew-card"),
|
tarotMetaHebrewCardEl: document.getElementById("tarot-meta-hebrew-card"),
|
||||||
tarotMetaCubeCardEl: document.getElementById("tarot-meta-cube-card"),
|
tarotMetaCubeCardEl: document.getElementById("tarot-meta-cube-card"),
|
||||||
|
tarotMetaIChingCardEl: document.getElementById("tarot-meta-iching-card"),
|
||||||
tarotMetaCalendarCardEl: document.getElementById("tarot-meta-calendar-card"),
|
tarotMetaCalendarCardEl: document.getElementById("tarot-meta-calendar-card"),
|
||||||
tarotDetailPlanetEl: document.getElementById("tarot-detail-planet"),
|
tarotDetailPlanetEl: document.getElementById("tarot-detail-planet"),
|
||||||
tarotDetailElementEl: document.getElementById("tarot-detail-element"),
|
tarotDetailElementEl: document.getElementById("tarot-detail-element"),
|
||||||
@@ -244,6 +245,7 @@
|
|||||||
tarotDetailCourtDateEl: document.getElementById("tarot-detail-courtdate"),
|
tarotDetailCourtDateEl: document.getElementById("tarot-detail-courtdate"),
|
||||||
tarotDetailHebrewEl: document.getElementById("tarot-detail-hebrew"),
|
tarotDetailHebrewEl: document.getElementById("tarot-detail-hebrew"),
|
||||||
tarotDetailCubeEl: document.getElementById("tarot-detail-cube"),
|
tarotDetailCubeEl: document.getElementById("tarot-detail-cube"),
|
||||||
|
tarotDetailIChingEl: document.getElementById("tarot-detail-iching"),
|
||||||
tarotDetailCalendarEl: document.getElementById("tarot-detail-calendar"),
|
tarotDetailCalendarEl: document.getElementById("tarot-detail-calendar"),
|
||||||
tarotKabPathEl: document.getElementById("tarot-kab-path"),
|
tarotKabPathEl: document.getElementById("tarot-kab-path"),
|
||||||
tarotHouseOfCardsEl: document.getElementById("tarot-house-of-cards")
|
tarotHouseOfCardsEl: document.getElementById("tarot-house-of-cards")
|
||||||
@@ -303,6 +305,7 @@
|
|||||||
buildSmallCardRulershipRelation,
|
buildSmallCardRulershipRelation,
|
||||||
buildSmallCardCourtLinkRelations,
|
buildSmallCardCourtLinkRelations,
|
||||||
buildCubeRelationsForCard,
|
buildCubeRelationsForCard,
|
||||||
|
buildIChingRelationsForCard,
|
||||||
parseMonthDayToken,
|
parseMonthDayToken,
|
||||||
createRelationListItem,
|
createRelationListItem,
|
||||||
findSephirahForMinorCard
|
findSephirahForMinorCard
|
||||||
@@ -513,6 +516,13 @@
|
|||||||
return tarotRelationsUi.buildCubeRelationsForCard(card, state.magickDataset);
|
return tarotRelationsUi.buildCubeRelationsForCard(card, state.magickDataset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildIChingRelationsForCard(card) {
|
||||||
|
if (typeof tarotRelationsUi.buildIChingRelationsForCard !== "function") {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return tarotRelationsUi.buildIChingRelationsForCard(card, state.referenceData);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns nav dispatch config for relations that have a corresponding section,
|
// Returns nav dispatch config for relations that have a corresponding section,
|
||||||
// null for informational-only relations.
|
// null for informational-only relations.
|
||||||
function getRelationNavTarget(relation) {
|
function getRelationNavTarget(relation) {
|
||||||
|
|||||||
@@ -244,6 +244,10 @@
|
|||||||
<strong>Cube of Space</strong>
|
<strong>Cube of Space</strong>
|
||||||
<ul id="tarot-detail-cube" class="tarot-relations"></ul>
|
<ul id="tarot-detail-cube" class="tarot-relations"></ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="tarot-meta-iching-card" class="tarot-meta-card" hidden>
|
||||||
|
<strong>I Ching</strong>
|
||||||
|
<ul id="tarot-detail-iching" class="tarot-relations"></ul>
|
||||||
|
</div>
|
||||||
<div id="tarot-meta-calendar-card" class="tarot-meta-card" hidden>
|
<div id="tarot-meta-calendar-card" class="tarot-meta-card" hidden>
|
||||||
<strong>Calendar Months</strong>
|
<strong>Calendar Months</strong>
|
||||||
<ul id="tarot-detail-calendar" class="tarot-relations"></ul>
|
<ul id="tarot-detail-calendar" class="tarot-relations"></ul>
|
||||||
@@ -392,7 +396,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="planet-meta-card">
|
<div class="planet-meta-card">
|
||||||
<strong>Tarot Correspondences</strong>
|
<strong>Tarot Correspondences</strong>
|
||||||
<p id="iching-detail-tarot" class="planet-text iching-tarot-text">--</p>
|
<div id="iching-detail-tarot" class="planet-text iching-tarot-text">--</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="planet-meta-card">
|
<div class="planet-meta-card">
|
||||||
<strong>Calendar Months</strong>
|
<strong>Calendar Months</strong>
|
||||||
|
|||||||
Reference in New Issue
Block a user