Base64 encode/decode floating toolbar with recursive settings.
// ==UserScript== // @name Base64 Encode Decode // @namespace base64-encode-decode // @version 0.2.0 // @description Base64 encode/decode floating toolbar with recursive settings. // @license ISC // @match https://kone.gg/* // @match https://*.kone.gg/* // @match https://arca.live/* // @match https://*.arca.live/* // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js // @grant GM.getValue // @grant GM.setValue // @grant GM_setClipboard // @grant GM_openInTab // @run-at document-idle // @noframes // ==/UserScript== (function(){var s=document.createElement("style");s.textContent=`/*! * OverlayScrollbars * Version: 2.14.0 * * Copyright (c) Rene Haas | KingSora. * https://github.com/KingSora * * Released under the MIT license. */ .os-size-observer, .os-size-observer-listener { scroll-behavior: auto !important; direction: inherit; pointer-events: none; overflow: hidden; visibility: hidden; box-sizing: border-box; } .os-size-observer, .os-size-observer-listener, .os-size-observer-listener-item, .os-size-observer-listener-item-final { writing-mode: horizontal-tb; position: absolute; left: 0; top: 0; } .os-size-observer { z-index: -1; contain: strict; display: flex; flex-direction: row; flex-wrap: nowrap; padding: inherit; border: inherit; box-sizing: inherit; margin: -133px; top: 0; right: 0; bottom: 0; left: 0; transform: scale(0.1); } .os-size-observer::before { content: ""; flex: none; box-sizing: inherit; padding: 10px; width: 10px; height: 10px; } .os-size-observer-appear { animation: os-size-observer-appear-animation 1ms forwards; } .os-size-observer-listener { box-sizing: border-box; position: relative; flex: auto; padding: inherit; border: inherit; margin: -133px; transform: scale(calc(1 / 0.1)); } .os-size-observer-listener.ltr { margin-right: -266px; margin-left: 0; } .os-size-observer-listener.rtl { margin-left: -266px; margin-right: 0; } .os-size-observer-listener:empty::before { content: ""; width: 100%; height: 100%; } .os-size-observer-listener:empty::before, .os-size-observer-listener > .os-size-observer-listener-item { display: block; position: relative; padding: inherit; border: inherit; box-sizing: content-box; flex: auto; } .os-size-observer-listener-scroll { box-sizing: border-box; display: flex; } .os-size-observer-listener-item { right: 0; bottom: 0; overflow: hidden; direction: ltr; flex: none; } .os-size-observer-listener-item-final { transition: none; } @keyframes os-size-observer-appear-animation { from { cursor: auto; } to { cursor: none; } } .os-trinsic-observer { flex: none; box-sizing: border-box; position: relative; max-width: 0px; max-height: 1px; padding: 0; margin: 0; border: none; overflow: hidden; z-index: -1; height: 0; top: calc(100% + 1px); contain: strict; } .os-trinsic-observer:not(:empty) { height: calc(100% + 1px); top: -1px; } .os-trinsic-observer:not(:empty) > .os-size-observer { width: 1000%; height: 1000%; min-height: 1px; min-width: 1px; } /** * hide native scrollbars * changes to this styles need to be reflected in the environment styles to correctly detect scrollbar hiding */ [data-overlayscrollbars-initialize]:not([data-overlayscrollbars-viewport]), [data-overlayscrollbars-viewport~=scrollbarHidden], html[data-overlayscrollbars-viewport~=scrollbarHidden] > body { scrollbar-width: none !important; } [data-overlayscrollbars-initialize]:not([data-overlayscrollbars-viewport])::-webkit-scrollbar, [data-overlayscrollbars-initialize]:not([data-overlayscrollbars-viewport])::-webkit-scrollbar-corner, [data-overlayscrollbars-viewport~=scrollbarHidden]::-webkit-scrollbar, [data-overlayscrollbars-viewport~=scrollbarHidden]::-webkit-scrollbar-corner, html[data-overlayscrollbars-viewport~=scrollbarHidden] > body::-webkit-scrollbar, html[data-overlayscrollbars-viewport~=scrollbarHidden] > body::-webkit-scrollbar-corner { -webkit-appearance: none !important; appearance: none !important; display: none !important; width: 0 !important; height: 0 !important; } [data-overlayscrollbars-initialize]:not([data-overlayscrollbars]):not(html):not(body) { overflow: auto; } /** * body element */ html[data-overlayscrollbars-body] { overflow: hidden; } html[data-overlayscrollbars-body], html[data-overlayscrollbars-body] > body { width: 100%; height: 100%; margin: 0; } html[data-overlayscrollbars-body] > body { overflow: visible; margin: 0; } /** * structure setup */ [data-overlayscrollbars] { position: relative; } [data-overlayscrollbars~=host], [data-overlayscrollbars-padding] { display: flex; align-items: stretch !important; flex-direction: row !important; flex-wrap: nowrap !important; scroll-behavior: auto !important; } [data-overlayscrollbars-padding], [data-overlayscrollbars-viewport]:not([data-overlayscrollbars]) { box-sizing: inherit; position: relative; flex: auto; height: auto; width: 100%; min-width: 0; padding: 0; margin: 0; border: none; z-index: 0; } [data-overlayscrollbars-viewport]:not([data-overlayscrollbars]) { --os-vaw: 0; --os-vah: 0; outline: none; } [data-overlayscrollbars-viewport]:not([data-overlayscrollbars]):focus { outline: none; } [data-overlayscrollbars-viewport][data-overlayscrollbars-viewport~=arrange]::before { content: ""; position: absolute; pointer-events: none; z-index: -1; min-width: 1px; min-height: 1px; width: var(--os-vaw); height: var(--os-vah); } /** * wrapper elements overflow: */ [data-overlayscrollbars~=host], [data-overlayscrollbars-padding] { overflow: hidden !important; } [data-overlayscrollbars~=host][data-overlayscrollbars~=noClipping], [data-overlayscrollbars-padding~=noClipping] { overflow: visible !important; } /** * viewport overflow: */ [data-overlayscrollbars-viewport] { --os-viewport-overflow-x: hidden; --os-viewport-overflow-y: hidden; overflow-x: var(--os-viewport-overflow-x); overflow-y: var(--os-viewport-overflow-y); } [data-overlayscrollbars-viewport~=overflowXVisible] { --os-viewport-overflow-x: visible; } [data-overlayscrollbars-viewport~=overflowXHidden] { --os-viewport-overflow-x: hidden; } [data-overlayscrollbars-viewport~=overflowXScroll] { --os-viewport-overflow-x: scroll; } [data-overlayscrollbars-viewport~=overflowYVisible] { --os-viewport-overflow-y: visible; } [data-overlayscrollbars-viewport~=overflowYHidden] { --os-viewport-overflow-y: hidden; } [data-overlayscrollbars-viewport~=overflowYScroll] { --os-viewport-overflow-y: scroll; } [data-overlayscrollbars-viewport~=overflowImportant] { overflow-x: var(--os-viewport-overflow-x) !important; overflow-y: var(--os-viewport-overflow-y) !important; } /** * viewport state modifiers: */ [data-overlayscrollbars-viewport~=noContent]:not(#osFakeId) { font-size: 0 !important; line-height: 0 !important; } [data-overlayscrollbars-viewport~=noContent]:not(#osFakeId)::before, [data-overlayscrollbars-viewport~=noContent]:not(#osFakeId)::after, [data-overlayscrollbars-viewport~=noContent]:not(#osFakeId) > *:not(#osFakeId) { display: none !important; position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border-width: 0 !important; } [data-overlayscrollbars-viewport~=measuring], [data-overlayscrollbars-viewport~=scrolling] { scroll-behavior: auto !important; scroll-snap-type: none !important; } [data-overlayscrollbars-viewport~=measuring][data-overlayscrollbars-viewport~=overflowXVisible] { overflow-x: hidden !important; } [data-overlayscrollbars-viewport~=measuring][data-overlayscrollbars-viewport~=overflowYVisible] { overflow-y: hidden !important; } /** * content element: */ [data-overlayscrollbars-content] { box-sizing: inherit; } /** * Display contents to bridge any flickering during deferred initialization. */ [data-overlayscrollbars-contents]:not(#osFakeId):not([data-overlayscrollbars-padding]):not([data-overlayscrollbars-viewport]):not([data-overlayscrollbars-content]) { display: contents; } /** * optional & experimental grid mode */ [data-overlayscrollbars-grid], [data-overlayscrollbars-grid] [data-overlayscrollbars-padding] { display: grid; grid-template: 1fr/1fr; } [data-overlayscrollbars-grid] > [data-overlayscrollbars-padding], [data-overlayscrollbars-grid] > [data-overlayscrollbars-viewport], [data-overlayscrollbars-grid] > [data-overlayscrollbars-padding] > [data-overlayscrollbars-viewport] { height: auto !important; width: auto !important; } @property --os-scroll-percent { syntax: "<number>"; inherits: true; initial-value: 0; } @property --os-viewport-percent { syntax: "<number>"; inherits: true; initial-value: 0; } .os-scrollbar { --os-viewport-percent: 0; --os-scroll-percent: 0; --os-scroll-direction: 0; --os-scroll-percent-directional: calc( var(--os-scroll-percent) - (var(--os-scroll-percent) + (1 - var(--os-scroll-percent)) * -1) * var(--os-scroll-direction) ); } .os-scrollbar { contain: size layout; contain: size layout style; transition: opacity 0.15s, visibility 0.15s, top 0.15s, right 0.15s, bottom 0.15s, left 0.15s; pointer-events: none; position: absolute; opacity: 0; visibility: hidden; } body > .os-scrollbar { position: fixed; z-index: 99999; } .os-scrollbar-transitionless { transition: none !important; } .os-scrollbar-track { position: relative; padding: 0 !important; border: none !important; } .os-scrollbar-handle { position: absolute; } .os-scrollbar-track, .os-scrollbar-handle { pointer-events: none; width: 100%; height: 100%; } .os-scrollbar.os-scrollbar-track-interactive .os-scrollbar-track, .os-scrollbar.os-scrollbar-handle-interactive .os-scrollbar-handle { pointer-events: auto; touch-action: none; } .os-scrollbar-horizontal { bottom: 0; left: 0; } .os-scrollbar-vertical { top: 0; right: 0; } .os-scrollbar-rtl.os-scrollbar-horizontal { right: 0; } .os-scrollbar-rtl.os-scrollbar-vertical { right: auto; left: 0; } .os-scrollbar-visible { opacity: 1; visibility: visible; } .os-scrollbar-auto-hide.os-scrollbar-auto-hide-hidden { opacity: 0; visibility: hidden; } .os-scrollbar-interaction.os-scrollbar-visible { opacity: 1; visibility: visible; } .os-scrollbar-unusable, .os-scrollbar-unusable *, .os-scrollbar-wheel, .os-scrollbar-wheel * { pointer-events: none !important; } .os-scrollbar-unusable .os-scrollbar-handle { opacity: 0 !important; transition: none !important; } .os-scrollbar-horizontal .os-scrollbar-handle { bottom: 0; left: calc(var(--os-scroll-percent-directional) * 100%); transform: translateX(calc(var(--os-scroll-percent-directional) * -100%)); width: calc(var(--os-viewport-percent) * 100%); } .os-scrollbar-vertical .os-scrollbar-handle { right: 0; top: calc(var(--os-scroll-percent-directional) * 100%); transform: translateY(calc(var(--os-scroll-percent-directional) * -100%)); height: calc(var(--os-viewport-percent) * 100%); } @supports (container-type: size) { .os-scrollbar-track { container-type: size; } .os-scrollbar-horizontal .os-scrollbar-handle { left: auto; transform: translateX(calc(var(--os-scroll-percent-directional) * 100cqw + var(--os-scroll-percent-directional) * -100%)); } .os-scrollbar-vertical .os-scrollbar-handle { top: auto; transform: translateY(calc(var(--os-scroll-percent-directional) * 100cqh + var(--os-scroll-percent-directional) * -100%)); } .os-scrollbar-rtl.os-scrollbar-horizontal .os-scrollbar-handle { right: auto; left: 0; } } .os-scrollbar-rtl.os-scrollbar-vertical .os-scrollbar-handle { right: auto; left: 0; } .os-scrollbar.os-scrollbar-horizontal.os-scrollbar-cornerless, .os-scrollbar.os-scrollbar-horizontal.os-scrollbar-cornerless.os-scrollbar-rtl { left: 0; right: 0; } .os-scrollbar.os-scrollbar-vertical.os-scrollbar-cornerless, .os-scrollbar.os-scrollbar-vertical.os-scrollbar-cornerless.os-scrollbar-rtl { top: 0; bottom: 0; } @media print { .os-scrollbar { display: none; } } .os-scrollbar { --os-size: 0; --os-padding-perpendicular: 0; --os-padding-axis: 0; --os-track-border-radius: 0; --os-track-bg: none; --os-track-bg-hover: none; --os-track-bg-active: none; --os-track-border: none; --os-track-border-hover: none; --os-track-border-active: none; --os-handle-border-radius: 0; --os-handle-bg: none; --os-handle-bg-hover: none; --os-handle-bg-active: none; --os-handle-border: none; --os-handle-border-hover: none; --os-handle-border-active: none; --os-handle-min-size: 33px; --os-handle-max-size: none; --os-handle-perpendicular-size: 100%; --os-handle-perpendicular-size-hover: 100%; --os-handle-perpendicular-size-active: 100%; --os-handle-interactive-area-offset: 0; } .os-scrollbar-track { border: var(--os-track-border); border-radius: var(--os-track-border-radius); background: var(--os-track-bg); transition: opacity 0.15s, background-color 0.15s, border-color 0.15s; } .os-scrollbar-track:hover { border: var(--os-track-border-hover); background: var(--os-track-bg-hover); } .os-scrollbar-track:active { border: var(--os-track-border-active); background: var(--os-track-bg-active); } .os-scrollbar-handle { border: var(--os-handle-border); border-radius: var(--os-handle-border-radius); background: var(--os-handle-bg); } .os-scrollbar-handle:hover { border: var(--os-handle-border-hover); background: var(--os-handle-bg-hover); } .os-scrollbar-handle:active { border: var(--os-handle-border-active); background: var(--os-handle-bg-active); } .os-scrollbar-track:before, .os-scrollbar-handle:before { content: ""; position: absolute; left: 0; right: 0; top: 0; bottom: 0; display: block; } .os-scrollbar-horizontal { padding: var(--os-padding-perpendicular) var(--os-padding-axis); right: var(--os-size); height: var(--os-size); } .os-scrollbar-horizontal.os-scrollbar-rtl { left: var(--os-size); right: 0; } .os-scrollbar-horizontal .os-scrollbar-track:before { top: calc(var(--os-padding-perpendicular) * -1); bottom: calc(var(--os-padding-perpendicular) * -1); } .os-scrollbar-horizontal .os-scrollbar-handle { min-width: var(--os-handle-min-size); max-width: var(--os-handle-max-size); height: var(--os-handle-perpendicular-size); transition: opacity 0.15s, background-color 0.15s, border-color 0.15s, height 0.15s; } .os-scrollbar-horizontal .os-scrollbar-handle:before { top: calc((var(--os-padding-perpendicular) + var(--os-handle-interactive-area-offset)) * -1); bottom: calc(var(--os-padding-perpendicular) * -1); } .os-scrollbar-horizontal:hover .os-scrollbar-handle { height: var(--os-handle-perpendicular-size-hover); } .os-scrollbar-horizontal:active .os-scrollbar-handle { height: var(--os-handle-perpendicular-size-active); } .os-scrollbar-vertical { padding: var(--os-padding-axis) var(--os-padding-perpendicular); bottom: var(--os-size); width: var(--os-size); } .os-scrollbar-vertical .os-scrollbar-track:before { left: calc(var(--os-padding-perpendicular) * -1); right: calc(var(--os-padding-perpendicular) * -1); } .os-scrollbar-vertical .os-scrollbar-handle { min-height: var(--os-handle-min-size); max-height: var(--os-handle-max-size); width: var(--os-handle-perpendicular-size); transition: opacity 0.15s, background-color 0.15s, border-color 0.15s, width 0.15s; } .os-scrollbar-vertical .os-scrollbar-handle:before { left: calc((var(--os-padding-perpendicular) + var(--os-handle-interactive-area-offset)) * -1); right: calc(var(--os-padding-perpendicular) * -1); } .os-scrollbar-vertical.os-scrollbar-rtl .os-scrollbar-handle:before { right: calc((var(--os-padding-perpendicular) + var(--os-handle-interactive-area-offset)) * -1); left: calc(var(--os-padding-perpendicular) * -1); } .os-scrollbar-vertical:hover .os-scrollbar-handle { width: var(--os-handle-perpendicular-size-hover); } .os-scrollbar-vertical:active .os-scrollbar-handle { width: var(--os-handle-perpendicular-size-active); } /* NONE THEME: */ [data-overlayscrollbars-viewport~=measuring] > .os-scrollbar, .os-theme-none.os-scrollbar { display: none !important; } /* DARK & LIGHT THEME: */ .os-theme-dark, .os-theme-light { box-sizing: border-box; --os-size: 10px; --os-padding-perpendicular: 2px; --os-padding-axis: 2px; --os-track-border-radius: 10px; --os-handle-interactive-area-offset: 4px; --os-handle-border-radius: 10px; } .os-theme-dark { --os-handle-bg: rgba(0, 0, 0, 0.44); --os-handle-bg-hover: rgba(0, 0, 0, 0.55); --os-handle-bg-active: rgba(0, 0, 0, 0.66); } .os-theme-light { --os-handle-bg: rgba(255, 255, 255, 0.44); --os-handle-bg-hover: rgba(255, 255, 255, 0.55); --os-handle-bg-active: rgba(255, 255, 255, 0.66); }/*\$vite\$:1*/`;document.head.appendChild(s)})(); (function(vue) { //#region src/core/platform/adapter.ts /** Singleton holder — set once at startup by entry point. */ var _adapter = null; function setPlatformAdapter(a) { _adapter = a; } function getAdapter() { if (!_adapter) throw new Error("PlatformAdapter not initialised"); return _adapter; } //#endregion //#region src/core/constants/index.ts var FAB_POSITIONS = [ "top-left", "top-center", "top-right", "middle-left", "middle-right", "bottom-left", "bottom-center", "bottom-right" ]; var COLOR_PRESETS = [ "#2563eb", "#3b82f6", "#0ea5e9", "#06b6d4", "#14b8a6", "#10b981", "#22c55e", "#84cc16", "#eab308", "#f59e0b", "#f97316", "#ef4444", "#e11d48", "#8b5cf6", "#6366f1" ]; //#endregion //#region src/core/utils/settings.ts /** Settings defaults and normalization. No chrome API calls. */ var DEFAULT_SETTINGS = { recursiveDecodeEnabled: true, recursiveDecodeCount: 1, recursiveDecodeForceEnabled: false, recursiveEncodeEnabled: true, recursiveEncodeCount: 1, activateNewTab: true, clearInputOnTabSwitch: false, fabPosition: "bottom-right", accentColor: "#2563eb", language: "en", contextMenuEnabled: true, autoClosePanel: false }; function bool(value, fallback) { return typeof value === "boolean" ? value : fallback; } function clampCount(value) { const n = typeof value === "number" ? value : Number(value); if (!Number.isFinite(n)) return 1; return Math.min(10, Math.max(1, Math.trunc(n))); } function fabPos(value) { return FAB_POSITIONS.includes(value) ? value : DEFAULT_SETTINGS.fabPosition; } function accent(value) { if (typeof value === "string" && /^#[0-9a-fA-F]{6}$/.test(value)) return value; return DEFAULT_SETTINGS.accentColor; } function lang(value) { return [ "en", "ko", "ja" ].includes(value) ? value : DEFAULT_SETTINGS.language; } function normalizeSettings(raw) { const d = DEFAULT_SETTINGS; return { recursiveDecodeEnabled: bool(raw?.recursiveDecodeEnabled, d.recursiveDecodeEnabled), recursiveDecodeCount: clampCount(raw?.recursiveDecodeCount ?? d.recursiveDecodeCount), recursiveDecodeForceEnabled: bool(raw?.recursiveDecodeForceEnabled, d.recursiveDecodeForceEnabled), recursiveEncodeEnabled: bool(raw?.recursiveEncodeEnabled, d.recursiveEncodeEnabled), recursiveEncodeCount: clampCount(raw?.recursiveEncodeCount ?? d.recursiveEncodeCount), activateNewTab: bool(raw?.activateNewTab, d.activateNewTab), clearInputOnTabSwitch: bool(raw?.clearInputOnTabSwitch, d.clearInputOnTabSwitch), fabPosition: fabPos(raw?.fabPosition), accentColor: accent(raw?.accentColor), language: lang(raw?.language), contextMenuEnabled: bool(raw?.contextMenuEnabled, d.contextMenuEnabled), autoClosePanel: bool(raw?.autoClosePanel, d.autoClosePanel) }; } //#endregion //#region src/core/platform/userscript.ts var K_SETTINGS = "b64_settings"; var K_HISTORY = "b64_history"; function sortBuckets(map) { return Object.values(map).sort((a, b) => b.updatedAt - a.updatedAt); } async function readMap() { const raw = await GM.getValue(K_HISTORY, "{}"); try { return JSON.parse(raw); } catch { return {}; } } async function writeMap(map) { await GM.setValue(K_HISTORY, JSON.stringify(map)); } function createUserScriptAdapter() { return { async writeClipboard(text) { try { GM_setClipboard(text, "text"); return true; } catch { return false; } }, async loadSettings() { const raw = await GM.getValue(K_SETTINGS, "{}"); try { return normalizeSettings(JSON.parse(raw)); } catch { return normalizeSettings(void 0); } }, async saveSettings(s) { await GM.setValue(K_SETTINGS, JSON.stringify(s)); }, async listBuckets() { return sortBuckets(await readMap()); }, async addEntry(action, input, output, iterations) { const map = { ...await readMap() }; const url = location.href; let domain; let origin; try { const u = new URL(url); domain = u.hostname.toLowerCase().replace(/^www\./, ""); origin = u.origin; } catch { domain = "unknown"; origin = ""; } const entry = { id: crypto.randomUUID(), action, domain, origin, url, pageTitle: document.title, favIconUrl: document.querySelector("link[rel*=\"icon\"]")?.href ?? "", input, output, iterations, createdAt: Date.now() }; const existing = map[domain]; map[domain] = { domain, origin, updatedAt: entry.createdAt, entries: [entry, ...existing?.entries ?? []].slice(0, 25) }; const trimmed = sortBuckets(map).slice(0, 40); await writeMap(Object.fromEntries(trimmed.map((b) => [b.domain, b]))); }, async clearHistory() { await writeMap({}); }, openTab(url, active) { GM_openInTab(url, { active }); } }; } //#endregion //#region src/core/utils/base64.ts /** Pure Base64 encode/decode functions. No side effects. */ var WHITESPACE = /\s+/g; var BASE64_RE = /^[A-Za-z0-9+/]+={0,2}$/; function compact(s) { return s.trim().replace(WHITESPACE, ""); } function toStandardAlphabet(s) { return s.replace(/-/g, "+").replace(/_/g, "/"); } function pad(s) { const r = s.length % 4; return r === 0 ? s : s + "=".repeat(4 - r); } function stripPad(s) { return s.replace(/=+$/, ""); } function hasControlChars(s) { for (const ch of s) { const c = ch.charCodeAt(0); if (c <= 8 || c === 11 || c === 12 || c >= 14 && c <= 31 || c === 127) return true; } return false; } function encode(text) { const bytes = new TextEncoder().encode(text); let bin = ""; for (let i = 0; i < bytes.length; i += 32768) bin += String.fromCharCode(...bytes.subarray(i, i + 32768)); return btoa(bin); } function decode(raw) { const input = compact(raw); if (!input) return { ok: false, reason: "empty" }; const std = toStandardAlphabet(input); if (!BASE64_RE.test(std) || std.length % 4 === 1) return { ok: false, reason: "invalid-format" }; const padded = pad(std); try { const bin = atob(padded); const bytes = Uint8Array.from(bin, (ch) => ch.charCodeAt(0)); const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes); if (hasControlChars(text)) return { ok: false, reason: "binary" }; if (stripPad(padded) !== stripPad(encode(text))) return { ok: false, reason: "decode-failed" }; return { ok: true, text }; } catch { return { ok: false, reason: "decode-failed" }; } } function decodeRecursive(input, maxDepth, force) { const first = decode(input); if (!first.ok) return first; let output = first.text; let iterations = 1; for (let i = 1; i < maxDepth; i++) { const next = decode(output); if (!next.ok) { if (force) return { ok: false, reason: "forced-decode-failed" }; break; } output = next.text; iterations++; } return { ok: true, output, iterations }; } function encodeRecursive(input, count) { let output = input; for (let i = 0; i < count; i++) output = encode(output); return { output, iterations: count }; } //#endregion //#region src/core/utils/i18n.ts /** Lightweight i18n strings keyed by Language code. */ var strings = { encode: { en: "Encode", ko: "인코딩", ja: "エンコード" }, decode: { en: "Decode", ko: "디코딩", ja: "デコード" }, history: { en: "History", ko: "기록", ja: "履歴" }, settings: { en: "Settings", ko: "설정", ja: "設定" }, repeat: { en: "Repeat", ko: "반복", ja: "繰返し" }, autoStop: { en: "Auto-stop", ko: "자동 중지", ja: "自動停止" }, inputEncode: { en: "Plain text to encode…", ko: "인코딩할 텍스트…", ja: "エンコードするテキスト…" }, inputDecode: { en: "Base64 to decode…", ko: "디코딩할 Base64…", ja: "デコードするBase64…" }, outputEncode: { en: "Encoded Base64 output", ko: "인코딩된 Base64 출력", ja: "エンコード済みBase64出力" }, outputDecode: { en: "Decoded plain text output", ko: "디코딩된 텍스트 출력", ja: "デコード済みテキスト出力" }, copyOutput: { en: "Copy output", ko: "출력 복사", ja: "出力をコピー" }, copied: { en: "✓ Copied", ko: "✓ 복사됨", ja: "✓ コピー済み" }, decodeFailed: { en: "⚠ Decode failed", ko: "⚠ 디코딩 실패", ja: "⚠ デコード失敗" }, decodeClipboard: { en: "Decode → Copy to clipboard", ko: "Decode → 클립보드 복사", ja: "デコード → クリップボードにコピー" }, openNewTab: { en: "Open in new tab", ko: "새 탭에서 열기", ja: "新しいタブで開く" }, openCurrentTab: { en: "Open in this tab", ko: "이 탭에서 열기", ja: "このタブで開く" }, clearAll: { en: "Clear all", ko: "전체 삭제", ja: "すべて削除" }, noHistory: { en: "No history yet", ko: "기록 없음", ja: "履歴なし" }, detail: { en: "Detail", ko: "상세", ja: "詳細" }, action: { en: "Action", ko: "동작", ja: "アクション" }, page: { en: "Page", ko: "페이지", ja: "ページ" }, input: { en: "Input", ko: "입력", ja: "入力" }, output: { en: "Output", ko: "출력", ja: "出力" }, iterations: { en: "Iterations", ko: "반복 횟수", ja: "反復回数" }, time: { en: "Time", ko: "시간", ja: "時間" }, recursiveDecode: { en: "Recursive decode", ko: "재귀 디코딩", ja: "再帰デコード" }, count: { en: "Count", ko: "횟수", ja: "回数" }, forceIgnoreErrors: { en: "Force (ignore errors)", ko: "강제 (오류 무시)", ja: "強制(エラー無視)" }, recursiveEncode: { en: "Recursive encode", ko: "재귀 인코딩", ja: "再帰エンコード" }, general: { en: "General", ko: "일반", ja: "一般" }, activateNewTab: { en: "Activate new tab on URL open", ko: "URL 열 때 새 탭 활성화", ja: "URL open 時に新しいタブをアクティブ化" }, clearInputOnSwitch: { en: "Clear input on tab switch", ko: "탭 전환 시 입력 초기화", ja: "タブ切替時に入力をクリア" }, contextMenu: { en: "Right-click context menu", ko: "우클릭 컨텍스트 메뉴", ja: "右クリックメニュー" }, autoClosePanel: { en: "Auto close panel on outside click", ko: "외부 클릭 시 패널 자동 닫기", ja: "パネル外クリックで自動閉じ" }, appearance: { en: "Appearance", ko: "외관", ja: "外観" }, buttonPosition: { en: "Button position", ko: "버튼 위치", ja: "ボタン位置" }, accentColor: { en: "Accent color", ko: "강조 색상", ja: "アクセントカラー" }, language: { en: "Language", ko: "언어", ja: "言語" }, saveSettings: { en: "Save settings", ko: "설정 저장", ja: "設定を保存" }, saved: { en: "✓ Saved", ko: "✓ 저장됨", ja: "✓ 保存済み" }, "pos-top-left": { en: "↖", ko: "↖", ja: "↖" }, "pos-top-center": { en: "↑", ko: "↑", ja: "↑" }, "pos-top-right": { en: "↗", ko: "↗", ja: "↗" }, "pos-middle-left": { en: "←", ko: "←", ja: "←" }, "pos-middle-right": { en: "→", ko: "→", ja: "→" }, "pos-bottom-left": { en: "↙", ko: "↙", ja: "↙" }, "pos-bottom-center": { en: "↓", ko: "↓", ja: "↓" }, "pos-bottom-right": { en: "↘", ko: "↘", ja: "↘" }, langEn: { en: "English", ko: "English", ja: "English" }, langKo: { en: "한국어", ko: "한국어", ja: "한国語" }, langJa: { en: "日本語", ko: "日本語", ja: "日本語" } }; var _lang = (0, vue.ref)("en"); function setI18nLanguage(lang) { _lang.value = lang; } function t(key) { const entry = strings[key]; return entry?.[_lang.value] ?? entry?.en ?? key; } //#endregion //#region node_modules/lucide-vue-next/dist/esm/shared/src/utils/hasA11yProp.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var hasA11yProp = (props) => { for (const prop in props) if (prop.startsWith("aria-") || prop === "role" || prop === "title") return true; return false; }; //#endregion //#region node_modules/lucide-vue-next/dist/esm/shared/src/utils/isEmptyString.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var isEmptyString = (value) => value === ""; //#endregion //#region node_modules/lucide-vue-next/dist/esm/shared/src/utils/mergeClasses.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var mergeClasses = (...classes) => classes.filter((className, index, array) => { return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index; }).join(" ").trim(); //#endregion //#region node_modules/lucide-vue-next/dist/esm/shared/src/utils/toKebabCase.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(); //#endregion //#region node_modules/lucide-vue-next/dist/esm/shared/src/utils/toCamelCase.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var toCamelCase = (string) => string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()); //#endregion //#region node_modules/lucide-vue-next/dist/esm/shared/src/utils/toPascalCase.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var toPascalCase = (string) => { const camelCase = toCamelCase(string); return camelCase.charAt(0).toUpperCase() + camelCase.slice(1); }; //#endregion //#region node_modules/lucide-vue-next/dist/esm/defaultAttributes.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var defaultAttributes = { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": 2, "stroke-linecap": "round", "stroke-linejoin": "round" }; //#endregion //#region node_modules/lucide-vue-next/dist/esm/Icon.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var Icon = ({ name, iconNode, absoluteStrokeWidth, "absolute-stroke-width": absoluteStrokeWidthKebabCase, strokeWidth, "stroke-width": strokeWidthKebabCase, size = defaultAttributes.width, color = defaultAttributes.stroke, ...props }, { slots }) => { return (0, vue.h)("svg", { ...defaultAttributes, ...props, width: size, height: size, stroke: color, "stroke-width": isEmptyString(absoluteStrokeWidth) || isEmptyString(absoluteStrokeWidthKebabCase) || absoluteStrokeWidth === true || absoluteStrokeWidthKebabCase === true ? Number(strokeWidth || strokeWidthKebabCase || defaultAttributes["stroke-width"]) * 24 / Number(size) : strokeWidth || strokeWidthKebabCase || defaultAttributes["stroke-width"], class: mergeClasses("lucide", props.class, ...name ? [`lucide-${toKebabCase(toPascalCase(name))}-icon`, `lucide-${toKebabCase(name)}`] : ["lucide-icon"]), ...!slots.default && !hasA11yProp(props) && { "aria-hidden": "true" } }, [...iconNode.map((child) => (0, vue.h)(...child)), ...slots.default ? [slots.default()] : []]); }; //#endregion //#region node_modules/lucide-vue-next/dist/esm/createLucideIcon.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var createLucideIcon = (iconName, iconNode) => (props, { slots, attrs }) => (0, vue.h)(Icon, { ...attrs, ...props, iconNode, name: iconName }, slots); //#endregion //#region node_modules/lucide-vue-next/dist/esm/icons/clock.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var Clock = createLucideIcon("clock", [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }], ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }]]); //#endregion //#region node_modules/lucide-vue-next/dist/esm/icons/code.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var Code = createLucideIcon("code", [["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }], ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]]); //#endregion //#region node_modules/lucide-vue-next/dist/esm/icons/repeat.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var Repeat = createLucideIcon("repeat", [ ["path", { d: "m17 2 4 4-4 4", key: "nntrym" }], ["path", { d: "M3 11v-1a4 4 0 0 1 4-4h14", key: "84bu3i" }], ["path", { d: "m7 22-4-4 4-4", key: "1wqhfi" }], ["path", { d: "M21 13v1a4 4 0 0 1-4 4H3", key: "1rx37r" }] ]); //#endregion //#region node_modules/lucide-vue-next/dist/esm/icons/settings.js /** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var Settings = createLucideIcon("settings", [["path", { d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915", key: "1i5ecw" }], ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]]); //#endregion //#region node_modules/overlayscrollbars/overlayscrollbars.mjs /*! * OverlayScrollbars * Version: 2.14.0 * * Copyright (c) Rene Haas | KingSora. * https://github.com/KingSora * * Released under the MIT license. */ var createCache = (t, n) => { const { o, i: s, u: e } = t; let c = o; let r; const cacheUpdateContextual = (t, n) => { const o = c; const i = t; const l = n || (s ? !s(o, i) : o !== i); if (l || e) { c = i; r = o; } return [ c, l, r ]; }; const cacheUpdateIsolated = (t) => cacheUpdateContextual(n(c, r), t); const getCurrentCache = (t) => [ c, !!t, r ]; return [n ? cacheUpdateIsolated : cacheUpdateContextual, getCurrentCache]; }; var n = typeof window !== "undefined" && typeof HTMLElement !== "undefined" && !!window.document ? window : {}; var o = Math.max; var s = Math.min; var e = Math.round; var c = Math.abs; var r = Math.sign; var i = n.cancelAnimationFrame; var l = n.requestAnimationFrame; var a = n.setTimeout; var u$1 = n.clearTimeout; var getApi = (t) => typeof n[t] !== "undefined" ? n[t] : void 0; var f = getApi("MutationObserver"); var _$1 = getApi("IntersectionObserver"); var d = getApi("ResizeObserver"); var p = getApi("ScrollTimeline"); var isUndefined = (t) => t === void 0; var isNull = (t) => t === null; var isNumber = (t) => typeof t === "number"; var isString = (t) => typeof t === "string"; var isBoolean = (t) => typeof t === "boolean"; var isFunction = (t) => typeof t === "function"; var isArray = (t) => Array.isArray(t); var isObject = (t) => typeof t === "object" && !isArray(t) && !isNull(t); var isArrayLike = (t) => { const n = !!t && t.length; const o = isNumber(n) && n > -1 && n % 1 == 0; return isArray(t) || !isFunction(t) && o ? n > 0 && isObject(t) ? n - 1 in t : true : false; }; var isPlainObject = (t) => !!t && t.constructor === Object; var isHTMLElement = (t) => t instanceof HTMLElement; var isElement = (t) => t instanceof Element; function each(t, n) { if (isArrayLike(t)) { for (let o = 0; o < t.length; o++) if (n(t[o], o, t) === false) break; } else if (t) each(Object.keys(t), ((o) => n(t[o], o, t))); return t; } var inArray = (t, n) => t.indexOf(n) >= 0; var concat = (t, n) => t.concat(n); var push = (t, n, o) => { if (!isString(n) && isArrayLike(n)) Array.prototype.push.apply(t, n); else t.push(n); return t; }; var from = (t) => Array.from(t || []); var createOrKeepArray = (t) => { if (isArray(t)) return t; return !isString(t) && isArrayLike(t) ? from(t) : [t]; }; var isEmptyArray = (t) => !!t && !t.length; var deduplicateArray = (t) => from(new Set(t)); var runEachAndClear = (t, n, o) => { const runFn = (t) => t ? t.apply(void 0, n || []) : true; each(t, runFn); if (!o) t.length = 0; }; var v = "paddingTop"; var g$1 = "paddingRight"; var h$1 = "paddingLeft"; var b$1 = "paddingBottom"; var w$1 = "marginLeft"; var y = "marginRight"; var S$1 = "marginBottom"; var m = "overflowX"; var O = "overflowY"; var C$1 = "width"; var $ = "height"; var x$1 = "visible"; var H = "hidden"; var E = "scroll"; var capitalizeFirstLetter = (t) => { const n = String(t || ""); return n ? n[0].toUpperCase() + n.slice(1) : ""; }; var equal = (t, n, o, s) => { if (t && n) { let s = true; each(o, ((o) => { if (t[o] !== n[o]) s = false; })); return s; } return false; }; var equalWH = (t, n) => equal(t, n, ["w", "h"]); var equalXY = (t, n) => equal(t, n, ["x", "y"]); var equalTRBL = (t, n) => equal(t, n, [ "t", "r", "b", "l" ]); var bind = (t, ...n) => t.bind(0, ...n); var selfClearTimeout = (t) => { let n; const o = t ? a : l; const s = t ? u$1 : i; return [(e) => { s(n); n = o((() => e()), isFunction(t) ? t() : t); }, () => s(n)]; }; var getDebouncer = (t) => { const n = isFunction(t) ? t() : t; if (isNumber(n)) { const t = n ? a : l; const o = n ? u$1 : i; return (s) => { const e = t((() => s()), n); return () => { o(e); }; }; } return n && n._; }; var debounce = (t, n) => { const { p: o, v: s, S: e, m: c } = n || {}; let r; let i; let l; let a; const u = function invokeFunctionToDebounce(n) { if (i) i(); if (r) r(); a = i = r = l = void 0; t.apply(this, n); }; const mergeParms = (t) => c && l ? c(l, t) : t; const flush = () => { if (i && l) u(mergeParms(l) || l); }; const f = function debouncedFn() { const t = from(arguments); const n = getDebouncer(o); if (n) { const o = typeof e === "function" ? e() : e; const c = getDebouncer(s); const _ = mergeParms(t) || t; const d = u.bind(0, _); if (i) i(); if (o && !a) { d(); a = true; i = n((() => a = void 0)); } else { i = n(d); if (c && !r) r = c(flush); } l = _; } else u(t); }; f.O = flush; return f; }; var hasOwnProperty = (t, n) => Object.prototype.hasOwnProperty.call(t, n); var keys = (t) => t ? Object.keys(t) : []; var assignDeep = (t, n, o, s, e, c, r) => { const i = [ n, o, s, e, c, r ]; if ((typeof t !== "object" || isNull(t)) && !isFunction(t)) t = {}; each(i, ((n) => { each(n, ((o, s) => { const e = n[s]; if (t === e) return true; const c = isArray(e); if (e && isPlainObject(e)) { const n = t[s]; let o = n; if (c && !isArray(n)) o = []; else if (!c && !isPlainObject(n)) o = {}; t[s] = assignDeep(o, e); } else t[s] = c ? e.slice() : e; })); })); return t; }; var removeUndefinedProperties = (t, n) => each(assignDeep({}, t), ((t, n, o) => { if (t === void 0) delete o[n]; else if (t && isPlainObject(t)) o[n] = removeUndefinedProperties(t); })); var isEmptyObject = (t) => !keys(t).length; var noop = () => {}; var capNumber = (t, n, e) => o(t, s(n, e)); var getDomTokensArray = (t) => deduplicateArray((isArray(t) ? t : (t || "").split(" ")).filter(((t) => t))); var getAttr = (t, n) => t && t.getAttribute(n); var hasAttr = (t, n) => t && t.hasAttribute(n); var setAttrs = (t, n, o) => { each(getDomTokensArray(n), ((n) => { if (t) t.setAttribute(n, String(o || "")); })); }; var removeAttrs = (t, n) => { each(getDomTokensArray(n), ((n) => t && t.removeAttribute(n))); }; var domTokenListAttr = (t, n) => { const o = getDomTokensArray(getAttr(t, n)); const s = bind(setAttrs, t, n); const domTokenListOperation = (t, n) => { const s = new Set(o); each(getDomTokensArray(t), ((t) => { s[n](t); })); return from(s).join(" "); }; return { C: (t) => s(domTokenListOperation(t, "delete")), $: (t) => s(domTokenListOperation(t, "add")), H: (t) => { const n = getDomTokensArray(t); return n.reduce(((t, n) => t && o.includes(n)), n.length > 0); } }; }; var removeAttrClass = (t, n, o) => { domTokenListAttr(t, n).C(o); return bind(addAttrClass, t, n, o); }; var addAttrClass = (t, n, o) => { domTokenListAttr(t, n).$(o); return bind(removeAttrClass, t, n, o); }; var addRemoveAttrClass = (t, n, o, s) => (s ? addAttrClass : removeAttrClass)(t, n, o); var hasAttrClass = (t, n, o) => domTokenListAttr(t, n).H(o); var createDomTokenListClass = (t) => domTokenListAttr(t, "class"); var removeClass = (t, n) => { createDomTokenListClass(t).C(n); }; var addClass = (t, n) => { createDomTokenListClass(t).$(n); return bind(removeClass, t, n); }; var find = (t, n) => { const o = n ? isElement(n) && n : document; return o ? from(o.querySelectorAll(t)) : []; }; var findFirst = (t, n) => { const o = n ? isElement(n) && n : document; return o && o.querySelector(t); }; var is = (t, n) => isElement(t) && t.matches(n); var isBodyElement = (t) => is(t, "body"); var contents = (t) => t ? from(t.childNodes) : []; var parent = (t) => t && t.parentElement; var closest = (t, n) => isElement(t) && t.closest(n); var getFocusedElement = (t) => document.activeElement; var liesBetween = (t, n, o) => { const s = closest(t, n); const e = t && findFirst(o, s); const c = closest(e, n) === s; return s && e ? s === t || e === t || c && closest(closest(t, o), n) !== s : false; }; var removeElements = (t) => { each(createOrKeepArray(t), ((t) => { const n = parent(t); if (t && n) n.removeChild(t); })); }; var appendChildren = (t, n) => bind(removeElements, t && n && each(createOrKeepArray(n), ((n) => { if (n) t.appendChild(n); }))); var z$1; var getTrustedTypePolicy = () => z$1; var setTrustedTypePolicy = (t) => { z$1 = t; }; var createDiv = (t) => { const n = document.createElement("div"); setAttrs(n, "class", t); return n; }; var createDOM = (t) => { const n = createDiv(); const o = getTrustedTypePolicy(); const s = t.trim(); n.innerHTML = o ? o.createHTML(s) : s; return each(contents(n), ((t) => removeElements(t))); }; var getCSSVal = (t, n) => t.getPropertyValue(n) || t[n] || ""; var validFiniteNumber = (t) => { const n = t || 0; return isFinite(n) ? n : 0; }; var parseToZeroOrNumber = (t) => validFiniteNumber(parseFloat(t || "")); var roundCssNumber = (t) => Math.round(t * 1e4) / 1e4; var numberToCssPx = (t) => `${roundCssNumber(validFiniteNumber(t))}px`; function setStyles(t, n) { t && n && each(n, ((n, o) => { try { const s = t.style; const e = isNull(n) || isBoolean(n) ? "" : isNumber(n) ? numberToCssPx(n) : n; if (o.indexOf("--") === 0) s.setProperty(o, e); else s[o] = e; } catch (s) {} })); } function getStyles(t, o, s) { const e = isString(o); let c = e ? "" : {}; if (t) { const r = n.getComputedStyle(t, s) || t.style; c = e ? getCSSVal(r, o) : from(o).reduce(((t, n) => { t[n] = getCSSVal(r, n); return t; }), c); } return c; } var topRightBottomLeft = (t, n, o) => { const s = n ? `${n}-` : ""; const e = o ? `-${o}` : ""; const c = `${s}top${e}`; const r = `${s}right${e}`; const i = `${s}bottom${e}`; const l = `${s}left${e}`; const a = getStyles(t, [ c, r, i, l ]); return { t: parseToZeroOrNumber(a[c]), r: parseToZeroOrNumber(a[r]), b: parseToZeroOrNumber(a[i]), l: parseToZeroOrNumber(a[l]) }; }; var getTrasformTranslateValue = (t, n) => `translate${isObject(t) ? `(${t.x},${t.y})` : `${n ? "X" : "Y"}(${t})`}`; var elementHasDimensions = (t) => !!(t.offsetWidth || t.offsetHeight || t.getClientRects().length); var I = { w: 0, h: 0 }; var getElmWidthHeightProperty = (t, n) => n ? { w: n[`${t}Width`], h: n[`${t}Height`] } : I; var getWindowSize = (t) => getElmWidthHeightProperty("inner", t || n); var A$1 = bind(getElmWidthHeightProperty, "offset"); var T = bind(getElmWidthHeightProperty, "client"); var D$1 = bind(getElmWidthHeightProperty, "scroll"); var getFractionalSize = (t) => { const n = parseFloat(getStyles(t, C$1)) || 0; const o = parseFloat(getStyles(t, $)) || 0; return { w: n - e(n), h: o - e(o) }; }; var getBoundingClientRect = (t) => t.getBoundingClientRect(); var hasDimensions = (t) => !!t && elementHasDimensions(t); var domRectHasDimensions = (t) => !!(t && (t[$] || t[C$1])); var domRectAppeared = (t, n) => { const o = domRectHasDimensions(t); return !domRectHasDimensions(n) && o; }; var removeEventListener = (t, n, o, s) => { each(getDomTokensArray(n), ((n) => { if (t) t.removeEventListener(n, o, s); })); }; var addEventListener = (t, n, o, s) => { var e; const c = (e = s && s.I) != null ? e : true; const r = s && s.A || false; const i = s && s.T || false; const l = { passive: c, capture: r }; return bind(runEachAndClear, getDomTokensArray(n).map(((n) => { const s = i ? (e) => { removeEventListener(t, n, s, r); if (o) o(e); } : o; if (t) t.addEventListener(n, s, l); return bind(removeEventListener, t, n, s, r); }))); }; var stopPropagation = (t) => t.stopPropagation(); var preventDefault = (t) => t.preventDefault(); var stopAndPrevent = (t) => stopPropagation(t) || preventDefault(t); var scrollElementTo = (t, n) => { const { x: o, y: s } = isNumber(n) ? { x: n, y: n } : n || {}; isNumber(o) && (t.scrollLeft = o); isNumber(s) && (t.scrollTop = s); }; var getElementScroll = (t) => ({ x: t.scrollLeft, y: t.scrollTop }); var getZeroScrollCoordinates = () => ({ D: { x: 0, y: 0 }, M: { x: 0, y: 0 } }); var sanitizeScrollCoordinates = (t, n) => { const { D: o, M: s } = t; const { w: e, h: i } = n; const sanitizeAxis = (t, n, o) => { let s = r(t) * o; let e = r(n) * o; if (s === e) { const o = c(t); const r = c(n); e = o > r ? 0 : e; s = o < r ? 0 : s; } s = s === e ? 0 : s; return [s + 0, e + 0]; }; const [l, a] = sanitizeAxis(o.x, s.x, e); const [u, f] = sanitizeAxis(o.y, s.y, i); return { D: { x: l, y: u }, M: { x: a, y: f } }; }; var isDefaultDirectionScrollCoordinates = ({ D: t, M: n }) => { const getAxis = (t, n) => t === 0 && t <= n; return { x: getAxis(t.x, n.x), y: getAxis(t.y, n.y) }; }; var getScrollCoordinatesPercent = ({ D: t, M: n }, o) => { const getAxis = (t, n, o) => capNumber(0, 1, (t - o) / (t - n) || 0); return { x: getAxis(t.x, n.x, o.x), y: getAxis(t.y, n.y, o.y) }; }; var focusElement = (t) => { if (t && t.focus) t.focus({ preventScroll: true, focusVisible: false }); }; var manageListener = (t, n) => { each(createOrKeepArray(n), t); }; var createEventListenerHub = (t) => { const n = /* @__PURE__ */ new Map(); const removeEvent = (t, o) => { if (t) { const s = n.get(t); manageListener(((t) => { if (s) s[t ? "delete" : "clear"](t); }), o); } else { n.forEach(((t) => { t.clear(); })); n.clear(); } }; const addEvent = (t, o) => { if (isString(t)) { const s = n.get(t) || /* @__PURE__ */ new Set(); n.set(t, s); manageListener(((t) => { if (isFunction(t)) s.add(t); }), o); return bind(removeEvent, t, o); } if (isBoolean(o) && o) removeEvent(); const s = keys(t); const e = []; each(s, ((n) => { const o = t[n]; if (o) push(e, addEvent(n, o)); })); return bind(runEachAndClear, e); }; const triggerEvent = (t, o) => { each(from(n.get(t)), ((t) => { if (o && !isEmptyArray(o)) t.apply(0, o); else t(); })); }; addEvent(t || {}); return [ addEvent, removeEvent, triggerEvent ]; }; var M = {}; var k = {}; var addPlugins = (t) => { each(t, ((t) => each(t, ((n, o) => { M[o] = t[o]; })))); }; var registerPluginModuleInstances = (t, n, o) => keys(t).map(((s) => { const { static: e, instance: c } = t[s]; const [r, i, l] = o || []; const a = o ? c : e; if (a) { const t = o ? a(r, i, n) : a(n); return (l || k)[s] = t; } })); var getStaticPluginModuleInstance = (t) => k[t]; var R = "__osOptionsValidationPlugin"; var V = `data-overlayscrollbars`; var L = "os-environment"; var U = `${L}-scrollbar-hidden`; var P$1 = `${V}-initialize`; var N = "noClipping"; var q$1 = `${V}-body`; var B$1 = V; var F$1 = "host"; var j$1 = `${V}-viewport`; var X = m; var Y = O; var W = "arrange"; var J = "measuring"; var G = "scrolling"; var K = "scrollbarHidden"; var Q = "noContent"; var Z = `${V}-padding`; var tt = `${V}-content`; var nt = "os-size-observer"; var ot = `${nt}-appear`; var st = `${nt}-listener`; `${st}`; `${st}`; var it = "os-trinsic-observer"; var lt = "os-theme-none"; var at = "os-scrollbar"; var ut = `${at}-rtl`; var ft = `${at}-horizontal`; var _t = `${at}-vertical`; var dt = `${at}-track`; var pt = `${at}-handle`; var vt = `${at}-visible`; var gt = `${at}-cornerless`; var ht = `${at}-interaction`; var bt = `${at}-unusable`; var wt = `${at}-auto-hide`; var yt = `${wt}-hidden`; var St = `${at}-wheel`; var mt = `${dt}-interactive`; var Ot = `${pt}-interactive`; var Ct = "__osSizeObserverPlugin"; var getShowNativeOverlaidScrollbars = (t, n) => { const { k: o } = n; const [s, e] = t("showNativeOverlaidScrollbars"); return [s && o.x && o.y, e]; }; var overflowIsVisible = (t) => t.indexOf(x$1) === 0; var overflowBehaviorToOverflowStyle = (t) => t.replace(`${x$1}-`, ""); var overflowCssValueToOverflowStyle = (t, n) => { if (t === "auto") return n ? E : H; const o = t || H; return [ H, E, x$1 ].includes(o) ? o : H; }; var getElementOverflowStyle = (t, n) => { const { overflowX: o, overflowY: s } = getStyles(t, [m, O]); return { x: overflowCssValueToOverflowStyle(o, n.x), y: overflowCssValueToOverflowStyle(s, n.y) }; }; var xt = "__osScrollbarsHidingPlugin"; var Et = "__osClickScrollPlugin"; var opsStringify = (t) => JSON.stringify(t, ((t, n) => { if (isFunction(n)) throw 0; return n; })); var getPropByPath = (t, n) => t ? `${n}`.split(".").reduce(((t, n) => t && hasOwnProperty(t, n) ? t[n] : void 0), t) : void 0; var It = [0, 33]; var At = [33, 99]; var Tt = [ 222, 666, true ]; var Dt = { paddingAbsolute: false, showNativeOverlaidScrollbars: false, update: { elementEvents: [["img", "load"]], debounce: { mutation: It, resize: null, event: At, env: Tt }, attributes: null, ignoreMutation: null, flowDirectionStyles: null }, overflow: { x: "scroll", y: "scroll" }, scrollbars: { theme: "os-theme-dark", visibility: "auto", autoHide: "never", autoHideDelay: 1300, autoHideSuspend: false, dragScroll: true, clickScroll: false, pointers: [ "mouse", "touch", "pen" ] } }; var getOptionsDiff = (t, n) => { const o = {}; each(concat(keys(n), keys(t)), ((s) => { const e = t[s]; const c = n[s]; if (isObject(e) && isObject(c)) { assignDeep(o[s] = {}, getOptionsDiff(e, c)); if (isEmptyObject(o[s])) delete o[s]; } else if (hasOwnProperty(n, s) && c !== e) { let t = true; if (isArray(e) || isArray(c)) try { if (opsStringify(e) === opsStringify(c)) t = false; } catch (r) {} if (t) o[s] = c; } })); return o; }; var createOptionCheck = (t, n, o) => (s) => [getPropByPath(t, s), o || getPropByPath(n, s) !== void 0]; var Mt; var getNonce = () => Mt; var setNonce = (t) => { Mt = t; }; var kt; var createEnvironment = () => { const getNativeScrollbarSize = (t, n, o) => { appendChildren(document.body, t); appendChildren(document.body, t); const s = T(t); const e = A$1(t); const c = getFractionalSize(n); if (o) removeElements(t); return { x: e.h - s.h + c.h, y: e.w - s.w + c.w }; }; const getNativeScrollbarsHiding = (t) => { let n = false; const o = addClass(t, U); try { n = getStyles(t, "scrollbar-width") === "none" || getStyles(t, "display", "::-webkit-scrollbar") === "none"; } catch (s) {} o(); return n; }; const s = createDOM(`<div class="${L}"><div></div><style>${`.${L}{scroll-behavior:auto!important;position:fixed;opacity:0;visibility:hidden;overflow:scroll;height:200px;width:200px;z-index:-1}.${L} div{width:200%;height:200%;margin:10px 0}.${U}{scrollbar-width:none!important}.${U}::-webkit-scrollbar,.${U}::-webkit-scrollbar-corner{appearance:none!important;display:none!important;width:0!important;height:0!important}`}</style></div>`)[0]; const e = s.firstChild; const c = s.lastChild; const r = getNonce(); if (r) c.nonce = r; const [i, , l] = createEventListenerHub(); const [a, u] = createCache({ o: getNativeScrollbarSize(s, e), i: equalXY }, bind(getNativeScrollbarSize, s, e, true)); const [f] = u(); const _ = getNativeScrollbarsHiding(s); const d = { x: f.x === 0, y: f.y === 0 }; const v = { elements: { host: null, padding: !_, viewport: (t) => _ && isBodyElement(t) && t, content: false }, scrollbars: { slot: true }, cancel: { nativeScrollbarsOverlaid: false, body: null } }; const g = assignDeep({}, Dt); const h = bind(assignDeep, {}, g); const b = bind(assignDeep, {}, v); const w = { P: f, k: d, U: _, J: !!p, G: bind(i, "r"), K: b, Z: (t) => assignDeep(v, t) && b(), tt: h, nt: (t) => assignDeep(g, t) && h(), ot: assignDeep({}, v), st: assignDeep({}, g) }; removeAttrs(s, "style"); removeElements(s); addEventListener(n, "resize", (() => { l("r", []); })); if (isFunction(n.matchMedia) && !_ && (!d.x || !d.y)) { const addZoomListener = (t) => { addEventListener(n.matchMedia(`(resolution: ${n.devicePixelRatio}dppx)`), "change", (() => { t(); addZoomListener(t); }), { T: true }); }; addZoomListener((() => { const [t, n] = a(); assignDeep(w.P, t); l("r", [n]); })); } return w; }; var getEnvironment = () => { if (!kt) kt = createEnvironment(); return kt; }; var createEventContentChange = (t, n, o) => { let s = false; const e = o ? /* @__PURE__ */ new WeakMap() : false; const destroy = () => { s = true; }; const updateElements = (c) => { if (e && o) each(o.map(((n) => { const [o, s] = n || []; return [s && o ? (c || find)(o, t) : [], s]; })), ((o) => each(o[0], ((c) => { const r = o[1]; const i = e.get(c) || []; if (t.contains(c) && r) { const t = addEventListener(c, r, ((o) => { if (s) { t(); e.delete(c); } else n(o); })); e.set(c, push(i, t)); } else { runEachAndClear(i); e.delete(c); } })))); }; updateElements(); return [destroy, updateElements]; }; var createDOMObserver = (t, n, o, s) => { let e = false; const { et: c, ct: r, rt: i, it: l, lt: a, ut: u } = s || {}; const [_, d] = createEventContentChange(t, (() => e && o(true)), i); const p = c || []; const v = r || []; const g = concat(p, v); const observerCallback = (e, c) => { if (!isEmptyArray(c)) { const r = a || noop; const i = u || noop; const f = []; const _ = []; let p = false; let g = false; each(c, ((o) => { const { attributeName: e, target: c, type: a, oldValue: u, addedNodes: d, removedNodes: h } = o; const b = a === "attributes"; const w = a === "childList"; const y = t === c; const S = b && e; const m = S && getAttr(c, e || ""); const O = isString(m) ? m : null; const C = S && u !== O; const $ = inArray(v, e) && C; if (n && (w || !y)) { const n = b && C; const a = n && l && is(c, l); const p = (a ? !r(c, e, u, O) : !b || n) && !i(o, !!a, t, s); each(d, ((t) => push(f, t))); each(h, ((t) => push(f, t))); g = g || p; } if (!n && y && C && !r(c, e, u, O)) { push(_, e); p = p || $; } })); d(((t) => deduplicateArray(f).reduce(((n, o) => { push(n, find(t, o)); return is(o, t) ? push(n, o) : n; }), []))); if (n) { if (!e && g) o(false); return [false]; } if (!isEmptyArray(_) || p) { const t = [deduplicateArray(_), p]; if (!e) o.apply(0, t); return t; } } }; const h = new f(bind(observerCallback, false)); return [() => { h.observe(t, { attributes: true, attributeOldValue: true, attributeFilter: g, subtree: n, childList: n, characterData: n }); e = true; return () => { if (e) { _(); h.disconnect(); e = false; } }; }, () => { if (e) return observerCallback(true, h.takeRecords()); }]; }; var Rt = null; var createSizeObserver = (t, n, o) => { const { ft: s } = o || {}; const e = getStaticPluginModuleInstance(Ct); const [c] = createCache({ o: false, u: true }); return () => { const o = []; const i = createDOM(`<div class="${nt}"><div class="${st}"></div></div>`)[0]; const l = i.firstChild; const onSizeChangedCallbackProxy = (t) => { const o = isArray(t) && !isEmptyArray(t); let s = false; let e = false; if (o) { const n = t[0]; const [o, , r] = c(n.contentRect); const i = domRectHasDimensions(o); e = domRectAppeared(o, r); s = !e && !i; } else e = t === true; if (!s) n({ _t: true, ft: e }); }; if (d) { if (!isBoolean(Rt)) { const n = new d(noop); n.observe(t, { get box() { Rt = true; } }); Rt = Rt || false; n.disconnect(); } const n = debounce(onSizeChangedCallbackProxy, { p: 0, v: 0 }); const resizeObserverCallback = (t) => n(t); const s = new d(resizeObserverCallback); s.observe(Rt ? t : l); push(o, [() => { s.disconnect(); }, !Rt && appendChildren(t, i)]); if (Rt) { const n = new d(resizeObserverCallback); n.observe(t, { box: "border-box" }); push(o, (() => n.disconnect())); } } else if (e) { const [n, c] = e(l, onSizeChangedCallbackProxy, s); push(o, concat([ addClass(i, ot), addEventListener(i, "animationstart", n), appendChildren(t, i) ], c)); } else return noop; return bind(runEachAndClear, o); }; }; var createTrinsicObserver = (t, n) => { let o; const isHeightIntrinsic = (t) => t.h === 0 || t.isIntersecting || t.intersectionRatio > 0; const s = createDiv(it); const [e] = createCache({ o: false }); const triggerOnTrinsicChangedCallback = (t, o) => { if (t) { const s = e(isHeightIntrinsic(t)); const [, c] = s; return c && !o && n(s) && [s]; } }; const intersectionObserverCallback = (t, n) => triggerOnTrinsicChangedCallback(n.pop(), t); return [() => { const n = []; if (_$1) { o = new _$1(bind(intersectionObserverCallback, false), { root: t }); o.observe(s); push(n, (() => { o.disconnect(); })); } else { const onSizeChanged = () => { triggerOnTrinsicChangedCallback(A$1(s)); }; push(n, createSizeObserver(s, onSizeChanged)()); onSizeChanged(); } return bind(runEachAndClear, push(n, appendChildren(t, s))); }, () => o && intersectionObserverCallback(true, o.takeRecords())]; }; var createObserversSetup = (t, n, o, s) => { let e; let c; let r; let i; let l; let a; let u; let f; const _ = `[${B$1}]`; const p = `[${j$1}]`; const v = [ "id", "class", "style", "open", "wrap", "cols", "rows" ]; const { dt: g, vt: h, L: b, gt: w, ht: y, V: S, bt: m, wt: O, yt: C, St: $ } = t; const getDirectionIsRTL = (t) => getStyles(t, "direction") === "rtl"; const createDebouncedObservesUpdate = () => { let t; let n; let o; const e = debounce(s, { p: () => t, v: () => n, S: () => o, m(t, n) { const [o] = t; const [s] = n; return [concat(keys(o), keys(s)).reduce(((t, n) => { t[n] = o[n] || s[n]; return t; }), {})]; } }); const fn = (s, c) => { if (isArray(c)) { const [s, e, r] = c; t = s; n = e; o = r; } else if (isNumber(c)) { t = c; n = false; o = false; } else { t = false; n = false; o = false; } e(s); }; fn.O = e.O; return fn; }; const x = { Ot: false, B: getDirectionIsRTL(g) }; const H = getEnvironment(); const E = getStaticPluginModuleInstance(xt); const [z] = createCache({ i: equalWH, o: { w: 0, h: 0 } }, (() => { const s = E && E.R(t, n, x, H, o).Y; const c = !(m && S) && hasAttrClass(h, B$1, N); const r = !S && O(W); const i = r && getElementScroll(w); const l = i && $(); const a = C(J, c); const u = r && s && s(); const f = D$1(b); const _ = getFractionalSize(b); if (u) u(); scrollElementTo(w, i); if (l) l(); if (c) a(); return { w: f.w + _.w, h: f.h + _.h }; })); const I = createDebouncedObservesUpdate(); const setDirection = (t) => { const n = getDirectionIsRTL(g); assignDeep(t, { Ct: f !== n }); assignDeep(x, { B: n }); f = n; }; const onTrinsicChanged = (t, n) => { const [o, e] = t; const c = { $t: e }; assignDeep(x, { Ot: o }); if (!n) s(c); return c; }; const onSizeChanged = ({ _t: t, ft: n }) => { const o = n ? s : I; const e = { _t: t || n, ft: n }; setDirection(e); o(e, c); }; const onContentMutation = (t, n) => { const [, o] = z(); const s = { xt: o }; setDirection(s); if (o && !n) I(s, t ? r : e); return s; }; const onHostMutation = (t, n, o) => { const s = { Ht: n }; setDirection(s); if (n && !o) I(s, e); return s; }; const [A, T] = y ? createTrinsicObserver(h, onTrinsicChanged) : []; const M = !S && createSizeObserver(h, onSizeChanged, { ft: true }); const [k, R] = createDOMObserver(h, false, onHostMutation, { ct: v, et: v }); const V = S && d && new d(((t) => { const n = t[t.length - 1].contentRect; onSizeChanged({ _t: true, ft: domRectAppeared(n, u) }); u = n; })); return [ () => { if (V) V.observe(h); const t = M && M(); const n = A && A(); const o = k(); const s = H.G(((t) => { const [, n] = z(); I({ Et: t, xt: n, _t: m }, i); })); return () => { if (V) V.disconnect(); if (t) t(); if (n) n(); if (a) a(); o(); s(); }; }, ({ zt: t, It: n, At: o }) => { const s = {}; const [u] = t("update.ignoreMutation"); const [f, d] = t("update.attributes"); const [g, h] = t("update.elementEvents"); const [w, m] = t("update.debounce"); const O = h || d; const C = n || o; const ignoreMutationFromOptions = (t) => isFunction(u) && u(t); if (O) { if (l) l(); if (a) a(); const [t, n] = createDOMObserver(y || b, true, onContentMutation, { et: concat(v, f || []), rt: g, it: _, ut: (t, n) => { const { target: o, attributeName: s } = t; return (!n && s && !S ? liesBetween(o, _, p) : false) || !!closest(o, `.${at}`) || !!ignoreMutationFromOptions(t); } }); a = t(); l = n; } if (m) { I.O(); if (isArray(w) || isNumber(w)) { e = w; c = false; r = At; i = Tt; } else if (isPlainObject(w)) { e = w.mutation; c = w.resize; r = w.event; i = w.env; } else { e = false; c = false; r = false; i = false; } } if (C) { const t = R(); const n = T && T(); const o = l && l(); if (t) assignDeep(s, onHostMutation(t[0], t[1], C)); if (n) assignDeep(s, onTrinsicChanged(n[0], C)); if (o) assignDeep(s, onContentMutation(o[0], C)); } setDirection(s); return s; }, x ]; }; var resolveInitialization = (t, n) => isFunction(n) ? n.apply(0, t) : n; var staticInitializationElement = (t, n, o, s) => { return resolveInitialization(t, isUndefined(s) ? o : s) || n.apply(0, t); }; var dynamicInitializationElement = (t, n, o, s) => { const c = resolveInitialization(t, isUndefined(s) ? o : s); return !!c && (isHTMLElement(c) ? c : n.apply(0, t)); }; var cancelInitialization = (t, n) => { const { nativeScrollbarsOverlaid: o, body: s } = n || {}; const { k: e, U: c, K: r } = getEnvironment(); const { nativeScrollbarsOverlaid: i, body: l } = r().cancel; const a = o != null ? o : i; const u = isUndefined(s) ? l : s; const f = (e.x || e.y) && a; const _ = t && (isNull(u) ? !c : u); return !!f || !!_; }; var createScrollbarsSetupElements = (t, n, o, s) => { const e = "--os-viewport-percent"; const c = "--os-scroll-percent"; const r = "--os-scroll-direction"; const { K: i } = getEnvironment(); const { scrollbars: l } = i(); const { slot: a } = l; const { dt: u, vt: f, L: _, Tt: d, gt: v, bt: g, V: h } = n; const { scrollbars: b } = d ? {} : t; const { slot: w } = b || {}; const y = []; const S = []; const m = []; const O = dynamicInitializationElement([ u, f, _ ], (() => h && g ? u : f), a, w); const initScrollTimeline = (t) => { if (p) { let n = null; let s = []; const e = new p({ source: v, axis: t }); const cancelAnimation = () => { if (n) n.cancel(); n = null; }; const _setScrollPercentAnimation = (c) => { const { Dt: r } = o; const i = isDefaultDirectionScrollCoordinates(r)[t]; const l = t === "x"; const a = [getTrasformTranslateValue(0, l), getTrasformTranslateValue(`calc(-100% + 100cq${l ? "w" : "h"})`, l)]; const u = i ? a : a.reverse(); if (s[0] === u[0] && s[1] === u[1]) return cancelAnimation; s = u; cancelAnimation(); n = c.Mt.animate({ clear: ["left"], transform: u }, { timeline: e }); return cancelAnimation; }; return { kt: _setScrollPercentAnimation }; } }; const C = { x: initScrollTimeline("x"), y: initScrollTimeline("y") }; const getViewportPercent = () => { const { Rt: t, Vt: n } = o; const getAxisValue = (t, n) => capNumber(0, 1, t / (t + n) || 0); return { x: getAxisValue(n.x, t.x), y: getAxisValue(n.y, t.y) }; }; const scrollbarStructureAddRemoveClass = (t, n, o) => { const s = o ? addClass : removeClass; each(t, ((t) => { s(t.Lt, n); })); }; const scrollbarStyle = (t, n) => { each(t, ((t) => { const [o, s] = n(t); setStyles(o, s); })); }; const scrollbarsAddRemoveClass = (t, n, o) => { const s = isBoolean(o); const e = s ? o : true; const c = s ? !o : true; if (e) scrollbarStructureAddRemoveClass(S, t, n); if (c) scrollbarStructureAddRemoveClass(m, t, n); }; const refreshScrollbarsHandleLength = () => { const t = getViewportPercent(); const createScrollbarStyleFn = (t) => (n) => [n.Lt, { [e]: roundCssNumber(t) + "" }]; scrollbarStyle(S, createScrollbarStyleFn(t.x)); scrollbarStyle(m, createScrollbarStyleFn(t.y)); }; const refreshScrollbarsHandleOffset = () => { if (!p) { const { Dt: t } = o; const n = getScrollCoordinatesPercent(t, getElementScroll(v)); const createScrollbarStyleFn = (t) => (n) => [n.Lt, { [c]: roundCssNumber(t) + "" }]; scrollbarStyle(S, createScrollbarStyleFn(n.x)); scrollbarStyle(m, createScrollbarStyleFn(n.y)); } }; const refreshScrollbarsScrollCoordinates = () => { const { Dt: t } = o; const n = isDefaultDirectionScrollCoordinates(t); const createScrollbarStyleFn = (t) => (n) => [n.Lt, { [r]: t ? "0" : "1" }]; scrollbarStyle(S, createScrollbarStyleFn(n.x)); scrollbarStyle(m, createScrollbarStyleFn(n.y)); if (p) { S.forEach(C.x.kt); m.forEach(C.y.kt); } }; const refreshScrollbarsScrollbarOffset = () => { if (h && !g) { const { Rt: t, Dt: n } = o; const s = isDefaultDirectionScrollCoordinates(n); const e = getScrollCoordinatesPercent(n, getElementScroll(v)); const styleScrollbarPosition = (n) => { const { Lt: o } = n; const c = parent(o) === _ && o; const getTranslateValue = (t, n, o) => { const s = n * t; return numberToCssPx(o ? s : -s); }; return [c, c && { transform: getTrasformTranslateValue({ x: getTranslateValue(e.x, t.x, s.x), y: getTranslateValue(e.y, t.y, s.y) }) }]; }; scrollbarStyle(S, styleScrollbarPosition); scrollbarStyle(m, styleScrollbarPosition); } }; const generateScrollbarDOM = (t) => { const n = t ? "x" : "y"; const e = createDiv(`${at} ${t ? ft : _t}`); const c = createDiv(dt); const r = createDiv(pt); const i = { Lt: e, Ut: c, Mt: r }; const l = C[n]; push(t ? S : m, i); push(y, [ appendChildren(e, c), appendChildren(c, r), bind(removeElements, e), l && l.kt(i), s(i, scrollbarsAddRemoveClass, t) ]); return i; }; const $ = bind(generateScrollbarDOM, true); const x = bind(generateScrollbarDOM, false); const appendElements = () => { appendChildren(O, S[0].Lt); appendChildren(O, m[0].Lt); return bind(runEachAndClear, y); }; $(); x(); return [{ Pt: refreshScrollbarsHandleLength, Nt: refreshScrollbarsHandleOffset, qt: refreshScrollbarsScrollCoordinates, Bt: refreshScrollbarsScrollbarOffset, Ft: scrollbarsAddRemoveClass, jt: { Xt: S, Yt: $, Wt: bind(scrollbarStyle, S) }, Jt: { Xt: m, Yt: x, Wt: bind(scrollbarStyle, m) } }, appendElements]; }; var createScrollbarsSetupEvents = (t, n, o, s) => (r, i, l) => { const { vt: u, L: f, V: _, gt: d, Gt: p, St: v } = n; const { Lt: g, Ut: h, Mt: b } = r; const [w, y] = selfClearTimeout(333); const [S, m] = selfClearTimeout(444); const scrollOffsetElementScrollBy = (t) => { if (isFunction(d.scrollBy)) d.scrollBy({ behavior: "smooth", left: t.x, top: t.y }); }; const createInteractiveScrollEvents = () => { const n = "pointerup pointercancel lostpointercapture"; const s = `client${l ? "X" : "Y"}`; const r = l ? C$1 : $; const i = l ? "left" : "top"; const a = l ? "w" : "h"; const u = l ? "x" : "y"; const createRelativeHandleMove = (t, n) => (s) => { const { Rt: e } = o; const c = A$1(h)[a] - A$1(b)[a]; const i = n * s / c * e[u]; scrollElementTo(d, { [u]: t + i }); }; const f = []; return addEventListener(h, "pointerdown", ((o) => { const l = closest(o.target, `.${pt}`) === b; const _ = l ? b : h; const g = t.scrollbars; const w = g[l ? "dragScroll" : "clickScroll"]; const { button: y, isPrimary: O, pointerType: C } = o; const { pointers: $ } = g; if (y === 0 && O && w && ($ || []).includes(C)) { runEachAndClear(f); m(); const t = !l && (o.shiftKey || w === "instant"); const g = bind(getBoundingClientRect, b); const y = bind(getBoundingClientRect, h); const getHandleOffset = (t, n) => (t || g())[i] - (n || y())[i]; const O = e(getBoundingClientRect(d)[r]) / A$1(d)[a] || 1; const C = createRelativeHandleMove(getElementScroll(d)[u], 1 / O); const $ = o[s]; const x = g(); const H = y(); const E = x[r]; const z = getHandleOffset(x, H) + E / 2; const I = $ - H[i]; const T = l ? 0 : I - z; const releasePointerCapture = (t) => { runEachAndClear(k); _.releasePointerCapture(t.pointerId); }; const D = l || t; const M = v(); const k = [ addEventListener(p, n, releasePointerCapture), addEventListener(p, "selectstart", ((t) => preventDefault(t)), { I: false }), addEventListener(h, n, releasePointerCapture), D && addEventListener(h, "pointermove", ((t) => C(T + (t[s] - $)))), D && (() => { const t = getElementScroll(d); M(); const n = getElementScroll(d); const o = { x: n.x - t.x, y: n.y - t.y }; if (c(o.x) > 3 || c(o.y) > 3) { v(); scrollElementTo(d, t); scrollOffsetElementScrollBy(o); S(M); } }) ]; _.setPointerCapture(o.pointerId); if (t) C(T); else if (!l) { const t = getStaticPluginModuleInstance(Et); if (t) { const n = t(C, T, E, ((t) => { if (t) M(); else push(k, M); })); push(k, n); push(f, bind(n, true)); } } } })); }; let O = true; return bind(runEachAndClear, [ addEventListener(b, "pointermove pointerleave", s), addEventListener(g, "pointerenter", (() => { i(ht, true); })), addEventListener(g, "pointerleave pointercancel", (() => { i(ht, false); })), !_ && addEventListener(g, "mousedown", (() => { const t = getFocusedElement(); if (hasAttr(t, j$1) || hasAttr(t, B$1) || t === document.body) a(bind(focusElement, f), 25); })), addEventListener(g, "wheel", ((t) => { const { deltaX: n, deltaY: o, deltaMode: s } = t; if (O && s === 0 && parent(g) === u) scrollOffsetElementScrollBy({ x: n, y: o }); O = false; i(St, true); w((() => { O = true; i(St); })); preventDefault(t); }), { I: false, A: true }), addEventListener(g, "pointerdown", (() => { const t = addEventListener(p, "click", ((t) => { n(); stopAndPrevent(t); }), { T: true, A: true, I: false }); const n = addEventListener(p, "pointerup pointercancel", (() => { n(); setTimeout(t, 150); }), { A: true, I: true }); }), { A: true, I: true }), createInteractiveScrollEvents(), y, m ]); }; var createScrollbarsSetup = (t, n, o, s, e, c) => { let r; let i; let l; let a; let u; let f = noop; let _ = 0; const d = ["mouse", "pen"]; const isHoverablePointerType = (t) => d.includes(t.pointerType); const [p, v] = selfClearTimeout(); const [g, h] = selfClearTimeout(100); const [b, w] = selfClearTimeout(100); const [y, S] = selfClearTimeout((() => _)); const [m, O] = createScrollbarsSetupElements(t, e, s, createScrollbarsSetupEvents(n, e, s, ((t) => isHoverablePointerType(t) && manageScrollbarsAutoHideInstantInteraction()))); const { vt: C, Kt: $, bt: H } = e; const { Ft: z, Pt: I, Nt: A, qt: T, Bt: D } = m; const manageScrollbarsAutoHide = (t, n) => { S(); if (t) z(yt); else { const t = bind(z, yt, true); if (_ > 0 && !n) y(t); else t(); } }; const manageScrollbarsAutoHideInstantInteraction = () => { if (l ? !r : !a) { manageScrollbarsAutoHide(true); g((() => { manageScrollbarsAutoHide(false); })); } }; const manageAutoHideSuspension = (t) => { z(wt, t, true); z(wt, t, false); }; const onHostMouseEnter = (t) => { if (isHoverablePointerType(t)) { r = l; if (l) manageScrollbarsAutoHide(true); } }; const M = [ S, h, w, v, () => f(), addEventListener(C, "pointerover", onHostMouseEnter, { T: true }), addEventListener(C, "pointerenter", onHostMouseEnter), addEventListener(C, "pointerleave", ((t) => { if (isHoverablePointerType(t)) { r = false; if (l) manageScrollbarsAutoHide(false); } })), addEventListener(C, "pointermove", ((t) => { if (isHoverablePointerType(t) && i) manageScrollbarsAutoHideInstantInteraction(); })), addEventListener($, "scroll", ((t) => { p((() => { A(); manageScrollbarsAutoHideInstantInteraction(); })); c(t); D(); })) ]; const k = getStaticPluginModuleInstance(xt); return [ () => bind(runEachAndClear, push(M, O())), ({ zt: t, At: n, Qt: e, Zt: c }) => { const { tn: r, nn: d, sn: p, en: v } = c || {}; const { Ct: g, ft: h } = e || {}; const { B: w } = o; const { k: y, U: S } = getEnvironment(); const { cn: m, j: O } = s; const [C, M] = t("showNativeOverlaidScrollbars"); const [R, V] = t("scrollbars.theme"); const [L, U] = t("scrollbars.visibility"); const [P, N] = t("scrollbars.autoHide"); const [q, B] = t("scrollbars.autoHideSuspend"); const [F] = t("scrollbars.autoHideDelay"); const [j, X] = t("scrollbars.dragScroll"); const [Y, W] = t("scrollbars.clickScroll"); const [J, G] = t("overflow"); const K = h && !n; const Q = O.x || O.y; const Z = r || d || v || g || n; const tt = p || U || G; const nt = C && y.x && y.y; const ot = !S && !k; const st = nt || ot; const setScrollbarVisibility = (t, n, o) => { const s = t.includes(E) && (L === x$1 || L === "auto" && n === E); z(vt, s, o); return s; }; _ = F; if (K) if (q && Q) { manageAutoHideSuspension(false); f(); b((() => { f = addEventListener($, "scroll", bind(manageAutoHideSuspension, true), { T: true }); })); } else manageAutoHideSuspension(true); if (M || ot) z(lt, st); if (V) { z(u); z(R, true); u = R; } if (B && !q) manageAutoHideSuspension(true); if (N) { i = P === "move"; l = P === "leave"; a = P === "never"; manageScrollbarsAutoHide(a, true); } if (X) z(Ot, j); if (W) z(mt, !!Y); if (tt) { const t = setScrollbarVisibility(J.x, m.x, true); const n = setScrollbarVisibility(J.y, m.y, false); z(gt, !(t && n)); } if (Z) { A(); I(); D(); if (v) T(); z(bt, !O.x, true); z(bt, !O.y, false); z(ut, w && !H); } }, {}, m ]; }; var createStructureSetupElements = (t) => { const { K: s, U: e } = getEnvironment(); const { elements: c } = s(); const { padding: r, viewport: i, content: l } = c; const a = isHTMLElement(t); const u = a ? {} : t; const { elements: f } = u; const { padding: _, viewport: d, content: p } = f || {}; const v = a ? t : u.target; const g = isBodyElement(v); const h = v.ownerDocument; const b = h.documentElement; const getDocumentWindow = () => h.defaultView || n; const w = bind(staticInitializationElement, [v]); const y = bind(dynamicInitializationElement, [v]); const S = bind(createDiv, ""); const C = bind(w, S, i); const $ = bind(y, S, l); const elementHasOverflow = (t) => { const n = A$1(t); const o = D$1(t); const s = getStyles(t, m); const e = getStyles(t, O); return o.w - n.w > 0 && !overflowIsVisible(s) || o.h - n.h > 0 && !overflowIsVisible(e); }; const x = C(d); const H = x === v; const E = H && g; const z = !H && $(p); const I = !H && x === z; const T = E ? b : x; const M = E ? T : v; const k = !H && y(S, r, _); const R = !I && z; const V = [ R, T, k, M ].map(((t) => isHTMLElement(t) && !parent(t) && t)); const elementIsGenerated = (t) => t && inArray(V, t); const L = !elementIsGenerated(T) && elementHasOverflow(T) ? T : v; const U = E ? b : T; const X = { dt: v, vt: M, L: T, rn: k, ht: R, gt: U, Kt: E ? h : T, ln: g ? b : L, Gt: h, bt: g, Tt: a, V: H, an: getDocumentWindow, wt: (t) => hasAttrClass(T, j$1, t), yt: (t, n) => addRemoveAttrClass(T, j$1, t, n), St: () => addRemoveAttrClass(U, j$1, G, true) }; const { dt: Y, vt: W, rn: J, L: Q, ht: nt } = X; const ot = [() => { removeAttrs(W, [B$1, P$1]); removeAttrs(Y, P$1); if (g) removeAttrs(b, [P$1, B$1]); }]; let st = contents([ nt, Q, J, W, Y ].find(((t) => t && !elementIsGenerated(t)))); const et = E ? Y : nt || Q; const ct = bind(runEachAndClear, ot); const appendElements = () => { const t = getDocumentWindow(); const n = getFocusedElement(); const unwrap = (t) => { appendChildren(parent(t), contents(t)); removeElements(t); }; const prepareWrapUnwrapFocus = (t) => addEventListener(t, "focusin focusout focus blur", stopAndPrevent, { A: true, I: false }); const o = "tabindex"; const s = getAttr(Q, o); const c = prepareWrapUnwrapFocus(n); setAttrs(W, B$1, H ? "" : F$1); setAttrs(J, Z, ""); setAttrs(Q, j$1, ""); setAttrs(nt, tt, ""); if (!H) { setAttrs(Q, o, s || "-1"); if (g) setAttrs(b, q$1, ""); } appendChildren(et, st); appendChildren(W, J); appendChildren(J || W, !H && Q); appendChildren(Q, nt); push(ot, [c, () => { const t = getFocusedElement(); const n = elementIsGenerated(Q); const e = n && t === Q ? Y : t; const c = prepareWrapUnwrapFocus(e); removeAttrs(J, Z); removeAttrs(nt, tt); removeAttrs(Q, j$1); if (g) removeAttrs(b, q$1); if (s) setAttrs(Q, o, s); else removeAttrs(Q, o); if (elementIsGenerated(nt)) unwrap(nt); if (n) unwrap(Q); if (elementIsGenerated(J)) unwrap(J); focusElement(e); c(); }]); if (e && !H) { addAttrClass(Q, j$1, K); push(ot, bind(removeAttrs, Q, j$1)); } focusElement(!H && g && n === Y && t.top === t ? Q : n); c(); st = 0; return ct; }; return [ X, appendElements, ct ]; }; var createTrinsicUpdateSegment = ({ ht: t }) => ({ Qt: n, un: o, At: s }) => { const { $t: e } = n || {}; const { Ot: c } = o; if (t && (e || s)) setStyles(t, { [$]: c && "100%" }); }; var createPaddingUpdateSegment = ({ vt: t, rn: n, L: o, V: s }, e) => { const [c, r] = createCache({ i: equalTRBL, o: topRightBottomLeft() }, bind(topRightBottomLeft, t, "padding", "")); return ({ zt: t, Qt: i, un: l, At: a }) => { let [u, f] = r(a); const { U: _ } = getEnvironment(); const { _t: d, xt: p, Ct: m } = i || {}; const { B: O } = l; const [$, x] = t("paddingAbsolute"); if (d || f || a || p) [u, f] = c(a); const E = !s && (x || m || f); if (E) { const t = !$ || !n && !_; const s = u.r + u.l; const c = u.t + u.b; const r = { [y]: t && !O ? -s : 0, [S$1]: t ? -c : 0, [w$1]: t && O ? -s : 0, top: t ? -u.t : 0, right: t ? O ? -u.r : "auto" : 0, left: t ? O ? "auto" : -u.l : 0, [C$1]: t && `calc(100% + ${s}px)` }; const i = { [v]: t ? u.t : 0, [g$1]: t ? u.r : 0, [b$1]: t ? u.b : 0, [h$1]: t ? u.l : 0 }; setStyles(n || o, r); setStyles(o, i); assignDeep(e, { rn: u, fn: !t, F: n ? i : assignDeep({}, r, i) }); } return { _n: E }; }; }; var createOverflowUpdateSegment = (t, s) => { const e = getEnvironment(); const { vt: r, rn: i, L: a, V: u, Kt: f, gt: _, bt: d, yt: p, an: v } = t; const { U: g } = e; const h = d && u; const b = bind(o, 0); const w = { display: () => false, direction: (t) => t !== "ltr", flexDirection: (t) => t.endsWith("-reverse"), writingMode: (t) => t !== "horizontal-tb" }; const y = keys(w); const S = { i: equalWH, o: { w: 0, h: 0 } }; const m = { i: equalXY, o: {} }; const setMeasuringMode = (t) => { p(J, !h && t); }; const getFlowDirectionStyles = () => getStyles(a, y); const getMeasuredScrollCoordinates = (t, n) => { const o = !keys(t).length; const s = !n && y.some(((n) => { const o = t[n]; return isString(o) && w[n](o); })); if (o && !s || !hasDimensions(a)) return { D: { x: 0, y: 0 }, M: { x: 1, y: 1 } }; setMeasuringMode(true); const r = getElementScroll(_); const i = addEventListener(f, E, ((t) => { const n = getElementScroll(_); if (t.isTrusted && n.x === r.x && n.y === r.y) stopPropagation(t); }), { A: true, T: true }); const u = p(Q, true); scrollElementTo(_, { x: 0, y: 0 }); u(); const d = getElementScroll(_); const v = D$1(_); scrollElementTo(_, { x: v.w, y: v.h }); const g = getElementScroll(_); const h = { x: g.x - d.x, y: g.y - d.y }; scrollElementTo(_, { x: -v.w, y: -v.h }); const b = getElementScroll(_); const S = { x: b.x - d.x, y: b.y - d.y }; const m = { x: c(h.x) >= c(S.x) ? g.x : b.x, y: c(h.y) >= c(S.y) ? g.y : b.y }; scrollElementTo(_, r); l((() => i())); return { D: d, M: m }; }; const getOverflowAmount = (t, o) => { const s = n.devicePixelRatio % 1 !== 0 ? 1 : 0; const e = { w: b(t.w - o.w), h: b(t.h - o.h) }; return { w: e.w > s ? e.w : 0, h: e.h > s ? e.h : 0 }; }; const getViewportOverflowStyle = (t, n) => { const getAxisOverflowStyle = (t, n, o, s) => { const e = t === x$1 ? H : overflowBehaviorToOverflowStyle(t); const c = overflowIsVisible(t); const r = overflowIsVisible(o); if (!n && !s) return H; if (c && r) return x$1; if (c) return n && s ? e : n ? x$1 : H; return n ? e : r && s ? x$1 : H; }; return { x: getAxisOverflowStyle(n.x, t.x, n.y, t.y), y: getAxisOverflowStyle(n.y, t.y, n.x, t.x) }; }; const setViewportOverflowStyle = (t) => { const createAllOverflowStyleClassNames = (t) => [ x$1, H, E ].map(((n) => createViewportOverflowStyleClassName(overflowCssValueToOverflowStyle(n), t))); p(createAllOverflowStyleClassNames(true).concat(createAllOverflowStyleClassNames()).join(" ")); p(keys(t).map(((n) => createViewportOverflowStyleClassName(t[n], n === "x"))).join(" "), true); }; const [O, C] = createCache(S, bind(getFractionalSize, a)); const [$, z] = createCache(S, bind(D$1, a)); const [I, A] = createCache(S); const [M] = createCache(m); const [k, R] = createCache(S); const [V] = createCache(m); const [L] = createCache({ i: (t, n) => equal(t, n, deduplicateArray(concat(keys(t), keys(n)))), o: {} }); const [U, P] = createCache({ i: (t, n) => equalXY(t.D, n.D) && equalXY(t.M, n.M), o: getZeroScrollCoordinates() }); const q = getStaticPluginModuleInstance(xt); const createViewportOverflowStyleClassName = (t, n) => { return `${n ? X : Y}${capitalizeFirstLetter(t)}`; }; return ({ zt: n, Qt: o, un: c, At: l }, { _n: u }) => { const { _t: f, Ht: _, xt: d, Ct: w, ft: y, Et: S } = o || {}; const { X: x, Y: H, W: E } = q && q.R(t, s, c, e, n) || {}; const [D, F] = getShowNativeOverlaidScrollbars(n, e); const [j, X] = n("overflow"); const Y = overflowIsVisible(j.x); const W = overflowIsVisible(j.y); const J = f || u || d || w || S || F; let G = C(l); let Q = z(l); let tt = A(l); let nt = R(l); if (F && g) p(K, !D); if (J) { if (hasAttrClass(r, B$1, N)) setMeasuringMode(true); const t = H && H(); const [n] = G = O(l); const [o] = Q = $(l); const s = T(a); const e = h && getWindowSize(v()); const c = { w: b(o.w + n.w), h: b(o.h + n.h) }; const i = { w: b((e ? e.w : s.w + b(s.w - o.w)) + n.w), h: b((e ? e.h : s.h + b(s.h - o.h)) + n.h) }; if (t) t(); nt = k(i); tt = I(getOverflowAmount(c, i), l); } const [ot, st] = nt; const [et, ct] = tt; const [rt, it] = Q; const [lt, at] = G; const [ut, ft] = M({ x: et.w > 0, y: et.h > 0 }); const _t = Y && W && (ut.x || ut.y) || Y && ut.x && !ut.y || W && ut.y && !ut.x; const dt = u || w || S || at || it || st || ct || X || F || J || _ && h; const [pt] = n("update.flowDirectionStyles"); const [vt, gt] = L(pt ? pt(a) : getFlowDirectionStyles(), l); const [bt, wt] = w || y || gt || ft || l ? U(getMeasuredScrollCoordinates(vt, !!pt), l) : P(); let yt = getViewportOverflowStyle(ut, j); setMeasuringMode(false); if (dt) { setViewportOverflowStyle(yt); yt = getElementOverflowStyle(a, ut); if (E && x) { x(yt, rt, lt); setStyles(a, E(yt)); } } const [St, mt] = V(yt); addRemoveAttrClass(r, B$1, N, _t); addRemoveAttrClass(i, Z, N, _t); assignDeep(s, { cn: St, Vt: { x: ot.w, y: ot.h }, Rt: { x: et.w, y: et.h }, j: ut, Dt: sanitizeScrollCoordinates(bt, et) }); return { sn: mt, tn: st, nn: ct, en: wt || ct }; }; }; var createStructureSetup = (t) => { const [n, o, s] = createStructureSetupElements(t); const e = { rn: { t: 0, r: 0, b: 0, l: 0 }, fn: false, F: { [y]: 0, [S$1]: 0, [w$1]: 0, [v]: 0, [g$1]: 0, [b$1]: 0, [h$1]: 0 }, Vt: { x: 0, y: 0 }, Rt: { x: 0, y: 0 }, cn: { x: H, y: H }, j: { x: false, y: false }, Dt: getZeroScrollCoordinates() }; const { dt: c, gt: r, V: i, St: l } = n; const { U: a, k: u } = getEnvironment(); const f = !a && (u.x || u.y); const _ = [ createTrinsicUpdateSegment(n), createPaddingUpdateSegment(n, e), createOverflowUpdateSegment(n, e) ]; return [ o, (t) => { const n = {}; const s = f && getElementScroll(r); const e = s && l(); each(_, ((o) => { assignDeep(n, o(t, n) || {}); })); scrollElementTo(r, s); if (e) e(); if (!i) scrollElementTo(c, 0); return n; }, e, n, s ]; }; var createSetups = (t, n, o, s, e) => { let c = false; const r = createOptionCheck(n, {}); const [i, l, a, u, f] = createStructureSetup(t); const [_, d, p] = createObserversSetup(u, a, r, ((t) => { update({}, t); })); const [v, g, , h] = createScrollbarsSetup(t, n, p, a, u, e); const updateHintsAreTruthy = (t) => keys(t).some(((n) => !!t[n])); const update = (t, e) => { if (o()) return false; const { dn: r, At: i, It: a, pn: u } = t; const f = r || {}; const _ = !!i || !c; const v = { zt: createOptionCheck(n, f, _), dn: f, At: _ }; if (u) { g(v); return false; } const h = e || d(assignDeep({}, v, { It: a })); const b = l(assignDeep({}, v, { un: p, Qt: h })); g(assignDeep({}, v, { Qt: h, Zt: b })); const w = updateHintsAreTruthy(h); const y = updateHintsAreTruthy(b); const S = w || y || !isEmptyObject(f) || _; c = true; if (S) s(t, { Qt: h, Zt: b }); return S; }; return [ () => { const { ln: t, gt: n, St: o } = u; const s = getElementScroll(t); const e = [ _(), i(), v() ]; const c = o(); scrollElementTo(n, s); c(); return bind(runEachAndClear, e); }, update, () => ({ vn: p, gn: a }), { hn: u, bn: h }, f ]; }; var Vt = /* @__PURE__ */ new WeakMap(); var addInstance = (t, n) => { Vt.set(t, n); }; var removeInstance = (t) => { Vt.delete(t); }; var getInstance = (t) => Vt.get(t); var OverlayScrollbars = (t, n, o) => { const { tt: s } = getEnvironment(); const e = isHTMLElement(t); const c = e ? t : t.target; const r = getInstance(c); if (n && !r) { let r = false; const i = []; const l = {}; const validateOptions = (t) => { const n = removeUndefinedProperties(t); const o = getStaticPluginModuleInstance(R); return o ? o(n, true) : n; }; const a = assignDeep({}, s(), validateOptions(n)); const [u, f, _] = createEventListenerHub(); const [d, p, v] = createEventListenerHub(o); const triggerEvent = (t, n) => { v(t, n); _(t, n); }; const [g, h, b, w, y] = createSetups(t, a, (() => r), (({ dn: t, At: n }, { Qt: o, Zt: s }) => { const { _t: e, Ct: c, $t: r, xt: i, Ht: l, ft: a } = o; const { tn: u, nn: f, sn: _, en: d } = s; triggerEvent("updated", [S, { updateHints: { sizeChanged: !!e, directionChanged: !!c, heightIntrinsicChanged: !!r, overflowEdgeChanged: !!u, overflowAmountChanged: !!f, overflowStyleChanged: !!_, scrollCoordinatesChanged: !!d, contentMutation: !!i, hostMutation: !!l, appear: !!a }, changedOptions: t || {}, force: !!n }]); }), ((t) => triggerEvent("scroll", [S, t]))); const destroy = (t) => { removeInstance(c); runEachAndClear(i); r = true; triggerEvent("destroyed", [S, t]); f(); p(); }; const S = { options(t, n) { if (t) { const e = getOptionsDiff(a, assignDeep(n ? s() : {}, validateOptions(t))); if (!isEmptyObject(e)) { assignDeep(a, e); h({ dn: e }); } } return assignDeep({}, a); }, on: d, off: (t, n) => { if (t && n) p(t, n); }, state() { const { vn: t, gn: n } = b(); const { B: o } = t; const { Vt: s, Rt: e, cn: c, j: i, rn: l, fn: a, Dt: u } = n; return assignDeep({}, { overflowEdge: s, overflowAmount: e, overflowStyle: c, hasOverflow: i, scrollCoordinates: { start: u.D, end: u.M }, padding: l, paddingAbsolute: a, directionRTL: o, destroyed: r }); }, elements() { const { dt: t, vt: n, rn: o, L: s, ht: e, gt: c, Kt: r } = w.hn; const { jt: i, Jt: l } = w.bn; const translateScrollbarStructure = (t) => { const { Mt: n, Ut: o, Lt: s } = t; return { scrollbar: s, track: o, handle: n }; }; const translateScrollbarsSetupElement = (t) => { const { Xt: n, Yt: o } = t; return assignDeep({}, translateScrollbarStructure(n[0]), { clone: () => { const t = translateScrollbarStructure(o()); h({ pn: true }); return t; } }); }; return assignDeep({}, { target: t, host: n, padding: o || s, viewport: s, content: e || s, scrollOffsetElement: c, scrollEventElement: r, scrollbarHorizontal: translateScrollbarsSetupElement(i), scrollbarVertical: translateScrollbarsSetupElement(l) }); }, update: (t) => h({ At: t, It: true }), destroy: bind(destroy, false), plugin: (t) => l[keys(t)[0]] }; push(i, [y]); addInstance(c, S); registerPluginModuleInstances(M, OverlayScrollbars, [ S, u, l ]); if (cancelInitialization(w.hn.bt, !e && t.cancel)) { destroy(true); return S; } push(i, g()); triggerEvent("initialized", [S]); S.update(); return S; } return r; }; OverlayScrollbars.plugin = (t) => { const n = isArray(t); const o = n ? t : [t]; const s = o.map(((t) => registerPluginModuleInstances(t, OverlayScrollbars)[0])); addPlugins(o); return n ? s : s[0]; }; OverlayScrollbars.valid = (t) => { const n = t && t.elements; const o = isFunction(n) && n(); return isPlainObject(o) && !!getInstance(o.target); }; OverlayScrollbars.env = () => { const { P: t, k: n, U: o, J: s, ot: e, st: c, K: r, Z: i, tt: l, nt: a } = getEnvironment(); return assignDeep({}, { scrollbarsSize: t, scrollbarsOverlaid: n, scrollbarsHiding: o, scrollTimeline: s, staticDefaultInitialization: e, staticDefaultOptions: c, getDefaultInitialization: r, setDefaultInitialization: i, getDefaultOptions: l, setDefaultOptions: a }); }; OverlayScrollbars.nonce = setNonce; OverlayScrollbars.trustedTypePolicy = setTrustedTypePolicy; //#endregion //#region node_modules/overlayscrollbars-vue/overlayscrollbars-vue.mjs var g = () => { if (typeof window > "u") { const o = () => {}; return [o, o]; } let a, t; const n = window, l = typeof n.requestIdleCallback == "function", s = n.requestAnimationFrame, r = n.cancelAnimationFrame, f = l ? n.requestIdleCallback : s, p = l ? n.cancelIdleCallback : r, e = () => { p(a), r(t); }; return [(o, m) => { e(), a = f(l ? () => { e(), t = s(o); } : o, typeof m == "object" ? m : { timeout: 2233 }); }, e]; }, x = (a) => { let t = null, n, l, s; const r = (0, vue.shallowRef)(a || {}), [f, p] = g(); return (0, vue.watch)(() => { var e; return (0, vue.unref)((e = r.value) == null ? void 0 : e.defer); }, (e) => { s = e; }, { deep: !0, immediate: !0 }), (0, vue.watch)(() => { var e; return (0, vue.unref)((e = r.value) == null ? void 0 : e.options); }, (e) => { n = e, OverlayScrollbars.valid(t) && t.options(n || {}, !0); }, { deep: !0, immediate: !0 }), (0, vue.watch)(() => { var e; return (0, vue.unref)((e = r.value) == null ? void 0 : e.events); }, (e) => { l = e, OverlayScrollbars.valid(t) && t.on( /* c8 ignore next */ l || {}, !0 ); }, { deep: !0, immediate: !0 }), (0, vue.onUnmounted)(() => { p(), t?.destroy(); }), [(e) => { if (OverlayScrollbars.valid(t)) return t; const o = () => t = OverlayScrollbars(e, n || {}, l || {}); s ? f(o, s) : o(); }, () => t]; }, P = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlayScrollbarsComponent", props: { element: { type: [String, Object], default: "div" }, options: { type: Object }, events: { type: Object }, defer: { type: [Boolean, Object] } }, emits: [ "osInitialized", "osUpdated", "osDestroyed", "osScroll" ], setup(a, { expose: t, emit: n }) { const l = a, s = { initialized: "osInitialized", updated: "osUpdated", destroyed: "osDestroyed", scroll: "osScroll" }, { element: r, options: f, events: p, defer: e } = (0, vue.toRefs)(l), o = (0, vue.shallowRef)(null), m = (0, vue.shallowRef)(null), I = (0, vue.ref)(), [E, O] = x({ options: f, events: I, defer: e }); return t({ osInstance: O, getElement: () => o.value }), (0, vue.watchPostEffect)((c) => { const { value: i } = o, { value: v } = m; i && (E(r.value === "body" ? { target: i, cancel: { body: null } } : { target: i, elements: { viewport: v, content: v } }), c(() => { var d; return (d = O()) == null ? void 0 : d.destroy(); })); }), (0, vue.watch)(() => (0, vue.unref)(p), (c) => { const i = c || {}; I.value = Object.keys(s).reduce((v, d) => { const k = i[d]; return v[d] = [(...R) => n(s[d], ...R), ...(Array.isArray(k) ? k : [k]).filter(Boolean)], v; }, {}); }, { deep: !0, immediate: !0 }), (c, i) => ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(r)), { "data-overlayscrollbars-initialize": "", ref_key: "elementRef", ref: o }, { default: (0, vue.withCtx)(() => [(0, vue.unref)(r) === "body" ? (0, vue.renderSlot)(c.$slots, "default", { key: 0 }) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 1, "data-overlayscrollbars-contents": "", ref_key: "slotRef", ref: m }, [(0, vue.renderSlot)(c.$slots, "default")], 512))]), _: 3 }, 512)); } }); //#endregion //#region src/core/ui/OverlayEncodeTab.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$5 = ["placeholder"]; var _hoisted_2$4 = ["placeholder", "value"]; //#endregion //#region src/core/ui/OverlayEncodeTab.vue var OverlayEncodeTab_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlayEncodeTab", props: { accent: {} }, setup(__props) { const props = __props; const inputText = (0, vue.ref)(""); const count = (0, vue.ref)(1); const copied = (0, vue.ref)(false); (0, vue.watch)(count, (v) => { if (v < 1) count.value = 1; if (v > 10) count.value = 10; }); const outputText = (0, vue.computed)(() => { const input = inputText.value; if (!input) return ""; if (count.value > 1) return encodeRecursive(input, count.value).output; return encode(input); }); (0, vue.watch)([inputText, count], () => { copied.value = false; }); async function copyOutput() { if (!outputText.value) return; if (await getAdapter().writeClipboard(outputText.value)) { await getAdapter().addEntry("encode", inputText.value, outputText.value, count.value); copied.value = true; setTimeout(() => copied.value = false, 1500); } } const wrapStyle = { padding: "12px 14px", display: "flex", flexDirection: "column", gap: "8px" }; const optBarStyle = { display: "flex", alignItems: "center", gap: "12px", padding: "6px 10px", background: "#f8f9fa", borderRadius: "8px" }; const optGroupStyle = { display: "flex", alignItems: "center", gap: "6px" }; const optIconStyle = { color: "#888", display: "flex", alignItems: "center" }; const optLabelStyle = { fontSize: "12px", fontWeight: "600", color: "#555" }; const stepperWrapStyle = { display: "flex", alignItems: "center", border: "1px solid #ddd", borderRadius: "6px", overflow: "hidden" }; const stepBtnStyle = { width: "26px", height: "26px", border: "none", background: "#f3f4f6", cursor: "pointer", fontSize: "14px", fontWeight: "600", color: "#555", display: "flex", alignItems: "center", justifyContent: "center" }; const stepValueStyle = { width: "28px", textAlign: "center", fontSize: "13px", fontWeight: "600", color: "#333", background: "#fff", lineHeight: "26px" }; const textareaBase = { width: "100%", minHeight: "72px", padding: "10px", border: "1px solid #ddd", borderRadius: "8px", resize: "vertical", fontFamily: "monospace", fontSize: "13px", lineHeight: "1.5", boxSizing: "border-box", outline: "none" }; const textareaStyle = { ...textareaBase }; const outputAreaStyle = { ...textareaBase, background: "#f9fafb", color: "#333" }; const copyBtnComputed = (0, vue.computed)(() => ({ padding: "8px 0", border: "none", borderRadius: "8px", background: props.accent, color: "#fff", cursor: "pointer", fontSize: "13px", fontWeight: "600" })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { style: wrapStyle }, [ (0, vue.createElementVNode)("div", { style: optBarStyle }, [(0, vue.createElementVNode)("div", { style: optGroupStyle }, [ (0, vue.createVNode)((0, vue.unref)(Repeat), { size: 14, style: optIconStyle }), (0, vue.createElementVNode)("span", { style: optLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("repeat")), 1), (0, vue.createElementVNode)("div", { style: stepperWrapStyle }, [ (0, vue.createElementVNode)("button", { style: stepBtnStyle, onClick: _cache[0] || (_cache[0] = ($event) => count.value = Math.max(1, count.value - 1)) }, "−"), (0, vue.createElementVNode)("span", { style: stepValueStyle }, (0, vue.toDisplayString)(count.value), 1), (0, vue.createElementVNode)("button", { style: stepBtnStyle, onClick: _cache[1] || (_cache[1] = ($event) => count.value = Math.min(10, count.value + 1)) }, "+") ]) ])]), (0, vue.withDirectives)((0, vue.createElementVNode)("textarea", { style: textareaStyle, placeholder: (0, vue.unref)(t)("inputEncode"), "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => inputText.value = $event) }, null, 8, _hoisted_1$5), [[vue.vModelText, inputText.value]]), (0, vue.createElementVNode)("textarea", { style: outputAreaStyle, placeholder: (0, vue.unref)(t)("outputEncode"), value: outputText.value, readonly: "" }, null, 8, _hoisted_2$4), (0, vue.createElementVNode)("button", { style: (0, vue.normalizeStyle)(copyBtnComputed.value), onClick: copyOutput }, (0, vue.toDisplayString)(copied.value ? (0, vue.unref)(t)("copied") : (0, vue.unref)(t)("copyOutput")), 5) ]); }; } }); //#endregion //#region src/core/ui/OverlayDecodeTab.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$4 = ["placeholder"]; var _hoisted_2$3 = ["placeholder", "value"]; //#endregion //#region src/core/ui/OverlayDecodeTab.vue var OverlayDecodeTab_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlayDecodeTab", props: { accent: {} }, setup(__props) { const props = __props; const inputText = (0, vue.ref)(""); const count = (0, vue.ref)(1); const autoStop = (0, vue.ref)(true); const copied = (0, vue.ref)(false); (0, vue.watch)(count, (v) => { if (v < 1) count.value = 1; if (v > 10) count.value = 10; }); const result = (0, vue.computed)(() => { const input = inputText.value; if (!input) return null; if (count.value > 1) return decodeRecursive(input, count.value, !autoStop.value); const r = decode(input); return r.ok ? { ok: true, output: r.text, iterations: 1 } : r; }); const outputDisplay = (0, vue.computed)(() => { const r = result.value; if (!r) return ""; return r.ok ? r.output : t("decodeFailed"); }); (0, vue.watch)([ inputText, count, autoStop ], () => { copied.value = false; }); async function copyOutput() { const r = result.value; if (!r || !r.ok) return; if (await getAdapter().writeClipboard(r.output)) { await getAdapter().addEntry("decode", inputText.value, r.output, r.iterations); copied.value = true; setTimeout(() => copied.value = false, 1500); } } const wrapStyle = { padding: "12px 14px", display: "flex", flexDirection: "column", gap: "8px" }; const optBarStyle = { display: "flex", alignItems: "center", gap: "10px", padding: "6px 10px", background: "#f8f9fa", borderRadius: "8px" }; const optGroupStyle = { display: "flex", alignItems: "center", gap: "6px" }; const optDivStyle = { width: "1px", height: "20px", background: "#ddd" }; const optIconStyle = { color: "#888", display: "flex", alignItems: "center" }; const optLabelStyle = { fontSize: "12px", fontWeight: "600", color: "#555" }; const stepperWrapStyle = { display: "flex", alignItems: "center", border: "1px solid #ddd", borderRadius: "6px", overflow: "hidden" }; const stepBtnStyle = { width: "26px", height: "26px", border: "none", background: "#f3f4f6", cursor: "pointer", fontSize: "14px", fontWeight: "600", color: "#555", display: "flex", alignItems: "center", justifyContent: "center" }; const stepValueStyle = { width: "28px", textAlign: "center", fontSize: "13px", fontWeight: "600", color: "#333", background: "#fff", lineHeight: "26px" }; const toggleRowStyle = { display: "flex", alignItems: "center", gap: "6px", cursor: "pointer" }; const toggleTrackComputed = (0, vue.computed)(() => ({ width: "32px", height: "18px", borderRadius: "9px", background: autoStop.value ? props.accent : "#ccc", position: "relative", transition: "background 0.2s", cursor: "pointer", flexShrink: "0" })); const toggleThumbComputed = (0, vue.computed)(() => ({ width: "14px", height: "14px", borderRadius: "50%", background: "#fff", position: "absolute", top: "2px", left: autoStop.value ? "16px" : "2px", transition: "left 0.2s", boxShadow: "0 1px 3px rgba(0,0,0,0.2)" })); const textareaBase = { width: "100%", minHeight: "72px", padding: "10px", border: "1px solid #ddd", borderRadius: "8px", resize: "vertical", fontFamily: "monospace", fontSize: "13px", lineHeight: "1.5", boxSizing: "border-box", outline: "none" }; const textareaStyle = { ...textareaBase }; const outputAreaStyle = { ...textareaBase, background: "#f9fafb", color: "#333" }; const copyBtnComputed = (0, vue.computed)(() => ({ padding: "8px 0", border: "none", borderRadius: "8px", background: props.accent, color: "#fff", cursor: "pointer", fontSize: "13px", fontWeight: "600" })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { style: wrapStyle }, [ (0, vue.createElementVNode)("div", { style: optBarStyle }, [ (0, vue.createElementVNode)("div", { style: optGroupStyle }, [ (0, vue.createVNode)((0, vue.unref)(Repeat), { size: 14, style: optIconStyle }), (0, vue.createElementVNode)("span", { style: optLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("repeat")), 1), (0, vue.createElementVNode)("div", { style: stepperWrapStyle }, [ (0, vue.createElementVNode)("button", { style: stepBtnStyle, onClick: _cache[0] || (_cache[0] = ($event) => count.value = Math.max(1, count.value - 1)) }, "−"), (0, vue.createElementVNode)("span", { style: stepValueStyle }, (0, vue.toDisplayString)(count.value), 1), (0, vue.createElementVNode)("button", { style: stepBtnStyle, onClick: _cache[1] || (_cache[1] = ($event) => count.value = Math.min(10, count.value + 1)) }, "+") ]) ]), (0, vue.createElementVNode)("div", { style: optDivStyle }), (0, vue.createElementVNode)("label", { style: toggleRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrackComputed.value), onClick: _cache[2] || (_cache[2] = (0, vue.withModifiers)(($event) => autoStop.value = !autoStop.value, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumbComputed.value) }, null, 4)], 4), (0, vue.createElementVNode)("span", { style: optLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("autoStop")), 1)]) ]), (0, vue.withDirectives)((0, vue.createElementVNode)("textarea", { style: textareaStyle, placeholder: (0, vue.unref)(t)("inputDecode"), "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => inputText.value = $event) }, null, 8, _hoisted_1$4), [[vue.vModelText, inputText.value]]), (0, vue.createElementVNode)("textarea", { style: outputAreaStyle, placeholder: (0, vue.unref)(t)("outputDecode"), value: outputDisplay.value, readonly: "" }, null, 8, _hoisted_2$3), (0, vue.createElementVNode)("button", { style: (0, vue.normalizeStyle)(copyBtnComputed.value), onClick: copyOutput }, (0, vue.toDisplayString)(copied.value ? (0, vue.unref)(t)("copied") : (0, vue.unref)(t)("copyOutput")), 5) ]); }; } }); //#endregion //#region src/core/ui/OverlayHistoryTab.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$3 = ["src"]; var _hoisted_2$2 = ["onClick"]; //#endregion //#region src/core/ui/OverlayHistoryTab.vue var OverlayHistoryTab_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlayHistoryTab", props: { accent: {} }, setup(__props) { const props = __props; const buckets = (0, vue.ref)([]); const selectedEntry = (0, vue.ref)(null); (0, vue.onMounted)(load); async function load() { buckets.value = await getAdapter().listBuckets(); } async function clearAll() { await getAdapter().clearHistory(); buckets.value = []; } function truncate(s, max) { return s.length > max ? s.slice(0, max) + "…" : s; } function actionLabel(a) { return { encode: "Enc", decode: "Dec", "decode-url-new-tab": "URL→", "decode-url-current-tab": "URL↗" }[a] ?? a; } function timeAgo(ts) { const diff = Date.now() - ts; const sec = Math.floor(diff / 1e3); if (sec < 60) return "just now"; const min = Math.floor(sec / 60); if (min < 60) return `${min}m`; const hr = Math.floor(min / 60); if (hr < 24) return `${hr}h`; return `${Math.floor(hr / 24)}d`; } const wrapStyle = { padding: "12px 14px", display: "flex", flexDirection: "column", gap: "8px" }; const topBarStyle = { display: "flex", justifyContent: "space-between", alignItems: "center" }; const titleStyle = { fontWeight: "700", fontSize: "13px", color: "#333" }; const clearBtnComputed = (0, vue.computed)(() => ({ padding: "4px 10px", border: "1px solid #ddd", borderRadius: "6px", background: "#fff", cursor: "pointer", fontSize: "12px", color: props.accent })); const emptyStyle = { textAlign: "center", color: "#999", padding: "32px 0", fontSize: "13px" }; const listStyle = { display: "flex", flexDirection: "column", gap: "2px" }; const bucketHeaderStyle = { display: "flex", alignItems: "center", gap: "6px", padding: "6px 0 2px", marginTop: "4px" }; const faviconStyle = { width: "14px", height: "14px", borderRadius: "2px" }; const domainStyle = { fontWeight: "600", fontSize: "12px", color: "#555" }; const entryStyle = { display: "flex", alignItems: "center", gap: "6px", padding: "5px 8px", borderRadius: "6px", cursor: "pointer", background: "#f9fafb" }; const entryTextStyle = { flex: "1", fontSize: "12px", color: "#333", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }; const timeStyle = { fontSize: "11px", color: "#999", flexShrink: "0" }; function actionBadgeStyle(action) { return { padding: "1px 6px", borderRadius: "4px", fontSize: "10px", fontWeight: "700", background: action.startsWith("decode-url") ? "#7c3aed" : props.accent, color: "#fff", flexShrink: "0" }; } const backdropStyle = { position: "fixed", inset: "0", background: "rgba(0,0,0,0.45)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 2147483647 }; const modalStyle = { background: "#fff", borderRadius: "12px", width: "360px", maxHeight: "80vh", display: "flex", flexDirection: "column", boxShadow: "0 12px 40px rgba(0,0,0,0.2)", overflow: "hidden" }; const modalHeaderStyle = { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "12px 16px", borderBottom: "1px solid #eee" }; const modalTitleStyle = { fontWeight: "700", fontSize: "14px" }; const modalCloseBtnStyle = { background: "none", border: "none", fontSize: "20px", cursor: "pointer", color: "#888", lineHeight: "1" }; const modalBodyStyle = { padding: "12px 16px", overflowY: "auto", display: "flex", flexDirection: "column", gap: "10px" }; const fieldStyle = { display: "flex", flexDirection: "column", gap: "2px" }; const fieldLabelStyle = { fontSize: "11px", fontWeight: "600", color: "#888", textTransform: "uppercase" }; const preStyle = { margin: "0", padding: "8px", background: "#f5f5f5", borderRadius: "6px", fontSize: "12px", fontFamily: "monospace", lineHeight: "1.5", whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: "120px", overflowY: "auto" }; return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { style: wrapStyle }, [ (0, vue.createElementVNode)("div", { style: topBarStyle }, [(0, vue.createElementVNode)("span", { style: titleStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("history")), 1), buckets.value.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", { key: 0, style: (0, vue.normalizeStyle)(clearBtnComputed.value), onClick: clearAll }, (0, vue.toDisplayString)((0, vue.unref)(t)("clearAll")), 5)) : (0, vue.createCommentVNode)("", true)]), !buckets.value.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 0, style: emptyStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("noHistory")), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 1, style: listStyle }, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(buckets.value, (bucket) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: bucket.domain }, [(0, vue.createElementVNode)("div", { style: bucketHeaderStyle }, [bucket.entries[0]?.favIconUrl ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("img", { key: 0, src: bucket.entries[0].favIconUrl, style: faviconStyle }, null, 8, _hoisted_1$3)) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("span", { style: domainStyle }, (0, vue.toDisplayString)(bucket.domain), 1)]), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(bucket.entries, (entry) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: entry.id, style: entryStyle, onClick: ($event) => selectedEntry.value = entry }, [ (0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(actionBadgeStyle(entry.action)) }, (0, vue.toDisplayString)(actionLabel(entry.action)), 5), (0, vue.createElementVNode)("span", { style: entryTextStyle }, (0, vue.toDisplayString)(truncate(entry.input, 40)), 1), (0, vue.createElementVNode)("span", { style: timeStyle }, (0, vue.toDisplayString)(timeAgo(entry.createdAt)), 1) ], 8, _hoisted_2$2); }), 128))], 64); }), 128))])), selectedEntry.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 2, style: backdropStyle, onClick: _cache[1] || (_cache[1] = (0, vue.withModifiers)(($event) => selectedEntry.value = null, ["self"])) }, [(0, vue.createElementVNode)("div", { style: modalStyle }, [(0, vue.createElementVNode)("div", { style: modalHeaderStyle }, [(0, vue.createElementVNode)("span", { style: modalTitleStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("detail")), 1), (0, vue.createElementVNode)("button", { style: modalCloseBtnStyle, onClick: _cache[0] || (_cache[0] = ($event) => selectedEntry.value = null) }, "×")]), (0, vue.createElementVNode)("div", { style: modalBodyStyle }, [ (0, vue.createElementVNode)("div", { style: fieldStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("action")), 1), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(actionLabel(selectedEntry.value.action)), 1)]), (0, vue.createElementVNode)("div", { style: fieldStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("page")), 1), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(selectedEntry.value.pageTitle || selectedEntry.value.url), 1)]), (0, vue.createElementVNode)("div", { style: fieldStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("input")), 1), (0, vue.createElementVNode)("pre", { style: preStyle }, (0, vue.toDisplayString)(selectedEntry.value.input), 1)]), (0, vue.createElementVNode)("div", { style: fieldStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("output")), 1), (0, vue.createElementVNode)("pre", { style: preStyle }, (0, vue.toDisplayString)(selectedEntry.value.output), 1)]), (0, vue.createElementVNode)("div", { style: fieldStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("iterations")), 1), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(selectedEntry.value.iterations), 1)]), (0, vue.createElementVNode)("div", { style: fieldStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabelStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("time")), 1), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(new Date(selectedEntry.value.createdAt).toLocaleString()), 1)]) ])])])) : (0, vue.createCommentVNode)("", true) ]); }; } }); //#endregion //#region src/core/ui/OverlaySettingsTab.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$2 = ["disabled", "onClick"]; var _hoisted_2$1 = ["onClick"]; var _hoisted_3 = ["onClick"]; //#endregion //#region src/core/ui/OverlaySettingsTab.vue var OverlaySettingsTab_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlaySettingsTab", props: { accent: {} }, emits: ["settings-changed"], setup(__props, { emit: __emit }) { const props = __props; const emit = __emit; const s = (0, vue.reactive)({ ...DEFAULT_SETTINGS }); let ready = false; const FAB_POSITIONS_GRID = [ "top-left", "top-center", "top-right", "middle-left", null, "middle-right", "bottom-left", "bottom-center", "bottom-right" ]; const langs = [ { code: "en", label: "EN" }, { code: "ko", label: "한" }, { code: "ja", label: "日" } ]; (0, vue.onMounted)(async () => { const loaded = await getAdapter().loadSettings(); Object.assign(s, loaded); await (0, vue.nextTick)(); ready = true; }); (0, vue.watch)(s, async () => { if (!ready) return; const normalized = normalizeSettings({ ...s }); setI18nLanguage(normalized.language); await getAdapter().saveSettings(normalized); emit("settings-changed", normalized); }); function toggleTrack(on) { return { width: "32px", height: "18px", borderRadius: "9px", background: on ? props.accent : "#ccc", position: "relative", transition: "background 0.2s", cursor: "pointer", flexShrink: "0", display: "inline-block" }; } function toggleThumb(on) { return { width: "14px", height: "14px", borderRadius: "50%", background: "#fff", position: "absolute", top: "2px", left: on ? "16px" : "2px", transition: "left 0.2s", boxShadow: "0 1px 3px rgba(0,0,0,0.2)" }; } const wrapStyle = { padding: "12px 14px", display: "flex", flexDirection: "column", gap: "10px", fontSize: "13px" }; const groupStyle = { border: "1px solid #eee", borderRadius: "8px", padding: "8px 10px", margin: "0", display: "flex", flexDirection: "column", gap: "8px" }; const legendStyle = { fontWeight: "600", fontSize: "12px", color: "#666", padding: "0 4px" }; const fieldRowStyle = { display: "flex", flexDirection: "column", gap: "6px" }; const fieldLabel = { fontSize: "12px", fontWeight: "600", color: "#555" }; const checkRowStyle = { display: "flex", alignItems: "center", gap: "8px", cursor: "pointer", fontSize: "12px" }; const indentStyle = { paddingLeft: "20px", display: "flex", flexDirection: "column", gap: "6px" }; const inlineRowStyle = { display: "flex", alignItems: "center", gap: "8px" }; const smLabel = { fontSize: "12px", color: "#555" }; const numInput = { width: "50px", padding: "3px 6px", border: "1px solid #ddd", borderRadius: "6px", fontSize: "12px", textAlign: "center", outline: "none" }; const posGridStyle = { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "4px", width: "120px" }; const posBtnStyle = { width: "36px", height: "28px", borderRadius: "4px", border: "1px solid #ddd", background: "#fff", cursor: "pointer", fontSize: "14px", display: "flex", alignItems: "center", justifyContent: "center", color: "#666" }; const posActiveBtnComputed = (0, vue.computed)(() => ({ ...posBtnStyle, border: `2px solid ${props.accent}`, background: props.accent + "18", color: props.accent, fontWeight: "700" })); const posEmptyStyle = { width: "36px", height: "28px", visibility: "hidden" }; const colorGridStyle = { display: "grid", gridTemplateColumns: "repeat(8, 1fr)", gap: "5px" }; function colorSwatchStyle(c, active) { return { width: "22px", height: "22px", borderRadius: "50%", border: active ? "2px solid #333" : "2px solid transparent", background: c, cursor: "pointer", outline: active ? `2px solid ${c}44` : "none", outlineOffset: "1px" }; } const langRowStyle = { display: "flex", gap: "4px" }; const langBtnStyle = { padding: "4px 12px", borderRadius: "6px", border: "1px solid #ddd", background: "#fff", cursor: "pointer", fontSize: "12px", fontWeight: "600", color: "#555" }; const langActiveBtnComputed = (0, vue.computed)(() => ({ ...langBtnStyle, border: `1px solid ${props.accent}`, background: props.accent + "18", color: props.accent })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { style: wrapStyle }, [ (0, vue.createElementVNode)("fieldset", { style: groupStyle }, [ (0, vue.createElementVNode)("legend", { style: legendStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("appearance")), 1), (0, vue.createElementVNode)("div", { style: fieldRowStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabel }, (0, vue.toDisplayString)((0, vue.unref)(t)("buttonPosition")), 1), (0, vue.createElementVNode)("div", { style: posGridStyle }, [((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(FAB_POSITIONS_GRID, (pos) => { return (0, vue.createElementVNode)("button", { key: pos || "center", style: (0, vue.normalizeStyle)(pos ? s.fabPosition === pos ? posActiveBtnComputed.value : posBtnStyle : posEmptyStyle), disabled: !pos, onClick: ($event) => pos && (s.fabPosition = pos) }, (0, vue.toDisplayString)(pos ? (0, vue.unref)(t)("pos-" + pos) : ""), 13, _hoisted_1$2); }), 64))])]), (0, vue.createElementVNode)("div", { style: fieldRowStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabel }, (0, vue.toDisplayString)((0, vue.unref)(t)("accentColor")), 1), (0, vue.createElementVNode)("div", { style: colorGridStyle }, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)((0, vue.unref)(COLOR_PRESETS), (c) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", { key: c, style: (0, vue.normalizeStyle)(colorSwatchStyle(c, s.accentColor === c)), onClick: ($event) => s.accentColor = c }, null, 12, _hoisted_2$1); }), 128))])]), (0, vue.createElementVNode)("div", { style: fieldRowStyle }, [(0, vue.createElementVNode)("span", { style: fieldLabel }, (0, vue.toDisplayString)((0, vue.unref)(t)("language")), 1), (0, vue.createElementVNode)("div", { style: langRowStyle }, [((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(langs, (l) => { return (0, vue.createElementVNode)("button", { key: l.code, style: (0, vue.normalizeStyle)(s.language === l.code ? langActiveBtnComputed.value : langBtnStyle), onClick: ($event) => s.language = l.code }, (0, vue.toDisplayString)(l.label), 13, _hoisted_3); }), 64))])]) ]), (0, vue.createElementVNode)("fieldset", { style: groupStyle }, [ (0, vue.createElementVNode)("legend", { style: legendStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("general")), 1), (0, vue.createElementVNode)("label", { style: checkRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrack(s.contextMenuEnabled)), onClick: _cache[0] || (_cache[0] = (0, vue.withModifiers)(($event) => s.contextMenuEnabled = !s.contextMenuEnabled, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumb(s.contextMenuEnabled)) }, null, 4)], 4), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("contextMenu")), 1)]), (0, vue.createElementVNode)("label", { style: checkRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrack(s.autoClosePanel)), onClick: _cache[1] || (_cache[1] = (0, vue.withModifiers)(($event) => s.autoClosePanel = !s.autoClosePanel, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumb(s.autoClosePanel)) }, null, 4)], 4), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("autoClosePanel")), 1)]), (0, vue.createElementVNode)("label", { style: checkRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrack(s.activateNewTab)), onClick: _cache[2] || (_cache[2] = (0, vue.withModifiers)(($event) => s.activateNewTab = !s.activateNewTab, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumb(s.activateNewTab)) }, null, 4)], 4), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("activateNewTab")), 1)]), (0, vue.createElementVNode)("label", { style: checkRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrack(s.clearInputOnTabSwitch)), onClick: _cache[3] || (_cache[3] = (0, vue.withModifiers)(($event) => s.clearInputOnTabSwitch = !s.clearInputOnTabSwitch, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumb(s.clearInputOnTabSwitch)) }, null, 4)], 4), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("clearInputOnSwitch")), 1)]) ]), (0, vue.createElementVNode)("fieldset", { style: groupStyle }, [ (0, vue.createElementVNode)("legend", { style: legendStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("decode")), 1), (0, vue.createElementVNode)("label", { style: checkRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrack(s.recursiveDecodeEnabled)), onClick: _cache[4] || (_cache[4] = (0, vue.withModifiers)(($event) => s.recursiveDecodeEnabled = !s.recursiveDecodeEnabled, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumb(s.recursiveDecodeEnabled)) }, null, 4)], 4), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("recursiveDecode")), 1)]), s.recursiveDecodeEnabled ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 0, style: indentStyle }, [(0, vue.createElementVNode)("div", { style: inlineRowStyle }, [(0, vue.createElementVNode)("span", { style: smLabel }, (0, vue.toDisplayString)((0, vue.unref)(t)("count")), 1), (0, vue.withDirectives)((0, vue.createElementVNode)("input", { type: "number", min: "1", max: "10", "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => s.recursiveDecodeCount = $event), style: numInput }, null, 512), [[ vue.vModelText, s.recursiveDecodeCount, void 0, { number: true } ]])]), (0, vue.createElementVNode)("label", { style: checkRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrack(s.recursiveDecodeForceEnabled)), onClick: _cache[6] || (_cache[6] = (0, vue.withModifiers)(($event) => s.recursiveDecodeForceEnabled = !s.recursiveDecodeForceEnabled, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumb(s.recursiveDecodeForceEnabled)) }, null, 4)], 4), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("forceIgnoreErrors")), 1)])])) : (0, vue.createCommentVNode)("", true) ]), (0, vue.createElementVNode)("fieldset", { style: groupStyle }, [ (0, vue.createElementVNode)("legend", { style: legendStyle }, (0, vue.toDisplayString)((0, vue.unref)(t)("encode")), 1), (0, vue.createElementVNode)("label", { style: checkRowStyle }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleTrack(s.recursiveEncodeEnabled)), onClick: _cache[7] || (_cache[7] = (0, vue.withModifiers)(($event) => s.recursiveEncodeEnabled = !s.recursiveEncodeEnabled, ["prevent"])) }, [(0, vue.createElementVNode)("span", { style: (0, vue.normalizeStyle)(toggleThumb(s.recursiveEncodeEnabled)) }, null, 4)], 4), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("recursiveEncode")), 1)]), s.recursiveEncodeEnabled ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 0, style: indentStyle }, [(0, vue.createElementVNode)("div", { style: inlineRowStyle }, [(0, vue.createElementVNode)("span", { style: smLabel }, (0, vue.toDisplayString)((0, vue.unref)(t)("count")), 1), (0, vue.withDirectives)((0, vue.createElementVNode)("input", { type: "number", min: "1", max: "10", "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => s.recursiveEncodeCount = $event), style: numInput }, null, 512), [[ vue.vModelText, s.recursiveEncodeCount, void 0, { number: true } ]])])])) : (0, vue.createCommentVNode)("", true) ]) ]); }; } }); //#endregion //#region src/core/ui/OverlayPanel.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$1 = ["title"]; var _hoisted_2 = ["title"]; //#endregion //#region src/core/ui/OverlayPanel.vue var OverlayPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlayPanel", props: { accent: {}, position: {} }, emits: ["close", "settings-changed"], setup(__props) { const props = __props; const view = (0, vue.ref)("encode"); const bodyStyle = { flex: "1", overflow: "hidden" }; function panelPositionCSS(pos) { const m = "24px"; const offset = "72px"; const isLeft = pos.includes("left"); const isRight = pos.includes("right"); const isTop = pos.startsWith("top"); const isMiddle = pos.startsWith("middle"); const isBottom = pos.startsWith("bottom"); const isCenter = pos.includes("center"); const css = {}; if (isRight) css.right = m; else if (isLeft) css.left = m; else if (isCenter) { css.left = "50%"; css.transform = "translateX(-50%)"; } if (isBottom) css.bottom = offset; else if (isTop) css.top = offset; else if (isMiddle) { css.top = "50%"; css.transform = (css.transform || "") + " translateY(-50%)"; } return css; } const panelComputed = (0, vue.computed)(() => ({ position: "fixed", width: "380px", maxHeight: "520px", background: "#fff", borderRadius: "12px", boxShadow: "0 8px 32px rgba(0,0,0,0.18)", fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif", fontSize: "14px", color: "#1a1a1a", display: "flex", flexDirection: "column", zIndex: 2147483646, overflow: "hidden", ...panelPositionCSS(props.position) })); const headerStyle = { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 12px", borderBottom: "1px solid #eee", gap: "4px" }; const navStyle = { display: "flex", alignItems: "center", gap: "2px" }; const navSepStyle = { width: "1px", height: "20px", background: "#e0e0e0", margin: "0 4px" }; const navTextBase = { padding: "5px 10px", borderRadius: "6px", border: "none", cursor: "pointer", fontSize: "13px", fontWeight: "600", transition: "background 0.15s, color 0.15s" }; const navTextStyle = { ...navTextBase, background: "transparent", color: "#666" }; const navActiveTextStyle = (0, vue.computed)(() => ({ ...navTextBase, background: props.accent + "18", color: props.accent })); const navIconBase = { width: "30px", height: "30px", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", transition: "background 0.15s" }; const navIconStyle = { ...navIconBase, background: "transparent", color: "#666" }; const navActiveIconStyle = (0, vue.computed)(() => ({ ...navIconBase, background: props.accent + "18", color: props.accent })); const closeBtnStyle = { background: "none", border: "none", fontSize: "20px", cursor: "pointer", color: "#888", lineHeight: "1", padding: "0 4px" }; return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { style: (0, vue.normalizeStyle)(panelComputed.value) }, [(0, vue.createElementVNode)("div", { style: headerStyle }, [(0, vue.createElementVNode)("div", { style: navStyle }, [ (0, vue.createElementVNode)("button", { style: (0, vue.normalizeStyle)(view.value === "encode" ? navActiveTextStyle.value : navTextStyle), onClick: _cache[0] || (_cache[0] = ($event) => view.value = "encode") }, (0, vue.toDisplayString)((0, vue.unref)(t)("encode")), 5), (0, vue.createElementVNode)("button", { style: (0, vue.normalizeStyle)(view.value === "decode" ? navActiveTextStyle.value : navTextStyle), onClick: _cache[1] || (_cache[1] = ($event) => view.value = "decode") }, (0, vue.toDisplayString)((0, vue.unref)(t)("decode")), 5), (0, vue.createElementVNode)("div", { style: navSepStyle }), (0, vue.createElementVNode)("button", { style: (0, vue.normalizeStyle)(view.value === "history" ? navActiveIconStyle.value : navIconStyle), title: (0, vue.unref)(t)("history"), onClick: _cache[2] || (_cache[2] = ($event) => view.value = "history") }, [(0, vue.createVNode)((0, vue.unref)(Clock), { size: 15 })], 12, _hoisted_1$1), (0, vue.createElementVNode)("button", { style: (0, vue.normalizeStyle)(view.value === "settings" ? navActiveIconStyle.value : navIconStyle), title: (0, vue.unref)(t)("settings"), onClick: _cache[3] || (_cache[3] = ($event) => view.value = "settings") }, [(0, vue.createVNode)((0, vue.unref)(Settings), { size: 15 })], 12, _hoisted_2) ]), (0, vue.createElementVNode)("button", { style: closeBtnStyle, onClick: _cache[4] || (_cache[4] = ($event) => _ctx.$emit("close")), title: "Close" }, "×")]), (0, vue.createVNode)((0, vue.unref)(P), { style: bodyStyle, options: { scrollbars: { autoHide: "scroll", autoHideDelay: 400 } } }, { default: (0, vue.withCtx)(() => [view.value === "encode" ? ((0, vue.openBlock)(), (0, vue.createBlock)(OverlayEncodeTab_default, { key: 0, accent: __props.accent }, null, 8, ["accent"])) : view.value === "decode" ? ((0, vue.openBlock)(), (0, vue.createBlock)(OverlayDecodeTab_default, { key: 1, accent: __props.accent }, null, 8, ["accent"])) : view.value === "history" ? ((0, vue.openBlock)(), (0, vue.createBlock)(OverlayHistoryTab_default, { key: 2, accent: __props.accent }, null, 8, ["accent"])) : ((0, vue.openBlock)(), (0, vue.createBlock)(OverlaySettingsTab_default, { key: 3, accent: __props.accent, onSettingsChanged: _cache[5] || (_cache[5] = ($event) => _ctx.$emit("settings-changed", $event)) }, null, 8, ["accent"]))]), _: 1 })], 4); }; } }); //#endregion //#region src/core/utils/url.ts /** URL validation — only allow http/https for navigation safety. */ function isNavigableUrl(text) { try { const url = new URL(text); return url.protocol === "http:" || url.protocol === "https:"; } catch { return false; } } //#endregion //#region src/core/ui/OverlayContextMenu.vue var OverlayContextMenu_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlayContextMenu", props: { visible: { type: Boolean }, x: {}, y: {}, selectedText: {} }, emits: ["close"], setup(__props, { emit: __emit }) { const props = __props; const emit = __emit; const settings = (0, vue.ref)({ ...DEFAULT_SETTINGS }); (0, vue.onMounted)(async () => { settings.value = await getAdapter().loadSettings(); }); (0, vue.watch)(() => props.visible, async (v) => { if (v) { settings.value = await getAdapter().loadSettings(); await (0, vue.nextTick)(); document.addEventListener("click", onOutsideClick, true); document.addEventListener("keydown", onEscape, true); } else { document.removeEventListener("click", onOutsideClick, true); document.removeEventListener("keydown", onEscape, true); } }); (0, vue.onUnmounted)(() => { document.removeEventListener("click", onOutsideClick, true); document.removeEventListener("keydown", onEscape, true); }); function onOutsideClick() { emit("close"); } function onEscape(e) { if (e.key === "Escape") emit("close"); } /** Decoded output + iteration count for current selection */ const decoded = (0, vue.computed)(() => { const text = props.selectedText; if (!text) return null; const s = settings.value; if (s.recursiveDecodeEnabled && s.recursiveDecodeCount > 1) { const r = decodeRecursive(text, s.recursiveDecodeCount, s.recursiveDecodeForceEnabled); return r.ok ? { output: r.output, iterations: r.iterations } : null; } const r = decode(text); return r.ok ? { output: r.text, iterations: 1 } : null; }); const decodedUrl = (0, vue.computed)(() => { const d = decoded.value; return d && isNavigableUrl(d.output) ? d.output : null; }); async function doDecode() { const d = decoded.value; if (d) { await getAdapter().writeClipboard(d.output); await getAdapter().addEntry("decode", props.selectedText, d.output, d.iterations); } emit("close"); } async function openUrl(newTab) { const url = decodedUrl.value; const d = decoded.value; if (!url || !d) return; const action = newTab ? "decode-url-new-tab" : "decode-url-current-tab"; await getAdapter().addEntry(action, props.selectedText, d.output, d.iterations); if (newTab) getAdapter().openTab(url, settings.value.activateNewTab); else window.location.href = url; emit("close"); } const menuPosition = (0, vue.computed)(() => ({ position: "fixed", left: `${props.x}px`, top: `${props.y}px`, zIndex: 2147483647, background: "#fff", border: "1px solid #e0e0e0", borderRadius: "8px", boxShadow: "0 4px 16px rgba(0,0,0,0.14)", padding: "4px 0", minWidth: "200px", fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif", fontSize: "13px" })); const itemStyle = { display: "block", width: "100%", padding: "8px 16px", border: "none", background: "transparent", cursor: "pointer", textAlign: "left", color: "#1a1a1a", fontSize: "13px", whiteSpace: "nowrap" }; const dividerStyle = { height: "1px", background: "#e5e5e5", margin: "4px 0" }; return (_ctx, _cache) => { return __props.visible ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 0, style: (0, vue.normalizeStyle)(menuPosition.value), onClick: _cache[2] || (_cache[2] = (0, vue.withModifiers)(() => {}, ["stop"])) }, [(0, vue.createElementVNode)("button", { style: itemStyle, onClick: doDecode }, (0, vue.toDisplayString)((0, vue.unref)(t)("decodeClipboard")), 1), decodedUrl.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [ (0, vue.createElementVNode)("div", { style: dividerStyle }), (0, vue.createElementVNode)("button", { style: itemStyle, onClick: _cache[0] || (_cache[0] = ($event) => openUrl(true)) }, (0, vue.toDisplayString)((0, vue.unref)(t)("openNewTab")), 1), (0, vue.createElementVNode)("button", { style: itemStyle, onClick: _cache[1] || (_cache[1] = ($event) => openUrl(false)) }, (0, vue.toDisplayString)((0, vue.unref)(t)("openCurrentTab")), 1) ], 64)) : (0, vue.createCommentVNode)("", true)], 4)) : (0, vue.createCommentVNode)("", true); }; } }); //#endregion //#region src/core/ui/OverlayApp.vue?vue&type=script&setup=true&lang.ts var _hoisted_1 = { "data-b64ext": "" }; //#endregion //#region src/core/ui/OverlayApp.vue var OverlayApp_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "OverlayApp", setup(__props) { const panelOpen = (0, vue.ref)(false); const fabHover = (0, vue.ref)(false); const settings = (0, vue.ref)({ ...DEFAULT_SETTINGS }); const ctxMenu = (0, vue.reactive)({ visible: false, x: 0, y: 0, text: "" }); (0, vue.onMounted)(async () => { settings.value = await getAdapter().loadSettings(); setI18nLanguage(settings.value.language); document.addEventListener("contextmenu", onContextMenu, true); }); (0, vue.onUnmounted)(() => { document.removeEventListener("contextmenu", onContextMenu, true); }); (0, vue.watch)(panelOpen, async (v) => { if (v) { settings.value = await getAdapter().loadSettings(); setI18nLanguage(settings.value.language); } }); function togglePanel() { panelOpen.value = !panelOpen.value; } function onSettingsChanged(s) { settings.value = s; setI18nLanguage(s.language); } function onContextMenu(e) { if (!settings.value.contextMenuEnabled) return; const sel = window.getSelection()?.toString().trim(); if (!sel) return; if (!decode(sel).ok) return; e.preventDefault(); ctxMenu.x = e.clientX; ctxMenu.y = e.clientY; ctxMenu.text = sel; ctxMenu.visible = true; } function positionCSS(pos) { const m = "24px"; const base = { position: "fixed", zIndex: 2147483644 }; const map = { "top-left": { top: m, left: m }, "top-center": { top: m, left: "50%", transform: "translateX(-50%)" }, "top-right": { top: m, right: m }, "middle-left": { top: "50%", left: m, transform: "translateY(-50%)" }, "middle-right": { top: "50%", right: m, transform: "translateY(-50%)" }, "bottom-left": { bottom: m, left: m }, "bottom-center": { bottom: m, left: "50%", transform: "translateX(-50%)" }, "bottom-right": { bottom: m, right: m } }; return { ...base, ...map[pos] }; } const fabWrapComputed = (0, vue.computed)(() => positionCSS(settings.value.fabPosition)); const fabBtnComputed = (0, vue.computed)(() => ({ width: "44px", height: "44px", borderRadius: "50%", border: "none", background: settings.value.accentColor, color: "#fff", cursor: "pointer", boxShadow: `0 4px 12px ${settings.value.accentColor}66`, display: "flex", alignItems: "center", justifyContent: "center", transition: "opacity 0.2s", opacity: panelOpen.value || fabHover.value ? "1" : "0.35" })); const backdropStyle = { position: "fixed", inset: "0", zIndex: 2147483645 }; return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1, [ (0, vue.createElementVNode)("div", { style: (0, vue.normalizeStyle)(fabWrapComputed.value), onMouseenter: _cache[0] || (_cache[0] = ($event) => fabHover.value = true), onMouseleave: _cache[1] || (_cache[1] = ($event) => fabHover.value = false) }, [(0, vue.createElementVNode)("button", { style: (0, vue.normalizeStyle)(fabBtnComputed.value), onClick: togglePanel, title: "Base64 Encode / Decode" }, [(0, vue.createVNode)((0, vue.unref)(Code), { size: 20 })], 4)], 36), panelOpen.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(OverlayPanel_default, { key: 0, accent: settings.value.accentColor, position: settings.value.fabPosition, onClose: _cache[2] || (_cache[2] = ($event) => panelOpen.value = false), onSettingsChanged }, null, 8, ["accent", "position"])) : (0, vue.createCommentVNode)("", true), panelOpen.value && settings.value.autoClosePanel ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 1, style: backdropStyle, onClick: _cache[3] || (_cache[3] = ($event) => panelOpen.value = false) })) : (0, vue.createCommentVNode)("", true), settings.value.contextMenuEnabled ? ((0, vue.openBlock)(), (0, vue.createBlock)(OverlayContextMenu_default, { key: 2, visible: ctxMenu.visible, x: ctxMenu.x, y: ctxMenu.y, selectedText: ctxMenu.text, onClose: _cache[4] || (_cache[4] = ($event) => ctxMenu.visible = false) }, null, 8, [ "visible", "x", "y", "selectedText" ])) : (0, vue.createCommentVNode)("", true) ]); }; } }); //#endregion //#region src/core/ui/mount.ts function mountOverlay() { const container = document.createElement("div"); container.setAttribute("data-b64ext", ""); document.body.appendChild(container); (0, vue.createApp)(OverlayApp_default).mount(container); } //#endregion //#region src/entry/userscript.ts /** UserScript entry point — Tampermonkey / Greasemonkey / Violentmonkey. */ setPlatformAdapter(createUserScriptAdapter()); mountOverlay(); //#endregion })(Vue);