diff --git a/app.js b/app.js index 97d6909..a5bf17f 100644 --- a/app.js +++ b/app.js @@ -31,6 +31,7 @@ const appRuntime = window.TarotAppRuntime || {}; const statusEl = document.getElementById("status"); const monthStripEl = document.getElementById("month-strip"); const calendarEl = document.getElementById("calendar"); +const timelineSectionEl = document.getElementById("timeline-section"); const calendarSectionEl = document.getElementById("calendar-section"); const holidaySectionEl = document.getElementById("holiday-section"); const tarotSectionEl = document.getElementById("tarot-section"); @@ -44,12 +45,15 @@ const kabbalahSectionEl = document.getElementById("kabbalah-section"); const kabbalahTreeSectionEl = document.getElementById("kabbalah-tree-section"); const cubeSectionEl = document.getElementById("cube-section"); const alphabetSectionEl = document.getElementById("alphabet-section"); +const alphabetLettersSectionEl = document.getElementById("alphabet-letters-section"); const numbersSectionEl = document.getElementById("numbers-section"); const zodiacSectionEl = document.getElementById("zodiac-section"); const quizSectionEl = document.getElementById("quiz-section"); const godsSectionEl = document.getElementById("gods-section"); const enochianSectionEl = document.getElementById("enochian-section"); +const openHomeEl = document.getElementById("open-home"); const openCalendarEl = document.getElementById("open-calendar"); +const openCalendarTimelineEl = document.getElementById("open-calendar-timeline"); const openCalendarMonthsEl = document.getElementById("open-calendar-months"); const openHolidaysEl = document.getElementById("open-holidays"); const openTarotEl = document.getElementById("open-tarot"); @@ -62,6 +66,7 @@ const openKabbalahEl = document.getElementById("open-kabbalah"); const openKabbalahTreeEl = document.getElementById("open-kabbalah-tree"); const openKabbalahCubeEl = document.getElementById("open-kabbalah-cube"); const openAlphabetEl = document.getElementById("open-alphabet"); +const openAlphabetLettersEl = document.getElementById("open-alphabet-letters"); const openNumbersEl = document.getElementById("open-numbers"); const openZodiacEl = document.getElementById("open-zodiac"); const openNatalEl = document.getElementById("open-natal"); @@ -72,6 +77,7 @@ const latEl = document.getElementById("lat"); const lngEl = document.getElementById("lng"); const nowSkyLayerEl = document.getElementById("now-sky-layer"); const nowPanelEl = document.getElementById("now-panel"); +const nowOverlayToggleEl = document.getElementById("now-overlay-toggle"); const connectionGateEl = document.getElementById("connection-gate"); const connectionGateBaseUrlEl = document.getElementById("connection-gate-base-url"); const connectionGateApiKeyEl = document.getElementById("connection-gate-api-key"); @@ -386,6 +392,7 @@ sectionStateUi.init?.({ calendarEl, monthStripEl, nowPanelEl, + timelineSectionEl, calendarSectionEl, holidaySectionEl, tarotSectionEl, @@ -399,12 +406,15 @@ sectionStateUi.init?.({ kabbalahTreeSectionEl, cubeSectionEl, alphabetSectionEl, + alphabetLettersSectionEl, numbersSectionEl, zodiacSectionEl, quizSectionEl, godsSectionEl, enochianSectionEl, + openHomeEl, openCalendarEl, + openCalendarTimelineEl, openCalendarMonthsEl, openHolidaysEl, openTarotEl, @@ -417,6 +427,7 @@ sectionStateUi.init?.({ openKabbalahTreeEl, openKabbalahCubeEl, openAlphabetEl, + openAlphabetLettersEl, openNumbersEl, openZodiacEl, openNatalEl, @@ -475,6 +486,16 @@ homeUi.init?.({ nowPanelEl, getCurrentGeo: () => appRuntime.getCurrentGeo?.() || null }); + +if (nowOverlayToggleEl && nowPanelEl) { + const syncNowOverlayVisibility = () => { + nowPanelEl.classList.toggle("is-overlay-hidden", !nowOverlayToggleEl.checked); + }; + + nowOverlayToggleEl.addEventListener("change", syncNowOverlayVisibility); + syncNowOverlayVisibility(); +} + navigationUi.init?.({ tarotSpreadUi, getActiveSection: () => sectionStateUi.getActiveSection?.() || "home", @@ -484,7 +505,9 @@ navigationUi.init?.({ normalizeNumberValue, selectNumberEntry, elements: { + openHomeEl, openCalendarEl, + openCalendarTimelineEl, openCalendarMonthsEl, openHolidaysEl, openTarotEl, @@ -497,6 +520,7 @@ navigationUi.init?.({ openKabbalahTreeEl, openKabbalahCubeEl, openAlphabetEl, + openAlphabetLettersEl, openNumbersEl, openZodiacEl, openNatalEl, diff --git a/app/data-service.js b/app/data-service.js index 92aa64c..450d072 100644 --- a/app/data-service.js +++ b/app/data-service.js @@ -366,6 +366,12 @@ })); } + async function loadGematriaWordsByValue(value) { + return fetchJson(buildApiUrl("/api/v1/gematria/words", { + value + })); + } + async function loadDeckOptions(forceRefresh = false) { if (!forceRefresh && deckOptionsCache) { return deckOptionsCache; @@ -495,6 +501,7 @@ isApiEnabled, loadDeckManifest, loadDeckOptions, + loadGematriaWordsByValue, loadQuizCategories, loadQuizTemplates, loadTarotCards, diff --git a/app/styles.css b/app/styles.css index bdc2445..e125a68 100644 --- a/app/styles.css +++ b/app/styles.css @@ -10,6 +10,7 @@ font-family: system-ui, -apple-system, "Segoe UI", Roboto, var(--font-script-main); background: #0f0f14; color: #f4f4f5; + overflow-x: hidden; } .topbar { padding: 12px 16px; @@ -19,11 +20,39 @@ gap: 10px; border-bottom: 1px solid #27272a; background: #18181b; + min-width: 0; + overflow: hidden; + } + .topbar-home-button { + padding: 0; + border: 0; + background: transparent; + color: #f4f4f5; + cursor: pointer; + font-size: 18px; + font-weight: 700; + letter-spacing: 0.01em; + flex: 0 0 auto; + } + .topbar-home-button:hover { + color: #fbbf24; + } + .topbar-home-button[aria-pressed="true"] { + color: #fbbf24; } .topbar-actions { display: flex; align-items: center; gap: 8px; + flex: 1 1 auto; + min-width: 0; + justify-content: flex-start; + overflow-x: auto; + overflow-y: hidden; + padding-bottom: 2px; + } + .topbar-actions::-webkit-scrollbar { + height: 6px; } .topbar-dropdown { position: relative; @@ -138,19 +167,19 @@ color: #86efac; } .connection-gate-status[data-tone="pending"] { - color: #fcd34d; + color: #fde68a; } .connection-gate-actions { display: flex; - flex-wrap: wrap; justify-content: flex-end; - gap: 10px; - margin-top: 18px; + gap: 12px; + margin-top: 16px; } .connection-gate-actions button { - padding: 9px 14px; - border-radius: 8px; + appearance: none; border: 1px solid #3f3f46; + border-radius: 10px; + padding: 10px 14px; background: #27272a; color: #f4f4f5; cursor: pointer; @@ -159,13 +188,12 @@ background: #3f3f46; } #connection-gate-connect { - border-color: #d97706; - background: linear-gradient(180deg, #f59e0b, #d97706); + border-color: #f59e0b; color: #111827; - font-weight: 700; + background: linear-gradient(180deg, #fbbf24, #ea580c); } #connection-gate-connect:hover { - background: linear-gradient(180deg, #fbbf24, #ea580c); + background: linear-gradient(180deg, #f59e0b, #d97706); } #tarot-section { height: calc(100vh - 61px); @@ -199,6 +227,14 @@ box-sizing: border-box; overflow: hidden; } + #timeline-section { + height: calc(100vh - 61px); + background: #18181b; + box-sizing: border-box; + overflow: hidden; + display: grid; + grid-template-rows: auto minmax(0, 1fr); + } #holiday-section { height: calc(100vh - 61px); background: #18181b; @@ -220,6 +256,9 @@ #calendar-section[hidden] { display: none; } + #timeline-section[hidden] { + display: none; + } #holiday-section[hidden] { display: none; } @@ -2243,31 +2282,64 @@ } /* ── Alphabet section ────────────────────────────────────────────────── */ - #alphabet-section { + #alphabet-section, + #alphabet-letters-section { height: calc(100vh - 61px); background: #18181b; box-sizing: border-box; overflow: hidden; - display: grid; - grid-template-rows: auto minmax(0, 1fr); } - #alphabet-section[hidden] { display: none; } + + #alphabet-section { + overflow: auto; + } + + #alphabet-section[hidden], + #alphabet-letters-section[hidden] { display: none; } + + .alpha-lookup-shell { + min-height: 100%; + padding: 18px 16px 24px; + box-sizing: border-box; + display: grid; + align-items: start; + } .alpha-special-top { - padding: 10px 12px 8px; - border-bottom: 1px solid #27272a; - overflow: auto; - background: #151520; + width: min(1120px, 100%); + margin: 0 auto; + padding: 14px; + border: 1px solid #27272a; + border-radius: 18px; + overflow: visible; + background: linear-gradient(180deg, #171726 0%, #12121a 100%); + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.28); } .alpha-gematria-card { display: grid; + gap: 10px; + } + + .alpha-gematria-toolbar { + display: flex; + justify-content: flex-end; + } + + .alpha-gematria-toggle { + display: inline-flex; + align-items: center; gap: 8px; + color: #d4d4d8; + font-size: 12px; + cursor: pointer; + -webkit-user-select: none; + user-select: none; } .alpha-gematria-controls { display: grid; - grid-template-columns: minmax(200px, 260px) minmax(0, 1fr); + grid-template-columns: minmax(220px, 260px) minmax(0, 1fr); gap: 8px; align-items: start; } @@ -2278,6 +2350,10 @@ min-width: 0; } + .alpha-gematria-field.is-disabled { + opacity: 0.55; + } + .alpha-gematria-field > span { color: #a1a1aa; font-size: 11px; @@ -2316,6 +2392,70 @@ word-break: break-word; } + .alpha-gematria-matches { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 10px; + max-height: min(52vh, 560px); + overflow: auto; + padding-right: 4px; + } + + .alpha-gematria-matches[hidden] { + display: none; + } + + .alpha-gematria-match { + display: grid; + gap: 8px; + padding: 12px; + border: 1px solid #2f2f39; + border-radius: 12px; + background: #0c0c12; + } + + .alpha-gematria-match-word { + color: #f4f4f5; + font-size: 15px; + font-weight: 700; + line-height: 1.2; + } + + .alpha-gematria-match-definition { + color: #d4d4d8; + font-size: 12px; + line-height: 1.45; + } + + .alpha-gematria-match-ciphers { + display: flex; + flex-wrap: wrap; + gap: 6px; + } + + .alpha-gematria-match-cipher { + display: inline-flex; + align-items: center; + padding: 4px 8px; + border: 1px solid #3f3f46; + border-radius: 999px; + background: #18181b; + color: #c4b5fd; + font-size: 11px; + line-height: 1; + } + + .alpha-gematria-match-empty { + grid-column: 1 / -1; + padding: 14px; + border: 1px dashed #3f3f46; + border-radius: 12px; + background: #101018; + color: #a1a1aa; + font-size: 12px; + line-height: 1.45; + } + .alpha-tabs { display: flex; flex-wrap: wrap; @@ -3675,17 +3815,17 @@ border-left: 0; } #now-panel { + --now-square-size: min(85vmin, calc(100vw - 172px), calc(100svh - 92px)); position: relative; overflow: hidden; - padding: 38px 24px 76px; - min-height: clamp(740px, 90vh, 1140px); - background: #1e1e24; + height: calc(100svh - 88px); + min-height: calc(100svh - 88px); + padding: 10px clamp(68px, 14vw, 220px); + background: #090c16; border-bottom: 1px solid #27272a; display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 0; - align-items: start; - align-content: start; + place-items: center; + isolation: isolate; } #now-panel[hidden] { @@ -3694,85 +3834,140 @@ #now-sky-layer { position: absolute; - width: calc(100% + 1360px); - height: calc(100% + 380px); - top: -200px; - left: -830px; + width: max(calc(var(--now-square-size) * 3.25), calc(100% + 420px)); + height: max(calc(var(--now-square-size) * 2.28), calc(100% + 250px)); + top: 50.5%; + left: 44%; + transform: translate(-50%, -50%); + transform-origin: center center; z-index: 0; pointer-events: none; opacity: 1; border: none; - filter: none; + filter: saturate(1.04); background-color: #000; } #now-panel::before { content: ""; - grid-column: 1 / -1; - grid-row: 3; - height: clamp(250px, 31vh, 430px); + position: absolute; + inset: 0; + z-index: 1; pointer-events: none; + background: + radial-gradient(circle at 50% 57%, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.04) 22%, rgba(7, 11, 24, 0) 48%), + radial-gradient(circle at 50% 57%, rgba(6, 10, 22, 0) 0%, rgba(6, 10, 22, 0) 38%, rgba(6, 10, 22, 0.38) 72%, rgba(3, 5, 12, 0.66) 100%); } #now-panel::after { content: ""; position: absolute; inset: 0; - z-index: 1; - background: transparent; + z-index: 2; + background: linear-gradient(180deg, rgba(3, 5, 12, 0.34) 0%, rgba(3, 5, 12, 0.08) 20%, rgba(3, 5, 12, 0.18) 100%); + pointer-events: none; + } + #now-panel.is-overlay-hidden::before, + #now-panel.is-overlay-hidden::after { + opacity: 0; + } + .now-panel-controls { + position: absolute; + top: 14px; + right: clamp(18px, 4vw, 44px); + z-index: 5; + display: flex; + justify-content: flex-end; + } + .now-panel-toggle { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 6px 10px; + border: 1px solid rgba(255, 255, 255, 0.72); + border-radius: 999px; + background: rgba(0, 0, 0, 0.82); + color: #f8fafc; + font-size: 11px; + letter-spacing: 0.04em; + text-transform: uppercase; + -webkit-user-select: none; + user-select: none; + } + .now-panel-toggle input { + margin: 0; + accent-color: #ffffff; + } + .now-panel-square { + position: relative; + z-index: 3; + box-sizing: border-box; + width: var(--now-square-size); + max-width: 780px; + aspect-ratio: 1; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-template-rows: minmax(0, 1.08fr) minmax(0, 0.92fr); + gap: clamp(8px, 1.3vmin, 14px); + padding: clamp(18px, 2.6vmin, 28px) clamp(12px, 1.8vmin, 18px) clamp(14px, 2vmin, 20px); + border-radius: 28px; + background: #000000; + border: 2px solid rgba(255, 255, 255, 0.88); + box-shadow: none; + overflow: hidden; + } + #now-panel.is-overlay-hidden .now-panel-square { + opacity: 0; + visibility: hidden; pointer-events: none; } .now-section { position: relative; - z-index: 2; + z-index: 1; min-width: 0; + min-height: 0; box-sizing: border-box; - padding: 10px 12px 12px; + padding: clamp(8px, 1.3vmin, 12px) clamp(8px, 1.4vmin, 12px) 0; display: flex; flex-direction: column; align-items: center; + justify-content: flex-start; text-align: center; - border-radius: 14px; + border-radius: 0; overflow: hidden; isolation: isolate; border: 0; - box-shadow: 0 8px 18px rgba(0, 0, 0, 0.24); - transition: color 180ms ease, box-shadow 180ms ease; + box-shadow: none; + transition: color 180ms ease, box-shadow 180ms ease, transform 180ms ease; } .now-section::before { - content: ""; - position: absolute; - width: clamp(210px, 56%, 340px); - height: 35%; - left: 50%; - bottom: 6px; - transform: translateX(-50%); - z-index: 0; - pointer-events: none; - opacity: 0.74; - border-radius: 999px; - background: - radial-gradient(56% 58% at 24% 44%, rgba(26, 32, 47, 0.64) 0%, rgba(26, 32, 47, 0.24) 62%, transparent 100%), - radial-gradient(52% 56% at 78% 40%, rgba(2, 6, 23, 0.58) 0%, rgba(2, 6, 23, 0.22) 62%, transparent 100%), - radial-gradient(64% 70% at 50% 72%, rgba(8, 12, 28, 0.54) 0%, rgba(8, 12, 28, 0.2) 64%, transparent 100%); - filter: saturate(0.92); + display: none; } .now-section > * { position: relative; z-index: 1; } + .now-section-hour { + grid-area: 1 / 1; + } + .now-section-moon { + grid-area: 1 / 2; + } + .now-section-decan { + grid-area: 1 / 3; + } #now-panel.is-day .now-section { - color: #111827; - box-shadow: 0 7px 16px rgba(15, 23, 42, 0.14); + color: #f8fafc; + background: transparent; + border-color: transparent; + box-shadow: none; } #now-panel.is-day .now-section::before { - background: - radial-gradient(56% 58% at 24% 44%, rgba(255, 255, 255, 0.86) 0%, rgba(255, 255, 255, 0.34) 62%, transparent 100%), - radial-gradient(52% 56% at 78% 40%, rgba(255, 255, 255, 0.82) 0%, rgba(255, 255, 255, 0.3) 62%, transparent 100%), - radial-gradient(64% 70% at 50% 72%, rgba(241, 245, 249, 0.74) 0%, rgba(226, 232, 240, 0.28) 64%, transparent 100%); - filter: saturate(1.02); + display: none; } #now-panel.is-night .now-section { color: #f8fafc; - box-shadow: 0 9px 20px rgba(0, 0, 0, 0.34); + background: transparent; + border-color: transparent; + box-shadow: none; } #now-panel.is-day .now-title, #now-panel.is-day .now-tarot, @@ -3780,8 +3975,8 @@ #now-panel.is-day .now-countdown-next, #now-panel.is-day .now-countdown-value, #now-panel.is-day .now-primary { - color: #111827; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3); + color: #f8fafc; + text-shadow: 0 1px 3px rgba(2, 6, 23, 0.75); } #now-panel.is-day .now-primary-hour { color: #581c87; @@ -3805,11 +4000,12 @@ text-shadow: 0 1px 3px rgba(2, 6, 23, 0.75); } .now-card { - margin: 6px 0 10px 0; - width: 150px; - height: 225px; + margin: 2px 0 6px 0; + width: min(64%, 144px); + height: auto; + aspect-ratio: 2 / 3; object-fit: cover; - border-radius: 6px; + border-radius: 8px; border: 1px solid #3f3f46; display: none; } @@ -3822,14 +4018,15 @@ box-shadow: 0 10px 22px rgba(2, 6, 23, 0.58); } .now-countdown-row { - margin-top: 4px; - width: min(100%, 340px); + margin-top: 2px; + width: min(100%, 220px); display: grid; - grid-template-columns: 130px 1fr; - column-gap: 10px; + grid-template-columns: auto minmax(0, 1fr); + column-gap: 6px; align-items: center; - color: #a1a1aa; - font-size: 12px; + color: #cbd5e1; + font-size: 14px; + line-height: 1.18; text-align: left; } .now-countdown-value { @@ -3839,72 +4036,85 @@ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; } .now-countdown-next { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + white-space: normal; + overflow: visible; + text-overflow: clip; } .now-title { - font-size: 11px; - color: #a1a1aa; + font-size: 12px; + color: #cbd5e1; text-transform: uppercase; letter-spacing: 0.05em; - margin-bottom: 4px; + line-height: 1.12; + margin-bottom: 0; } .now-stats-section { position: relative; - z-index: 2; + z-index: 1; grid-column: 1 / -1; grid-row: 2; - margin-top: 10px; - border-radius: 14px; - padding: 12px 14px; - background: rgba(15, 23, 42, 0.42); - border: 1px solid rgba(148, 163, 184, 0.35); - box-shadow: 0 8px 18px rgba(0, 0, 0, 0.24); + min-width: 0; + min-height: 0; + border-radius: 0; + padding: clamp(8px, 1.25vmin, 12px) clamp(12px, 1.8vmin, 18px) 0; + background: transparent; + border: 0; + box-shadow: none; display: grid; - gap: 8px; + grid-template-columns: minmax(0, 1fr); + grid-template-rows: auto auto auto; + gap: 4px; + overflow: auto; } .now-stats-title { - font-size: 11px; - color: #cbd5e1; + font-size: 14px; + line-height: 1.08; + color: #e2e8f0; text-transform: uppercase; - letter-spacing: 0.06em; + letter-spacing: 0.07em; font-weight: 700; } .now-stats-sabian { - font-size: 14px; - font-weight: 600; - line-height: 1.4; + font-size: clamp(17px, 2.5vmin, 23px); + font-weight: 550; + line-height: 1.32; color: #f8fafc; white-space: pre-line; + overflow: visible; + max-height: none; } .now-stats-planets { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 6px 10px; - font-size: 13px; - line-height: 1.35; + gap: 4px 12px; + font-size: clamp(15px, 1.9vmin, 17px); + line-height: 1.3; color: #e2e8f0; + align-content: start; + min-height: 0; + overflow: visible; } .now-stats-planet { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + white-space: normal; + overflow: visible; + text-overflow: clip; + overflow-wrap: anywhere; + line-height: 1.28; font-variant-numeric: tabular-nums; } #now-panel.is-day .now-stats-section { - background: rgba(255, 255, 255, 0.58); - border-color: rgba(15, 23, 42, 0.2); - box-shadow: 0 7px 16px rgba(15, 23, 42, 0.12); + background: transparent; + border-color: transparent; + box-shadow: none; } #now-panel.is-day .now-stats-title { - color: #475569; - text-shadow: none; + color: #e2e8f0; + text-shadow: 0 1px 3px rgba(2, 6, 23, 0.75); } #now-panel.is-day .now-stats-sabian, #now-panel.is-day .now-stats-planets { - color: #0f172a; - text-shadow: none; + color: #f8fafc; + text-shadow: 0 1px 3px rgba(2, 6, 23, 0.75); } #now-panel.is-night .now-stats-title, #now-panel.is-night .now-stats-sabian, @@ -3912,8 +4122,9 @@ text-shadow: 0 1px 3px rgba(2, 6, 23, 0.75); } .now-primary { - font-size: 20px; + font-size: clamp(16px, 2.4vmin, 24px); font-weight: 600; + line-height: 1.15; } .now-primary-hour { color: #a855f7; @@ -3925,9 +4136,10 @@ color: #f97316; } .now-tarot { - font-size: 13px; + font-size: clamp(12px, 1.7vmin, 16px); color: #d4d4d8; - margin-top: 2px; + line-height: 1.12; + margin-top: 1px; } .toastui-calendar-timegrid-time-column .toastui-calendar-timegrid-current-time { @@ -4214,9 +4426,37 @@ opacity: 0; } - .toastui-calendar-timegrid { - height: 240%; - min-height: 1200px; + .toastui-calendar-layout.toastui-calendar-week-view { + height: 100% !important; + min-height: 0; + display: grid; + grid-template-rows: 52px minmax(0, 1fr); + } + + .toastui-calendar-layout.toastui-calendar-week-view > .toastui-calendar-panel.toastui-calendar-allday, + .toastui-calendar-layout.toastui-calendar-week-view > :has(> .toastui-calendar-panel-resizer) { + display: none !important; + } + + .toastui-calendar-allday-panel, + .toastui-calendar-panel.toastui-calendar-allday, + .toastui-calendar-panel.toastui-calendar-allday .toastui-calendar-panel-title, + .toastui-calendar-panel.toastui-calendar-allday .toastui-calendar-panel-grid-wrapper, + .toastui-calendar-panel.toastui-calendar-allday .toastui-calendar-panel-allday-events { + display: none !important; + } + + .toastui-calendar-layout.toastui-calendar-week-view > .toastui-calendar-panel.toastui-calendar-time { + grid-row: 2; + height: auto !important; + min-height: 0; + overflow: hidden !important; + } + + .toastui-calendar-timegrid, + .toastui-calendar-timegrid-scroll-area { + height: 100% !important; + min-height: 0 !important; } .toastui-calendar-event-time { @@ -4268,6 +4508,19 @@ } @media (max-width: 900px) { + #now-panel { + --now-square-size: min(calc(100vw - 110px), calc(100svh - 94px)); + padding: 8px clamp(30px, 8vw, 82px); + } + .now-panel-square { + border-radius: 22px; + } + .now-card { + width: min(64%, 122px); + } + .now-stats-planets { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } .planet-layout { grid-template-columns: minmax(0, 1fr); } @@ -4283,6 +4536,114 @@ } } - #calendar { - height: calc(100vh - 96px); + @media (max-width: 640px) { + #now-panel { + --now-square-size: min(calc(100vw - 74px), calc(100svh - 90px)); + padding: 6px clamp(20px, 6vw, 44px); + } + .now-panel-square { + gap: 6px; + padding: 6px; + } + .now-section { + padding: 7px; + } + .now-card { + width: min(60%, 96px); + } + .now-primary { + font-size: clamp(12px, 3vw, 16px); + } + .now-countdown-row { + width: 100%; + grid-template-columns: minmax(0, 1fr); + gap: 2px; + font-size: 10px; + text-align: center; + } + .now-countdown-value, + .now-countdown-next { + text-align: center; + } + .now-stats-planets { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + } + + @media (max-width: 480px) { + #now-panel { + --now-square-size: min(calc(100vw - 46px), calc(100svh - 86px)); + } + .now-panel-square { + border-radius: 18px; + } + .now-section, + .now-stats-section { + border-radius: 16px; + padding: 7px; + } + .now-title, + .now-stats-title { + font-size: 9px; + } + .now-tarot, + .now-stats-sabian, + .now-stats-planets { + font-size: 10px; + } + .now-stats-planets { + grid-template-columns: minmax(0, 1fr); + } + } + + @media (max-height: 520px) { + #now-panel { + --now-square-size: min(76vmin, calc(100vw - 78px), calc(100svh - 108px)); + height: calc(100svh - 101px); + min-height: calc(100svh - 101px); + padding: 6px clamp(28px, 9vw, 72px); + } + .now-panel-square { + grid-template-rows: minmax(0, 0.92fr) minmax(0, 1.08fr); + gap: 6px; + padding: 16px 6px 8px; + border-radius: 18px; + } + .now-section, + .now-stats-section { + border-radius: 16px; + padding: 6px; + } + .now-card { + width: min(66%, 92px); + margin-bottom: 6px; + } + .now-title { + font-size: 8px; + } + .now-primary { + font-size: 15px; + } + .now-stats-title { + font-size: 11px; + } + .now-stats-sabian { + font-size: 11px; + line-height: 1.42; + } + .now-stats-planets { + font-size: 11px; + line-height: 1.42; + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .now-tarot, + .now-countdown-row { + display: none; + } + } + + #calendar { + height: 100%; + min-height: 0; + overflow: hidden; } diff --git a/app/ui-alphabet-gematria.js b/app/ui-alphabet-gematria.js index 2ba1a69..0d6ef9d 100644 --- a/app/ui-alphabet-gematria.js +++ b/app/ui-alphabet-gematria.js @@ -8,7 +8,11 @@ cipherEl: null, inputEl: null, resultEl: null, - breakdownEl: null + breakdownEl: null, + modeToggleEl: null, + matchesEl: null, + inputLabelEl: null, + cipherLabelEl: null }) }; @@ -17,8 +21,12 @@ db: null, listenersBound: false, activeCipherId: "", - inputText: "", - scriptCharMap: new Map() + forwardInputText: "", + reverseInputText: "", + activeMode: "forward", + scriptCharMap: new Map(), + reverseLookupCache: new Map(), + reverseRequestId: 0 }; function getAlphabets() { @@ -34,10 +42,32 @@ cipherEl: null, inputEl: null, resultEl: null, - breakdownEl: null + breakdownEl: null, + modeToggleEl: null, + matchesEl: null, + inputLabelEl: null, + cipherLabelEl: null }; } + function isReverseMode() { + return state.activeMode === "reverse"; + } + + function getCurrentInputText() { + return isReverseMode() + ? state.reverseInputText + : state.forwardInputText; + } + + function formatCount(value) { + const numericValue = Number(value); + if (!Number.isFinite(numericValue)) { + return "0"; + } + return numericValue.toLocaleString(); + } + function getFallbackGematriaDb() { return { baseAlphabet: "abcdefghijklmnopqrstuvwxyz", @@ -47,6 +77,12 @@ name: "Simple Ordinal", description: "A=1 ... Z=26", values: Array.from({ length: 26 }, (_, index) => index + 1) + }, + { + id: "decadic-cipher", + name: "Decadic Cipher", + description: "A=1 ... I=9, J=10 ... R=90, S=100 ... Z=800", + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800] } ] }; @@ -238,6 +274,221 @@ cipherEl.value = state.activeCipherId; } + function setMatchesMessage(matchesEl, message) { + if (!matchesEl) { + return; + } + + matchesEl.replaceChildren(); + const emptyEl = document.createElement("div"); + emptyEl.className = "alpha-gematria-match-empty"; + emptyEl.textContent = message; + matchesEl.appendChild(emptyEl); + } + + function clearReverseMatches(matchesEl) { + if (!matchesEl) { + return; + } + + matchesEl.replaceChildren(); + matchesEl.hidden = true; + } + + function updateModeUi() { + const { + cipherEl, + inputEl, + modeToggleEl, + matchesEl, + inputLabelEl, + cipherLabelEl + } = getElements(); + + const reverseMode = isReverseMode(); + + if (modeToggleEl) { + modeToggleEl.checked = reverseMode; + } + + if (inputLabelEl) { + inputLabelEl.textContent = reverseMode ? "Value" : "Text"; + } + + if (cipherLabelEl) { + cipherLabelEl.textContent = reverseMode ? "Cipher (disabled in reverse mode)" : "Cipher"; + } + + if (cipherEl) { + cipherEl.disabled = reverseMode; + cipherEl.closest(".alpha-gematria-field")?.classList.toggle("is-disabled", reverseMode); + } + + if (inputEl) { + inputEl.placeholder = reverseMode ? "Enter a whole number, e.g. 33" : "Type or paste text"; + inputEl.inputMode = reverseMode ? "numeric" : "text"; + inputEl.spellcheck = !reverseMode; + + const nextValue = getCurrentInputText(); + if (inputEl.value !== nextValue) { + inputEl.value = nextValue; + } + } + + if (!reverseMode) { + clearReverseMatches(matchesEl); + } + } + + function parseReverseLookupValue(rawValue) { + const normalizedValue = String(rawValue || "").trim(); + if (!normalizedValue) { + return null; + } + + if (!/^\d+$/.test(normalizedValue)) { + return Number.NaN; + } + + const numericValue = Number(normalizedValue); + if (!Number.isSafeInteger(numericValue)) { + return Number.NaN; + } + + return numericValue; + } + + async function loadReverseLookup(value) { + const cacheKey = String(value); + if (state.reverseLookupCache.has(cacheKey)) { + return state.reverseLookupCache.get(cacheKey); + } + + const payload = await window.TarotDataService?.loadGematriaWordsByValue?.(value); + state.reverseLookupCache.set(cacheKey, payload); + return payload; + } + + function renderReverseLookupMatches(payload, numericValue) { + const { resultEl, breakdownEl, matchesEl } = getElements(); + if (!resultEl || !breakdownEl || !matchesEl) { + return; + } + + const matches = Array.isArray(payload?.matches) ? payload.matches : []; + const count = Number(payload?.count); + const displayCount = Number.isFinite(count) ? count : matches.length; + const ciphers = Array.isArray(payload?.ciphers) ? payload.ciphers : []; + const cipherCount = Number(payload?.cipherCount); + const displayCipherCount = Number.isFinite(cipherCount) ? cipherCount : ciphers.length; + const visibleMatches = matches.slice(0, 120); + + resultEl.textContent = `Value: ${formatCount(numericValue)}`; + + if (!displayCount) { + breakdownEl.textContent = "No words matched this reverse gematria value."; + matchesEl.hidden = false; + setMatchesMessage(matchesEl, "No matches found in the reverse gematria index."); + return; + } + + const topCipherSummary = ciphers + .slice(0, 6) + .map((cipher) => `${String(cipher?.name || cipher?.id || "Unknown")} ${formatCount(cipher?.count)}`) + .join(" · "); + + breakdownEl.textContent = `Found ${formatCount(displayCount)} matches across ${formatCount(displayCipherCount)} ciphers.${topCipherSummary ? ` Top ciphers: ${topCipherSummary}.` : ""}${displayCount > visibleMatches.length ? ` Showing first ${formatCount(visibleMatches.length)}.` : ""}`; + + const fragment = document.createDocumentFragment(); + visibleMatches.forEach((match) => { + const cardEl = document.createElement("article"); + cardEl.className = "alpha-gematria-match"; + + const wordEl = document.createElement("div"); + wordEl.className = "alpha-gematria-match-word"; + wordEl.textContent = String(match?.word || "--"); + cardEl.appendChild(wordEl); + + const definition = String(match?.definition || "").trim(); + if (definition) { + const definitionEl = document.createElement("div"); + definitionEl.className = "alpha-gematria-match-definition"; + definitionEl.textContent = definition; + cardEl.appendChild(definitionEl); + } + + const ciphersEl = document.createElement("div"); + ciphersEl.className = "alpha-gematria-match-ciphers"; + const matchCiphers = Array.isArray(match?.ciphers) ? match.ciphers : []; + matchCiphers.slice(0, 6).forEach((cipher) => { + const chipEl = document.createElement("span"); + chipEl.className = "alpha-gematria-match-cipher"; + chipEl.textContent = String(cipher?.name || cipher?.id || "Unknown"); + ciphersEl.appendChild(chipEl); + }); + if (matchCiphers.length > 6) { + const extraEl = document.createElement("span"); + extraEl.className = "alpha-gematria-match-cipher"; + extraEl.textContent = `+${matchCiphers.length - 6} more`; + ciphersEl.appendChild(extraEl); + } + cardEl.appendChild(ciphersEl); + + fragment.appendChild(cardEl); + }); + + matchesEl.replaceChildren(fragment); + matchesEl.hidden = false; + } + + async function renderReverseLookupResult() { + const { resultEl, breakdownEl, matchesEl } = getElements(); + if (!resultEl || !breakdownEl || !matchesEl) { + return; + } + + const rawValue = state.reverseInputText; + if (!String(rawValue || "").trim()) { + resultEl.textContent = "Value: --"; + breakdownEl.textContent = "Enter a whole number to find words across all available ciphers."; + matchesEl.hidden = false; + setMatchesMessage(matchesEl, "Reverse lookup searches the API-backed gematria word index."); + return; + } + + const numericValue = parseReverseLookupValue(rawValue); + if (!Number.isFinite(numericValue)) { + resultEl.textContent = "Value: --"; + breakdownEl.textContent = "Enter digits only to search the reverse gematria index."; + matchesEl.hidden = false; + setMatchesMessage(matchesEl, "Use a whole number such as 33 or 418."); + return; + } + + const requestId = state.reverseRequestId + 1; + state.reverseRequestId = requestId; + resultEl.textContent = `Value: ${formatCount(numericValue)}`; + breakdownEl.textContent = "Searching reverse gematria index..."; + matchesEl.hidden = false; + setMatchesMessage(matchesEl, "Loading matching words..."); + + try { + const payload = await loadReverseLookup(numericValue); + if (requestId !== state.reverseRequestId || !isReverseMode()) { + return; + } + renderReverseLookupMatches(payload, numericValue); + } catch { + if (requestId !== state.reverseRequestId || !isReverseMode()) { + return; + } + resultEl.textContent = `Value: ${formatCount(numericValue)}`; + breakdownEl.textContent = "Reverse lookup is unavailable right now."; + matchesEl.hidden = false; + setMatchesMessage(matchesEl, "Unable to load reverse gematria words from the API."); + } + } + function computeGematria(text, cipher, baseAlphabet) { const normalizedInput = normalizeGematriaText(text); const scriptMap = state.scriptCharMap instanceof Map @@ -281,7 +532,7 @@ }; } - function renderGematriaResult() { + function renderForwardGematriaResult() { const { resultEl, breakdownEl } = getElements(); if (!resultEl || !breakdownEl) { return; @@ -299,7 +550,7 @@ return; } - const { total, count, breakdown } = computeGematria(state.inputText, cipher, db.baseAlphabet); + const { total, count, breakdown } = computeGematria(state.forwardInputText, cipher, db.baseAlphabet); resultEl.textContent = `Total: ${total}`; if (!count) { @@ -310,8 +561,19 @@ breakdownEl.textContent = `${cipher.name} · ${count} letters · ${breakdown} = ${total}`; } + function renderGematriaResult() { + updateModeUi(); + + if (isReverseMode()) { + void renderReverseLookupResult(); + return; + } + + renderForwardGematriaResult(); + } + function bindGematriaListeners() { - const { cipherEl, inputEl } = getElements(); + const { cipherEl, inputEl, modeToggleEl } = getElements(); if (state.listenersBound || !cipherEl || !inputEl) { return; } @@ -322,7 +584,17 @@ }); inputEl.addEventListener("input", () => { - state.inputText = inputEl.value || ""; + if (isReverseMode()) { + state.reverseInputText = inputEl.value || ""; + } else { + state.forwardInputText = inputEl.value || ""; + } + renderGematriaResult(); + }); + + modeToggleEl?.addEventListener("change", () => { + state.activeMode = modeToggleEl.checked ? "reverse" : "forward"; + updateModeUi(); renderGematriaResult(); }); @@ -336,10 +608,7 @@ } bindGematriaListeners(); - - if (inputEl.value !== state.inputText) { - inputEl.value = state.inputText; - } + updateModeUi(); void loadGematriaDb().then(() => { refreshScriptMap((state.db || getFallbackGematriaDb()).baseAlphabet); diff --git a/app/ui-alphabet.js b/app/ui-alphabet.js index d3fe898..32ecda6 100644 --- a/app/ui-alphabet.js +++ b/app/ui-alphabet.js @@ -52,6 +52,7 @@ let tabAll, tabHebrew, tabGreek, tabEnglish, tabArabic, tabEnochian; let searchInputEl, searchClearEl, typeFilterEl; let gematriaCipherEl, gematriaInputEl, gematriaResultEl, gematriaBreakdownEl; + let gematriaReverseEl, gematriaMatchesEl, gematriaInputLabelEl, gematriaCipherLabelEl; function getElements() { listEl = document.getElementById("alpha-letter-list"); @@ -72,6 +73,10 @@ gematriaInputEl = document.getElementById("alpha-gematria-input"); gematriaResultEl = document.getElementById("alpha-gematria-result"); gematriaBreakdownEl = document.getElementById("alpha-gematria-breakdown"); + gematriaReverseEl = document.getElementById("alpha-gematria-reverse"); + gematriaMatchesEl = document.getElementById("alpha-gematria-matches"); + gematriaInputLabelEl = document.getElementById("alpha-gematria-input-label"); + gematriaCipherLabelEl = document.getElementById("alpha-gematria-cipher-label"); } function getGematriaElements() { @@ -80,7 +85,11 @@ cipherEl: gematriaCipherEl, inputEl: gematriaInputEl, resultEl: gematriaResultEl, - breakdownEl: gematriaBreakdownEl + breakdownEl: gematriaBreakdownEl, + modeToggleEl: gematriaReverseEl, + matchesEl: gematriaMatchesEl, + inputLabelEl: gematriaInputLabelEl, + cipherLabelEl: gematriaCipherLabelEl }; } diff --git a/app/ui-navigation.js b/app/ui-navigation.js index a588d00..bd1a6db 100644 --- a/app/ui-navigation.js +++ b/app/ui-navigation.js @@ -33,6 +33,10 @@ function bindTopLevelNavButtons() { const elements = config.elements || {}; + bindClick(elements.openHomeEl, () => { + setActiveSection("home"); + }); + bindClick(elements.openTarotEl, () => { if (getActiveSection() === "tarot") { setActiveSection("home"); @@ -78,6 +82,10 @@ setActiveSection(getActiveSection() === "alphabet" ? "home" : "alphabet"); }); + bindClick(elements.openAlphabetLettersEl, () => { + setActiveSection(getActiveSection() === "alphabet-letters" ? "home" : "alphabet-letters"); + }); + bindClick(elements.openNumbersEl, () => { setActiveSection(getActiveSection() === "numbers" ? "home" : "numbers"); }); @@ -104,8 +112,12 @@ bindClick(elements.openCalendarEl, () => { const activeSection = getActiveSection(); - const isCalendarMenuActive = activeSection === "calendar" || activeSection === "holidays"; - setActiveSection(isCalendarMenuActive ? "home" : "calendar"); + const isCalendarMenuActive = activeSection === "timeline" || activeSection === "calendar" || activeSection === "holidays"; + setActiveSection(isCalendarMenuActive ? "home" : "timeline"); + }); + + bindClick(elements.openCalendarTimelineEl, () => { + setActiveSection(getActiveSection() === "timeline" ? "home" : "timeline"); }); bindClick(elements.openCalendarMonthsEl, () => { @@ -160,7 +172,7 @@ if (typeof ensure.ensureAlphabetSection === "function" && magickDataset) { ensure.ensureAlphabetSection(magickDataset, referenceData); } - setActiveSection("alphabet"); + setActiveSection("alphabet-letters"); const alphabet = event?.detail?.alphabet; const hebrewLetterId = event?.detail?.hebrewLetterId; diff --git a/app/ui-section-state.js b/app/ui-section-state.js index a02bc2d..dc2bf59 100644 --- a/app/ui-section-state.js +++ b/app/ui-section-state.js @@ -3,6 +3,7 @@ const VALID_SECTIONS = new Set([ "home", + "timeline", "calendar", "holidays", "tarot", @@ -16,6 +17,7 @@ "kabbalah-tree", "cube", "alphabet", + "alphabet-letters", "numbers", "zodiac", "quiz", @@ -80,9 +82,10 @@ const magickDataset = getMagickDataset(); const isHomeOpen = activeSection === "home"; + const isTimelineOpen = activeSection === "timeline"; const isCalendarOpen = activeSection === "calendar"; const isHolidaysOpen = activeSection === "holidays"; - const isCalendarMenuOpen = isCalendarOpen || isHolidaysOpen; + const isCalendarMenuOpen = isTimelineOpen || isCalendarOpen || isHolidaysOpen; const isTarotOpen = activeSection === "tarot"; const isAstronomyOpen = activeSection === "astronomy"; const isPlanetOpen = activeSection === "planets"; @@ -97,11 +100,14 @@ const isCubeOpen = activeSection === "cube"; const isKabbalahMenuOpen = isKabbalahOpen || isKabbalahTreeOpen || isCubeOpen; const isAlphabetOpen = activeSection === "alphabet"; + const isAlphabetLettersOpen = activeSection === "alphabet-letters"; + const isAlphabetMenuOpen = isAlphabetOpen || isAlphabetLettersOpen; const isNumbersOpen = activeSection === "numbers"; const isQuizOpen = activeSection === "quiz"; const isGodsOpen = activeSection === "gods"; const isEnochianOpen = activeSection === "enochian"; + setHidden(elements.timelineSectionEl, !isTimelineOpen); setHidden(elements.calendarSectionEl, !isCalendarOpen); setHidden(elements.holidaySectionEl, !isHolidaysOpen); setHidden(elements.tarotSectionEl, !isTarotOpen); @@ -115,16 +121,17 @@ setHidden(elements.kabbalahTreeSectionEl, !isKabbalahTreeOpen); setHidden(elements.cubeSectionEl, !isCubeOpen); setHidden(elements.alphabetSectionEl, !isAlphabetOpen); + setHidden(elements.alphabetLettersSectionEl, !isAlphabetLettersOpen); setHidden(elements.numbersSectionEl, !isNumbersOpen); setHidden(elements.zodiacSectionEl, !isZodiacOpen); setHidden(elements.quizSectionEl, !isQuizOpen); setHidden(elements.godsSectionEl, !isGodsOpen); setHidden(elements.enochianSectionEl, !isEnochianOpen); setHidden(elements.nowPanelEl, !isHomeOpen); - setHidden(elements.monthStripEl, !isHomeOpen); - setHidden(elements.calendarEl, !isHomeOpen); + setPressed(elements.openHomeEl, isHomeOpen); setPressed(elements.openCalendarEl, isCalendarMenuOpen); + toggleActive(elements.openCalendarTimelineEl, isTimelineOpen); toggleActive(elements.openCalendarMonthsEl, isCalendarOpen); toggleActive(elements.openHolidaysEl, isHolidaysOpen); setPressed(elements.openTarotEl, isTarotOpen); @@ -137,7 +144,8 @@ setPressed(elements.openKabbalahEl, isKabbalahMenuOpen); toggleActive(elements.openKabbalahTreeEl, isKabbalahTreeOpen); toggleActive(elements.openKabbalahCubeEl, isCubeOpen); - setPressed(elements.openAlphabetEl, isAlphabetOpen); + setPressed(elements.openAlphabetEl, isAlphabetMenuOpen); + toggleActive(elements.openAlphabetLettersEl, isAlphabetLettersOpen); setPressed(elements.openNumbersEl, isNumbersOpen); toggleActive(elements.openZodiacEl, isZodiacOpen); toggleActive(elements.openNatalEl, isNatalOpen); @@ -149,6 +157,11 @@ config.settingsUi?.closeSettingsPopup?.(); } + if (isTimelineOpen) { + renderHomeFallback(); + return; + } + if (isCalendarOpen) { ensure.ensureCalendarSection?.(referenceData, magickDataset); return; @@ -198,7 +211,7 @@ return; } - if (isAlphabetOpen) { + if (isAlphabetOpen || isAlphabetLettersOpen) { ensure.ensureAlphabetSection?.(magickDataset, referenceData); return; } @@ -233,7 +246,7 @@ return; } - renderHomeFallback(); + config.homeUi?.syncNowPanelTheme?.(new Date()); } function getActiveSection() { diff --git a/index.html b/index.html index 428494f..2f0b2e1 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ Tarot Time! + @@ -15,15 +16,16 @@ - +
- Tarot Time! +
@@ -53,7 +55,12 @@
- +
+ + +
@@ -617,27 +624,39 @@
+ + + @@ -812,46 +832,57 @@ + +
-
-
Current Planetary Hour
- Current planetary hour card -
--
-
--
-
- -- - > -- -
+
+
-
-
Moon Phase
- Current moon phase card -
--
-
--
-
- -- - > -- +
+
+
Current Planetary Hour
+ Current planetary hour card +
--
+
--
+
+ -- + > -- +
-
-
-
Current Decan (Sun)
- Current decan card -
--
-
--
-
- -- - > -- +
+
Moon Phase
+ Current moon phase card +
--
+
--
+
+ -- + > -- +
+
+
+
Current Decan (Sun)
+ Current decan card +
--
+
--
+
+ -- + > -- +
+
+
+
Current Planet Positions & Sabian Symbol
+
--
+
--
-
-
-
Current Planet Positions & Sabian Symbol
-
--
-
--
- -
@@ -919,12 +950,12 @@ - + - + - + diff --git a/package-lock.json b/package-lock.json index b07ff6d..32b0fdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "@fontsource/noto-sans-hebrew": "^5.2.8", "@fontsource/noto-sans-phoenician": "^5.2.6", "@fontsource/noto-serif": "^5.2.9", + "@toast-ui/calendar": "^2.1.3", "astronomy-engine": "^2.1.19", "suncalc": "^1.9.0" }, @@ -17,6 +18,202 @@ "http-server": "^14.1.1" } }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz", + "integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==", + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "license": "MIT" + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", + "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", + "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.1.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.0.tgz", + "integrity": "sha512-H4tuz2nhWgNKLt1inYpoVCfbJbMwX/lQKp3g69rrrIMIYlFD9+zTykOKhNR8uGrAmbS/kT9n6hTFkmDkxLgeTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, "node_modules/@fontsource/amiri": { "version": "5.2.8", "resolved": "https://registry.npmjs.org/@fontsource/amiri/-/amiri-5.2.8.tgz", @@ -62,6 +259,36 @@ "url": "https://github.com/sponsors/ayuhito" } }, + "node_modules/@toast-ui/calendar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@toast-ui/calendar/-/calendar-2.1.3.tgz", + "integrity": "sha512-QxEf6MhcpqQ3dLSv6pxww1i6Ks/Ejp6mqy8GG7INvNYezmoXeo1IUBN4Cy9zLZeIgQHs02GEfusN5UzB+FyPhg==", + "license": "MIT", + "dependencies": { + "immer": "^9.0.15", + "isomorphic-dompurify": "^0.20.0", + "preact": "^10.10.0", + "preact-render-to-string": "^5.2.1", + "tui-date-picker": "^4.0.1", + "tui-time-picker": "^2.0.1" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -104,6 +331,15 @@ "node": ">= 0.8" } }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -182,11 +418,51 @@ "node": ">= 0.4.0" } }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssstyle": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.2.0.tgz", + "integrity": "sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^5.0.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -200,6 +476,24 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/dompurify": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", + "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", + "license": "(MPL-2.0 OR Apache-2.0)", + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -215,6 +509,18 @@ "node": ">= 0.4" } }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -412,6 +718,19 @@ "node": ">=8.0.0" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/http-server": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", @@ -440,6 +759,19 @@ "node": ">=12" } }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -453,6 +785,96 @@ "node": ">=0.10.0" } }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, + "node_modules/isomorphic-dompurify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-3.0.0.tgz", + "integrity": "sha512-5K+MYP7Nrg74+Bi+QmQGzQ/FgEOyVHWsN8MuJy5wYQxxBRxPnWsD25Tjjt5FWYhan3OQ+vNLubyNJH9dfG03lQ==", + "license": "MIT", + "dependencies": { + "dompurify": "^3.3.1", + "jsdom": "^28.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/jsdom": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.31", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", + "@exodus/bytes": "^1.11.0", + "cssstyle": "^6.0.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "undici": "^7.21.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -463,6 +885,12 @@ "node": ">= 0.4" } }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "license": "CC0-1.0" + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -490,7 +918,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/object-inspect": { @@ -516,6 +943,18 @@ "opener": "bin/opener-bin.js" } }, + "node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/portfinder": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.38.tgz", @@ -530,6 +969,43 @@ "node": ">= 10.12" } }, + "node_modules/preact": { + "version": "10.28.4", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.4.tgz", + "integrity": "sha512-uKFfOHWuSNpRFVTnljsCluEFq57OKT+0QdOiQo8XWnQ/pSvg7OpX5eNOejELXJMWy+BwM2nobz0FkvzmnpCNsQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "license": "MIT", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, + "node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.15.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", @@ -546,6 +1022,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -567,6 +1052,18 @@ "dev": true, "license": "MIT" }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/secure-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", @@ -650,6 +1147,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/suncalc": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.9.0.tgz", @@ -668,6 +1174,78 @@ "node": ">=8" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" + }, + "node_modules/tldts": { + "version": "7.0.25", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.25.tgz", + "integrity": "sha512-keinCnPbwXEUG3ilrWQZU+CqcTTzHq9m2HhoUP2l7Xmi8l1LuijAXLpAJ5zRW+ifKTNscs4NdCkfkDCBYm352w==", + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.25" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.25", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.25.tgz", + "integrity": "sha512-ZjCZK0rppSBu7rjHYDYsEaMOIbbT+nWF57hKkv4IUmZWBNrBWBOjIElc0mKRgLM8bm7x/BBlof6t2gi/Oq/Asw==", + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/tui-date-picker": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tui-date-picker/-/tui-date-picker-4.3.3.tgz", + "integrity": "sha512-/2YoLnj5c1e+Ag1ZZYOgzEs2o0v7Ol7c5UAnBj438zGlkwkMxyH0HwP2pVqqIYX05WE7K0+6nTWVMybS8otBgw==", + "license": "MIT", + "dependencies": { + "tui-time-picker": "^2.1.6" + } + }, + "node_modules/tui-time-picker": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/tui-time-picker/-/tui-time-picker-2.1.6.tgz", + "integrity": "sha512-4Jmo3wjGS+Ii4/qQgt5DaFEohHpB3U6BzWeTODVVFHD9sx3NOsbomY9K0xMobSLODi+tQEH7wfOtNU0IJmcQ6Q==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -687,6 +1265,27 @@ "dev": true, "license": "MIT" }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, "node_modules/whatwg-encoding": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", @@ -700,6 +1299,44 @@ "engines": { "node": ">=12" } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" } } } diff --git a/package.json b/package.json index 4941a23..79e27cd 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,20 @@ "@fontsource/noto-sans-hebrew": "^5.2.8", "@fontsource/noto-sans-phoenician": "^5.2.6", "@fontsource/noto-serif": "^5.2.9", + "@toast-ui/calendar": "^2.1.3", "astronomy-engine": "^2.1.19", "suncalc": "^1.9.0" }, "devDependencies": { "http-server": "^14.1.1" }, + "overrides": { + "isomorphic-dompurify": "3.0.0", + "dompurify": "3.3.2", + "jsdom": "28.1.0", + "http-proxy-agent": "7.0.2", + "@tootallnate/once": "3.0.1" + }, "scripts": { "start": "npx http-server . -o index.html", "dev": "npm run start"