/* ui-alphabet.js — Multi-alphabet browser (English / Hebrew / Greek / Arabic / Enochian) */ (function () { "use strict"; const alphabetGematriaUi = window.AlphabetGematriaUi || {}; const alphabetBrowserUi = window.AlphabetBrowserUi || {}; const alphabetKabbalahUi = window.AlphabetKabbalahUi || {}; const alphabetReferenceBuilders = window.AlphabetReferenceBuilders || {}; const alphabetDetailUi = window.AlphabetDetailUi || {}; if ( typeof alphabetBrowserUi.createAlphabetBrowser !== "function" || typeof alphabetKabbalahUi.buildCubePlacementButton !== "function" || typeof alphabetKabbalahUi.buildFourWorldLayersFromDataset !== "function" || typeof alphabetKabbalahUi.createEmptyCubeRefs !== "function" || typeof alphabetKabbalahUi.getCubePlacementForHebrewLetter !== "function" || typeof alphabetKabbalahUi.getCubePlacementForPlanet !== "function" || typeof alphabetKabbalahUi.getCubePlacementForSign !== "function" || typeof alphabetKabbalahUi.normalizeId !== "function" || typeof alphabetKabbalahUi.normalizeLetterId !== "function" || typeof alphabetKabbalahUi.titleCase !== "function" ) { throw new Error("AlphabetBrowserUi and AlphabetKabbalahUi modules must load before ui-alphabet.js"); } const state = { initialized: false, alphabets: null, activeAlphabet: "all", selectedKey: null, filters: { query: "", letterType: "" }, fourWorldLayers: [], monthRefsByHebrewId: new Map(), cubeRefs: { hebrewPlacementById: new Map(), signPlacementById: new Map(), planetPlacementById: new Map(), pathPlacementByNo: new Map() } }; function arabicDisplayName(letter) { return browserUi.arabicDisplayName(letter); } // ── Element cache ──────────────────────────────────────────────────── let listEl, countEl, detailNameEl, detailSubEl, detailBodyEl; let tabAll, tabHebrew, tabGreek, tabEnglish, tabArabic, tabEnochian; let searchInputEl, searchClearEl, typeFilterEl; let gematriaCipherEl, gematriaInputEl, gematriaResultEl, gematriaBreakdownEl; function getElements() { listEl = document.getElementById("alpha-letter-list"); countEl = document.getElementById("alpha-letter-count"); detailNameEl = document.getElementById("alpha-detail-name"); detailSubEl = document.getElementById("alpha-detail-sub"); detailBodyEl = document.getElementById("alpha-detail-body"); tabAll = document.getElementById("alpha-tab-all"); tabHebrew = document.getElementById("alpha-tab-hebrew"); tabGreek = document.getElementById("alpha-tab-greek"); tabEnglish = document.getElementById("alpha-tab-english"); tabArabic = document.getElementById("alpha-tab-arabic"); tabEnochian = document.getElementById("alpha-tab-enochian"); searchInputEl = document.getElementById("alpha-search-input"); searchClearEl = document.getElementById("alpha-search-clear"); typeFilterEl = document.getElementById("alpha-type-filter"); gematriaCipherEl = document.getElementById("alpha-gematria-cipher"); gematriaInputEl = document.getElementById("alpha-gematria-input"); gematriaResultEl = document.getElementById("alpha-gematria-result"); gematriaBreakdownEl = document.getElementById("alpha-gematria-breakdown"); } function getGematriaElements() { getElements(); return { cipherEl: gematriaCipherEl, inputEl: gematriaInputEl, resultEl: gematriaResultEl, breakdownEl: gematriaBreakdownEl }; } function ensureGematriaCalculator() { alphabetGematriaUi.init?.({ getAlphabets: () => state.alphabets, getGematriaElements }); alphabetGematriaUi.ensureCalculator?.(); } // ── Data helpers ───────────────────────────────────────────────────── function getLetters() { return browserUi.getLetters(); } function alphabetForLetter(letter) { return browserUi.alphabetForLetter(letter); } function letterKeyByAlphabet(alphabet, letter) { return browserUi.letterKeyByAlphabet(alphabet, letter); } function letterKey(letter) { return browserUi.letterKey(letter); } function displayGlyph(letter) { return browserUi.displayGlyph(letter); } function displayLabel(letter) { return browserUi.displayLabel(letter); } function displaySub(letter) { return browserUi.displaySub(letter); } function normalizeLetterType(value) { return browserUi.normalizeLetterType(value); } function getHebrewLetterTypeMap() { return browserUi.getHebrewLetterTypeMap(); } function resolveLetterType(letter) { return browserUi.resolveLetterType(letter); } function buildLetterSearchText(letter) { return browserUi.buildLetterSearchText(letter); } function getFilteredLetters() { return browserUi.getFilteredLetters(); } function syncFilterControls() { browserUi.syncFilterControls(); } function applyFiltersAndRender() { browserUi.applyFiltersAndRender(); } function bindFilterControls() { browserUi.bindFilterControls(); } function enochianGlyphKey(letter) { return browserUi.enochianGlyphKey(letter); } function enochianGlyphCode(letter) { return browserUi.enochianGlyphCode(letter); } function enochianGlyphUrl(letter) { return browserUi.enochianGlyphUrl(letter); } function enochianGlyphImageHtml(letter, className) { return browserUi.enochianGlyphImageHtml(letter, className); } // ── List rendering ──────────────────────────────────────────────────── function renderList() { browserUi.renderList(); } // ── Detail rendering ────────────────────────────────────────────────── function renderDetail(letter) { if (!detailNameEl) return; const alphabet = alphabetForLetter(letter); detailNameEl.replaceChildren(); if (alphabet === "enochian") { const image = document.createElement("img"); image.className = "alpha-enochian-glyph-img alpha-enochian-glyph-img--detail"; image.src = enochianGlyphUrl(letter); image.alt = `Enochian ${enochianGlyphKey(letter) || "?"}`; image.loading = "lazy"; image.decoding = "async"; image.addEventListener("error", () => { detailNameEl.textContent = enochianGlyphKey(letter) || "?"; }); detailNameEl.appendChild(image); } else { detailNameEl.textContent = displayGlyph(letter); } detailNameEl.classList.add("alpha-detail-glyph"); detailNameEl.classList.toggle("alpha-detail-glyph--arabic", alphabet === "arabic"); detailNameEl.classList.toggle("alpha-detail-glyph--enochian", alphabet === "enochian"); if (typeof alphabetDetailUi.renderDetail === "function") { alphabetDetailUi.renderDetail(getDetailRenderContext(letter, alphabet)); } } function card(title, bodyHTML) { return `
`; } const PLANET_SYMBOLS = { mercury: "☿︎", luna: "☾︎", venus: "♀︎", sol: "☉︎", jupiter: "♃︎", mars: "♂︎", saturn: "♄︎" }; const ZODIAC_SYMBOLS = { aries: "♈︎", taurus: "♉︎", gemini: "♊︎", cancer: "♋︎", leo: "♌︎", virgo: "♍︎", libra: "♎︎", scorpio: "♏︎", sagittarius: "♐︎", capricorn: "♑︎", aquarius: "♒︎", pisces: "♓︎" }; const HEBREW_DOUBLE_DUALITY = { bet: { left: "Life", right: "Death" }, gimel: { left: "Peace", right: "War" }, dalet: { left: "Wisdom", right: "Folly" }, kaf: { left: "Wealth", right: "Poverty" }, pe: { left: "Beauty", right: "Ugliness" }, resh: { left: "Fruitfulness", right: "Sterility" }, tav: { left: "Dominion", right: "Slavery" } }; function normalizeId(value) { return alphabetKabbalahUi.normalizeId(value); } function normalizeLetterId(value) { return alphabetKabbalahUi.normalizeLetterId(value); } function titleCase(value) { return alphabetKabbalahUi.titleCase(value); } function buildFourWorldLayersFromDataset(magickDataset) { return alphabetKabbalahUi.buildFourWorldLayersFromDataset(magickDataset); } function buildMonthReferencesByHebrew(referenceData, alphabets) { if (typeof alphabetReferenceBuilders.buildMonthReferencesByHebrew !== "function") { return new Map(); } return alphabetReferenceBuilders.buildMonthReferencesByHebrew(referenceData, alphabets); } function createEmptyCubeRefs() { return alphabetKabbalahUi.createEmptyCubeRefs(); } function buildCubeReferences(magickDataset) { if (typeof alphabetReferenceBuilders.buildCubeReferences !== "function") { return createEmptyCubeRefs(); } return alphabetReferenceBuilders.buildCubeReferences(magickDataset); } function getCubePlacementForHebrewLetter(hebrewLetterId, pathNo = null) { return alphabetKabbalahUi.getCubePlacementForHebrewLetter(state.cubeRefs, hebrewLetterId, pathNo); } function getCubePlacementForPlanet(planetId) { return alphabetKabbalahUi.getCubePlacementForPlanet(state.cubeRefs, planetId); } function getCubePlacementForSign(signId) { return alphabetKabbalahUi.getCubePlacementForSign(state.cubeRefs, signId); } function cubePlacementBtn(placement, fallbackDetail = null) { return alphabetKabbalahUi.buildCubePlacementButton(placement, navBtn, fallbackDetail); } function cap(s) { return s ? s.charAt(0).toUpperCase() + s.slice(1) : ""; } function navBtn(label, event, detail) { const attrs = Object.entries(detail).map(([k, v]) => `data-${k}="${v}"`).join(" "); return ``; } function getDetailRenderContext(letter, alphabet) { return { letter, alphabet, detailSubEl, detailBodyEl, alphabets: state.alphabets, fourWorldLayers: state.fourWorldLayers, monthRefsByHebrewId: state.monthRefsByHebrewId, PLANET_SYMBOLS, ZODIAC_SYMBOLS, HEBREW_DOUBLE_DUALITY, card, navBtn, cap, normalizeId, normalizeLetterId, getCubePlacementForPlanet, getCubePlacementForSign, getCubePlacementForHebrewLetter, cubePlacementBtn, arabicDisplayName, enochianGlyphImageHtml, attachDetailListeners }; } const browserUi = alphabetBrowserUi.createAlphabetBrowser({ state, normalizeId, getDomRefs: () => ({ listEl, countEl, detailNameEl, detailSubEl, detailBodyEl, tabAll, tabHebrew, tabGreek, tabEnglish, tabArabic, tabEnochian, searchInputEl, searchClearEl, typeFilterEl }), renderDetail }); // ── Event delegation on detail body ────────────────────────────────── function attachDetailListeners() { if (!detailBodyEl) return; // Nav buttons — generic: forward all data-* (except data-event) as the event detail detailBodyEl.querySelectorAll(".alpha-nav-btn[data-event]").forEach((btn) => { btn.addEventListener("click", () => { const evtName = btn.dataset.event; const detail = {}; Object.entries(btn.dataset).forEach(([key, val]) => { if (key === "event") return; // Convert kebab data keys to camelCase (e.g. planet-id → planetId) const camel = key.replace(/-([a-z])/g, (_, c) => c.toUpperCase()); detail[camel] = isNaN(Number(val)) || val === "" ? val : Number(val); }); document.dispatchEvent(new CustomEvent(evtName, { detail })); }); }); // Sister letter cross-navigation within this section detailBodyEl.querySelectorAll(".alpha-sister-btn[data-alpha]").forEach((btn) => { btn.addEventListener("click", () => { const alpha = btn.dataset.alpha; const key = btn.dataset.key; switchAlphabet(alpha, key); }); }); } // ── Selection ───────────────────────────────────────────────────────── function selectLetter(key) { browserUi.selectLetter(key); } // ── Alphabet switching ──────────────────────────────────────────────── function switchAlphabet(alpha, selectKey) { browserUi.switchAlphabet(alpha, selectKey); } function updateTabs() { browserUi.updateTabs(); } function resetDetail() { browserUi.resetDetail(); } // ── Public init ─────────────────────────────────────────────────────── function ensureAlphabetSection(magickDataset, referenceData = null) { const grouped = magickDataset?.grouped || {}; const alphabetData = (grouped["alphabets"] && grouped["alphabets"]["hebrew"]) ? grouped["alphabets"] : null; if (alphabetData) { state.alphabets = alphabetData; alphabetGematriaUi.refreshScriptMap?.(); } state.fourWorldLayers = buildFourWorldLayersFromDataset(magickDataset); state.cubeRefs = buildCubeReferences(magickDataset); if (referenceData && state.alphabets) { state.monthRefsByHebrewId = buildMonthReferencesByHebrew(referenceData, state.alphabets); } if (state.initialized) { ensureGematriaCalculator(); syncFilterControls(); renderList(); const letters = getFilteredLetters(); const selected = letters.find((entry) => letterKey(entry) === state.selectedKey) || letters[0]; if (selected) { renderDetail(selected); } else { resetDetail(); if (detailSubEl) { detailSubEl.textContent = "No letters match the current filter."; } } return; } state.initialized = true; // alphabets.json is a top-level file → grouped["alphabets"] = the data object getElements(); ensureGematriaCalculator(); bindFilterControls(); syncFilterControls(); if (!state.alphabets) { if (detailSubEl) detailSubEl.textContent = "Alphabet data not loaded."; return; } // Attach tab listeners [tabAll, tabHebrew, tabGreek, tabEnglish, tabArabic, tabEnochian].forEach((btn) => { if (!btn) return; btn.addEventListener("click", () => { switchAlphabet(btn.dataset.alpha, null); }); }); switchAlphabet("all", null); } // ── Incoming navigation ─────────────────────────────────────────────── function selectLetterByHebrewId(hebrewLetterId) { switchAlphabet("hebrew", hebrewLetterId); } function selectGreekLetterByName(name) { switchAlphabet("greek", name); } function selectEnglishLetter(letter) { switchAlphabet("english", letter); } function selectArabicLetter(name) { switchAlphabet("arabic", name); } function selectEnochianLetter(id) { switchAlphabet("enochian", id); } window.AlphabetSectionUi = { ensureAlphabetSection, selectLetterByHebrewId, selectGreekLetterByName, selectEnglishLetter, selectArabicLetter, selectEnochianLetter }; })();