accessify-widget 0.3.84 → 0.3.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accessify.min.js +1 -1
- package/dist/accessify.min.js.map +1 -1
- package/dist/accessify.mjs +1 -1
- package/dist/{index-CJB-hRuq.js → index-Cg_HDWEb.js} +30 -68
- package/dist/{index-CJB-hRuq.js.map → index-Cg_HDWEb.js.map} +1 -1
- package/dist/{keyboard-nav-Bxe4jywQ.js → keyboard-nav-CeBNNVpU.js} +2 -2
- package/dist/{keyboard-nav-Bxe4jywQ.js.map → keyboard-nav-CeBNNVpU.js.map} +1 -1
- package/dist/{link-highlight-D9gxFmiG.js → link-highlight-DBGm067Y.js} +3 -3
- package/dist/link-highlight-DBGm067Y.js.map +1 -0
- package/dist/{page-structure-BOFg6Zbt.js → page-structure-DMJpS2ag.js} +6 -9
- package/dist/page-structure-DMJpS2ag.js.map +1 -0
- package/dist/{reading-guide-C_jxzorm.js → reading-guide-VT8NciIL.js} +1 -7
- package/dist/reading-guide-VT8NciIL.js.map +1 -0
- package/dist/{reading-mask-B_NxbhTN.js → reading-mask-BABChuCz.js} +7 -21
- package/dist/reading-mask-BABChuCz.js.map +1 -0
- package/dist/widget.js +1 -1
- package/dist/widget.js.map +1 -1
- package/package.json +1 -1
- package/dist/link-highlight-D9gxFmiG.js.map +0 -1
- package/dist/page-structure-BOFg6Zbt.js.map +0 -1
- package/dist/reading-guide-C_jxzorm.js.map +0 -1
- package/dist/reading-mask-B_NxbhTN.js.map +0 -1
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"link-highlight-D9gxFmiG.js","sources":["../src/features/link-highlight.ts"],"sourcesContent":["import type { FeatureModule, FeatureState } from '../types';\n\nexport default function createLinkHighlightModule(): FeatureModule {\n let enabled = false;\n const STYLE_ID = 'accessify-link-highlight';\n const STORAGE_KEY = 'accessify-link-highlight';\n\n function getStyles(): string {\n return `\n /* accessify link highlighting */\n a[href] {\n text-decoration: underline !important;\n text-decoration-thickness: 3px !important;\n text-underline-offset: 3px !important;\n text-decoration-color: #1a73e8 !important;\n background-color: rgba(26, 115, 232, 0.1) !important;\n padding: 2px 4px !important;\n border-radius: 2px !important;\n transition: background-color 0.15s ease !important;\n }\n\n a[href]:hover, a[href]:active, a[href]:focus {\n background-color: rgba(26, 115, 232, 0.25) !important;\n }\n\n a[href]:visited {\n text-decoration-color: #681da8 !important;\n background-color: rgba(104, 29, 168, 0.1) !important;\n }\n\n a[href]:visited:hover, a[href]:visited:active, a[href]:visited:focus {\n background-color: rgba(104, 29, 168, 0.25) !important;\n }\n\n /* External link indicator */\n a[href^=\"http\"]:not([href*=\"${typeof window !== 'undefined' ? window.location.hostname : ''}\"]):after {\n content: \" \\\\2197\";\n font-size: 0.8em;\n vertical-align: super;\n }\n `;\n }\n\n function injectStyles() {\n let styleEl = document.getElementById(STYLE_ID);\n if (!styleEl) {\n styleEl = document.createElement('style');\n styleEl.id = STYLE_ID;\n document.head.appendChild(styleEl);\n }\n styleEl.textContent = getStyles();\n }\n\n function removeStyles() {\n const styleEl = document.getElementById(STYLE_ID);\n styleEl?.remove();\n }\n\n function activate() {\n enabled = true;\n injectStyles();\n localStorage.setItem(STORAGE_KEY, 'true');\n }\n\n function deactivate() {\n enabled = false;\n removeStyles();\n localStorage.removeItem(STORAGE_KEY);\n }\n\n return {\n id: 'link-highlight',\n name: () => 'Link Highlight',\n description: 'Highlight all links with thick underlines and background colors',\n icon: 'link-highlight',\n category: 'visual',\n activate,\n deactivate,\n getState: (): FeatureState => ({\n id: 'link-highlight',\n enabled,\n }),\n setState: (state: { enabled: boolean }) => {\n if (state.enabled) {\n activate();\n } else {\n deactivate();\n }\n },\n };\n}\n"],"names":[],"mappings":"AAEA,SAAwB,4BAA2C;AACjE,MAAI,UAAU;AACd,QAAM,WAAW;AACjB,QAAM,cAAc;AAEpB,WAAS,YAAoB;AAC3B,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCA2ByB,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/F;AAEA,WAAS,eAAe;AACtB,QAAI,UAAU,SAAS,eAAe,QAAQ;AAC9C,QAAI,CAAC,SAAS;AACZ,gBAAU,SAAS,cAAc,OAAO;AACxC,cAAQ,KAAK;AACb,eAAS,KAAK,YAAY,OAAO;AAAA,IACnC;AACA,YAAQ,cAAc,UAAA;AAAA,EACxB;AAEA,WAAS,eAAe;AACtB,UAAM,UAAU,SAAS,eAAe,QAAQ;AAChD,aAAS,OAAA;AAAA,EACX;AAEA,WAAS,WAAW;AAClB,cAAU;AACV,iBAAA;AACA,iBAAa,QAAQ,aAAa,MAAM;AAAA,EAC1C;AAEA,WAAS,aAAa;AACpB,cAAU;AACV,iBAAA;AACA,iBAAa,WAAW,WAAW;AAAA,EACrC;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM,MAAM;AAAA,IACZ,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,UAAU,OAAqB;AAAA,MAC7B,IAAI;AAAA,MACJ;AAAA,IAAA;AAAA,IAEF,UAAU,CAAC,UAAgC;AACzC,UAAI,MAAM,SAAS;AACjB,iBAAA;AAAA,MACF,OAAO;AACL,mBAAA;AAAA,MACF;AAAA,IACF;AAAA,EAAA;AAEJ;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"page-structure-BOFg6Zbt.js","sources":["../src/features/page-structure.ts"],"sourcesContent":["import type { FeatureModule, FeatureState } from '../types';\nimport { getCurrentWidgetLang, t } from '../i18n/index';\n\nexport default function createPageStructureModule(): FeatureModule {\n let enabled = false;\n let panelEl: HTMLElement | null = null;\n const PANEL_ID = 'accessify-page-structure';\n let mutationObserver: MutationObserver | null = null;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let originalPushState: typeof history.pushState | null = null;\n let originalReplaceState: typeof history.replaceState | null = null;\n const boundPopstateHandler = () => scheduleRefresh();\n let lastContentHash = '';\n\n function lang(): string {\n return getCurrentWidgetLang();\n }\n\n function collectHeadings(): Array<{ tag: string; text: string; el: HTMLElement }> {\n const results: Array<{ tag: string; text: string; el: HTMLElement }> = [];\n const headings = document.querySelectorAll<HTMLElement>('h1, h2, h3, h4, h5, h6');\n headings.forEach((el) => {\n if (el.closest('#accessify-root')) return;\n const text = el.textContent?.trim() || '';\n if (text) results.push({ tag: el.tagName.toLowerCase(), text, el });\n });\n return results;\n }\n\n function collectLandmarks(): Array<{ role: string; label: string; el: HTMLElement }> {\n const results: Array<{ role: string; label: string; el: HTMLElement }> = [];\n const selectors = [\n 'main', 'nav', 'aside', 'header', 'footer', 'section[aria-label]',\n 'section[aria-labelledby]', '[role=\"main\"]', '[role=\"navigation\"]',\n '[role=\"complementary\"]', '[role=\"banner\"]', '[role=\"contentinfo\"]',\n '[role=\"search\"]',\n ];\n const els = document.querySelectorAll<HTMLElement>(selectors.join(','));\n els.forEach((el) => {\n if (el.closest('#accessify-root')) return;\n const role = el.getAttribute('role') || el.tagName.toLowerCase();\n const label = el.getAttribute('aria-label') || el.getAttribute('aria-labelledby') || role;\n results.push({ role, label, el });\n });\n return results;\n }\n\n function buildPanel() {\n panelEl = document.createElement('div');\n panelEl.id = PANEL_ID;\n panelEl.setAttribute('role', 'dialog');\n panelEl.setAttribute('aria-label', t('pageStructure.title', lang()));\n\n const headings = collectHeadings();\n const landmarks = collectLandmarks();\n\n const indent: Record<string, string> = {\n h1: '0', h2: '12px', h3: '24px', h4: '36px', h5: '48px', h6: '60px',\n };\n\n let html = `\n <style>\n #${PANEL_ID} {\n position: fixed; top: 50%; left: 50%;\n transform: translate(-50%, -50%);\n z-index: 999998;\n background: #fff; color: #1a1a1a;\n border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.2);\n padding: 24px; width: 400px; max-height: 80vh;\n overflow-y: auto; font-family: system-ui, sans-serif;\n font-size: 14px; line-height: 1.5;\n }\n #${PANEL_ID} h3 { margin: 0 0 12px; font-size: 16px; }\n #${PANEL_ID} .ps-section { margin-bottom: 16px; }\n #${PANEL_ID} .ps-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: #888; margin-bottom: 6px; }\n #${PANEL_ID} .ps-item {\n display: block; width: 100%; text-align: left;\n padding: 6px 8px; border: none; background: none;\n cursor: pointer; border-radius: 6px; font-size: 13px;\n color: #1a1a1a; font-family: inherit;\n }\n #${PANEL_ID} .ps-item:hover, #${PANEL_ID} .ps-item:active { background: #f0f0f2; }\n #${PANEL_ID} .ps-item:focus-visible { outline: 2px solid #0055CC; outline-offset: 1px; }\n #${PANEL_ID} .ps-tag { color: #888; font-size: 11px; margin-right: 6px; }\n #${PANEL_ID} .ps-close {\n position: absolute; top: 12px; right: 12px;\n background: none; border: none; cursor: pointer;\n font-size: 18px; color: #888; padding: 4px 8px; border-radius: 4px;\n }\n #${PANEL_ID} .ps-close:hover, #${PANEL_ID} .ps-close:active { background: #f0f0f2; }\n @media (prefers-color-scheme: dark) {\n #${PANEL_ID} { background: #1a1a1a; color: #f0f0f0; }\n #${PANEL_ID} .ps-item { color: #f0f0f0; }\n #${PANEL_ID} .ps-item:hover, #${PANEL_ID} .ps-item:active { background: #2a2a2e; }\n #${PANEL_ID} .ps-close { color: #aaa; }\n #${PANEL_ID} .ps-close:hover, #${PANEL_ID} .ps-close:active { background: #2a2a2e; }\n }\n @media (max-width: 640px) {\n #${PANEL_ID} { width: calc(100vw - 32px); max-width: 400px; }\n }\n </style>\n <button class=\"ps-close\" aria-label=\"${t('widget.close', lang())}\">×</button>\n <h3>${t('pageStructure.title', lang())}</h3>\n `;\n\n if (headings.length > 0) {\n html += `<div class=\"ps-section\"><div class=\"ps-label\">${t('pageStructure.headings', lang())}</div>`;\n headings.forEach((h, i) => {\n html += `<button class=\"ps-item\" data-type=\"heading\" data-index=\"${i}\" style=\"padding-left:${indent[h.tag] || '0'}\">\n <span class=\"ps-tag\">${h.tag}</span>${escapeHtml(h.text.slice(0, 80))}\n </button>`;\n });\n html += '</div>';\n }\n\n if (landmarks.length > 0) {\n html += `<div class=\"ps-section\"><div class=\"ps-label\">${t('pageStructure.landmarks', lang())}</div>`;\n landmarks.forEach((lm, i) => {\n html += `<button class=\"ps-item\" data-type=\"landmark\" data-index=\"${i}\">\n <span class=\"ps-tag\">${escapeHtml(lm.role)}</span>${escapeHtml(lm.label.slice(0, 60))}\n </button>`;\n });\n html += '</div>';\n }\n\n if (headings.length === 0 && landmarks.length === 0) {\n html += `<p style=\"color:#888\">${t('pageStructure.empty', lang())}</p>`;\n }\n\n panelEl.innerHTML = html;\n\n // Event delegation\n panelEl.addEventListener('click', (e) => {\n const btn = (e.target as HTMLElement).closest<HTMLElement>('.ps-item');\n if (btn) {\n const type = btn.dataset.type;\n const idx = parseInt(btn.dataset.index || '0', 10);\n let target: HTMLElement | undefined;\n if (type === 'heading') target = headings[idx]?.el;\n else if (type === 'landmark') target = landmarks[idx]?.el;\n if (target) {\n target.scrollIntoView({ behavior: 'smooth', block: 'center' });\n target.focus({ preventScroll: true });\n }\n }\n if ((e.target as HTMLElement).closest('.ps-close')) {\n deactivate();\n }\n });\n\n document.body.appendChild(panelEl);\n const firstBtn = panelEl.querySelector<HTMLElement>('.ps-item, .ps-close');\n firstBtn?.focus();\n }\n\n function escapeHtml(str: string): string {\n return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n }\n\n // --- Content hash for change detection ---\n function contentHash(): string {\n const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');\n let hash = '';\n headings.forEach((el) => { hash += el.textContent?.trim().slice(0, 20) || ''; });\n return hash;\n }\n\n function scheduleRefresh() {\n if (!enabled || !panelEl) return;\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n const newHash = contentHash();\n if (newHash !== lastContentHash) {\n lastContentHash = newHash;\n panelEl?.remove();\n buildPanel();\n }\n }, 300);\n }\n\n // --- SPA navigation detection ---\n function setupSPAListeners() {\n // Override pushState/replaceState to detect SPA navigation\n if (!originalPushState) {\n originalPushState = history.pushState;\n history.pushState = function (...args: Parameters<typeof history.pushState>) {\n originalPushState!.apply(this, args);\n scheduleRefresh();\n };\n }\n if (!originalReplaceState) {\n originalReplaceState = history.replaceState;\n history.replaceState = function (...args: Parameters<typeof history.replaceState>) {\n originalReplaceState!.apply(this, args);\n scheduleRefresh();\n };\n }\n window.addEventListener('popstate', boundPopstateHandler);\n }\n\n function teardownSPAListeners() {\n if (originalPushState) {\n history.pushState = originalPushState;\n originalPushState = null;\n }\n if (originalReplaceState) {\n history.replaceState = originalReplaceState;\n originalReplaceState = null;\n }\n window.removeEventListener('popstate', boundPopstateHandler);\n }\n\n // --- MutationObserver for dynamic content ---\n function setupObserver() {\n if (mutationObserver) return;\n mutationObserver = new MutationObserver(() => scheduleRefresh());\n const target = document.querySelector('main') || document.body;\n mutationObserver.observe(target, { childList: true, subtree: true });\n }\n\n function teardownObserver() {\n mutationObserver?.disconnect();\n mutationObserver = null;\n if (debounceTimer) { clearTimeout(debounceTimer); debounceTimer = null; }\n }\n\n function activate() {\n enabled = true;\n lastContentHash = contentHash();\n buildPanel();\n setupObserver();\n setupSPAListeners();\n }\n\n function deactivate() {\n enabled = false;\n teardownObserver();\n teardownSPAListeners();\n panelEl?.remove();\n panelEl = null;\n }\n\n return {\n id: 'page-structure',\n name: () => 'Page Structure',\n description: 'View headings and landmarks for quick navigation',\n icon: 'page-structure',\n category: 'motor',\n activate,\n deactivate,\n getState: (): FeatureState => ({ id: 'page-structure', enabled }),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reading-guide-C_jxzorm.js","sources":["../src/features/reading-guide.ts"],"sourcesContent":["import type { FeatureModule, FeatureState } from '../types';\n\ninterface ReadingGuideOptions {\n height: number;\n opacity: number;\n}\n\nconst DEFAULT_OPTIONS: ReadingGuideOptions = {\n height: 8,\n opacity: 0.3,\n};\n\nexport default function createReadingGuideModule(): FeatureModule {\n let enabled = false;\n let guideEl: HTMLDivElement | null = null;\n let currentY = 0;\n let options: ReadingGuideOptions = { ...DEFAULT_OPTIONS };\n const STORAGE_KEY = 'accessify-reading-guide';\n const GUIDE_ID = 'accessify-reading-guide';\n\n function handleMouseMove(e: MouseEvent) {\n currentY = e.clientY;\n updateGuidePosition();\n }\n\n function handleTouchMove(e: TouchEvent) {\n if (e.touches.length > 0) {\n currentY = e.touches[0].clientY;\n updateGuidePosition();\n }\n }\n\n function handleKeyDown(e: KeyboardEvent) {\n if (!enabled || !guideEl) return;\n const STEP = 10;\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n currentY = Math.max(0, currentY - STEP);\n updateGuidePosition();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n currentY = Math.min(window.innerHeight, currentY + STEP);\n updateGuidePosition();\n }\n }\n\n function handleResize() {\n // Clamp guide position after viewport change (e.g. device rotation)\n currentY = Math.min(currentY, window.innerHeight);\n updateGuidePosition();\n }\n\n function updateGuidePosition() {\n if (!guideEl) return;\n const halfHeight = options.height / 2;\n guideEl.style.top = `${currentY - halfHeight}px`;\n }\n\n function createGuideElement(): HTMLDivElement {\n const el = document.createElement('div');\n el.id = GUIDE_ID;\n el.setAttribute('role', 'presentation');\n el.setAttribute('aria-hidden', 'true');\n Object.assign(el.style, {\n position: 'fixed',\n left: '0',\n width: '100%',\n height: `${options.height}px`,\n backgroundColor: `rgba(255, 255, 0, ${options.opacity})`,\n pointerEvents: 'none',\n zIndex: '2147483646',\n top: '50%',\n transition: 'top 0.05s linear',\n boxShadow: '0 0 4px rgba(0,0,0,0.2)',\n });\n return el;\n }\n\n function activate() {\n enabled = true;\n const saved = localStorage.getItem(STORAGE_KEY);\n if (saved) {\n try {\n const parsed = JSON.parse(saved);\n options = {\n height: Math.min(60, Math.max(2, parsed.height ?? DEFAULT_OPTIONS.height)),\n opacity: Math.min(1, Math.max(0.1, parsed.opacity ?? DEFAULT_OPTIONS.opacity)),\n };\n } catch {\n options = { ...DEFAULT_OPTIONS };\n }\n }\n\n guideEl = createGuideElement();\n document.documentElement.appendChild(guideEl);\n\n currentY = window.innerHeight / 2;\n updateGuidePosition();\n\n document.addEventListener('mousemove', handleMouseMove, { passive: true });\n document.addEventListener('touchmove', handleTouchMove, { passive: true });\n document.addEventListener('keydown', handleKeyDown);\n window.addEventListener('resize', handleResize, { passive: true });\n }\n\n function deactivate() {\n enabled = false;\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('touchmove', handleTouchMove);\n document.removeEventListener('keydown', handleKeyDown);\n window.removeEventListener('resize', handleResize);\n\n if (guideEl) {\n guideEl.remove();\n guideEl = null;\n }\n localStorage.removeItem(STORAGE_KEY);\n }\n\n return {\n id: 'reading-guide',\n name: () => 'Reading Guide',\n description: 'Horizontal ruler that follows your cursor for easier reading',\n icon: 'reading-guide',\n category: 'cognitive',\n activate,\n deactivate,\n getState: (): FeatureState => ({\n id: 'reading-guide',\n enabled,\n value: { ...options },\n }),\n setState: (newOptions: Partial<ReadingGuideOptions>) => {\n options = {\n height: Math.min(60, Math.max(2, newOptions.height ?? options.height)),\n opacity: Math.min(1, Math.max(0.1, newOptions.opacity ?? options.opacity)),\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(options));\n\n if (guideEl) {\n guideEl.style.height = `${options.height}px`;\n guideEl.style.backgroundColor = `rgba(255, 255, 0, ${options.opacity})`;\n updateGuidePosition();\n }\n },\n };\n}\n"],"names":["DEFAULT_OPTIONS"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reading-mask-B_NxbhTN.js","sources":["../src/features/reading-mask.ts"],"sourcesContent":["import type { FeatureModule, FeatureState } from '../types';\n\nexport default function createReadingMaskModule(): FeatureModule {\n let enabled = false;\n let maskTop: HTMLElement | null = null;\n let maskBottom: HTMLElement | null = null;\n let viewportHeight = 120;\n\n const STORAGE_KEY = 'accessify-reading-mask';\n\n function createOverlays() {\n maskTop = document.createElement('div');\n maskBottom = document.createElement('div');\n\n const baseStyle = `\n position: fixed; left: 0; right: 0; z-index: 999990;\n background: rgba(0, 0, 0, 0.65); pointer-events: none;\n transition: top 80ms ease, bottom 80ms ease, height 80ms ease;\n `;\n maskTop.setAttribute('style', baseStyle + 'top: 0;');\n maskTop.setAttribute('aria-hidden', 'true');\n maskTop.id = 'accessify-mask-top';\n maskBottom.setAttribute('style', baseStyle + 'bottom: 0;');\n maskBottom.setAttribute('aria-hidden', 'true');\n maskBottom.id = 'accessify-mask-bottom';\n\n document.body.appendChild(maskTop);\n document.body.appendChild(maskBottom);\n }\n\n let lastY = 0;\n\n function updateMask(y: number) {\n if (!maskTop || !maskBottom) return;\n lastY = y;\n const half = viewportHeight / 2;\n const topH = Math.max(0, y - half);\n const bottomH = Math.max(0, window.innerHeight - y - half);\n maskTop.style.height = topH + 'px';\n maskBottom.style.height = bottomH + 'px';\n }\n\n function handleMouseMove(e: MouseEvent) {\n updateMask(e.clientY);\n }\n\n function handleTouchMove(e: TouchEvent) {\n if (e.touches.length > 0) {\n updateMask(e.touches[0].clientY);\n }\n }\n\n function handleKeyDown(e: KeyboardEvent) {\n if (!maskTop || !maskBottom) return;\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n const active = document.activeElement as HTMLElement | null;\n if (!active) return;\n const rect = active.getBoundingClientRect();\n updateMask(rect.top + rect.height / 2);\n }\n }\n\n function handleResize() {\n // Clamp mask position after viewport change (e.g. device rotation)\n const clamped = Math.min(lastY, window.innerHeight);\n updateMask(clamped);\n }\n\n function activate() {\n enabled = true;\n createOverlays();\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('touchmove', handleTouchMove, { passive: true });\n document.addEventListener('keydown', handleKeyDown);\n window.addEventListener('resize', handleResize, { passive: true });\n }\n\n function deactivate() {\n enabled = false;\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('touchmove', handleTouchMove);\n document.removeEventListener('keydown', handleKeyDown);\n window.removeEventListener('resize', handleResize);\n maskTop?.remove();\n maskBottom?.remove();\n maskTop = null;\n maskBottom = null;\n }\n\n return {\n id: 'reading-mask',\n name: () => 'Reading Mask',\n description: 'Focus window that dims surrounding content',\n icon: 'reading-mask',\n category: 'motor',\n activate,\n deactivate,\n getState: (): FeatureState => ({ id: 'reading-mask', enabled, value: viewportHeight }),\n setState: (height: number) => {\n viewportHeight = Math.min(400, Math.max(60, height));\n },\n };\n}\n"],"names":[],"mappings":"AAEA,SAAwB,0BAAyC;AAC/D,MAAI,UAAU;AACd,MAAI,UAA8B;AAClC,MAAI,aAAiC;AACrC,MAAI,iBAAiB;AAIrB,WAAS,iBAAiB;AACxB,cAAU,SAAS,cAAc,KAAK;AACtC,iBAAa,SAAS,cAAc,KAAK;AAEzC,UAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAKlB,YAAQ,aAAa,SAAS,YAAY,SAAS;AACnD,YAAQ,aAAa,eAAe,MAAM;AAC1C,YAAQ,KAAK;AACb,eAAW,aAAa,SAAS,YAAY,YAAY;AACzD,eAAW,aAAa,eAAe,MAAM;AAC7C,eAAW,KAAK;AAEhB,aAAS,KAAK,YAAY,OAAO;AACjC,aAAS,KAAK,YAAY,UAAU;AAAA,EACtC;AAEA,MAAI,QAAQ;AAEZ,WAAS,WAAW,GAAW;AAC7B,QAAI,CAAC,WAAW,CAAC,WAAY;AAC7B,YAAQ;AACR,UAAM,OAAO,iBAAiB;AAC9B,UAAM,OAAO,KAAK,IAAI,GAAG,IAAI,IAAI;AACjC,UAAM,UAAU,KAAK,IAAI,GAAG,OAAO,cAAc,IAAI,IAAI;AACzD,YAAQ,MAAM,SAAS,OAAO;AAC9B,eAAW,MAAM,SAAS,UAAU;AAAA,EACtC;AAEA,WAAS,gBAAgB,GAAe;AACtC,eAAW,EAAE,OAAO;AAAA,EACtB;AAEA,WAAS,gBAAgB,GAAe;AACtC,QAAI,EAAE,QAAQ,SAAS,GAAG;AACxB,iBAAW,EAAE,QAAQ,CAAC,EAAE,OAAO;AAAA,IACjC;AAAA,EACF;AAEA,WAAS,cAAc,GAAkB;AACvC,QAAI,CAAC,WAAW,CAAC,WAAY;AAC7B,QAAI,EAAE,QAAQ,aAAa,EAAE,QAAQ,aAAa;AAChD,YAAM,SAAS,SAAS;AACxB,UAAI,CAAC,OAAQ;AACb,YAAM,OAAO,OAAO,sBAAA;AACpB,iBAAW,KAAK,MAAM,KAAK,SAAS,CAAC;AAAA,IACvC;AAAA,EACF;AAEA,WAAS,eAAe;AAEtB,UAAM,UAAU,KAAK,IAAI,OAAO,OAAO,WAAW;AAClD,eAAW,OAAO;AAAA,EACpB;AAEA,WAAS,WAAW;AAClB,cAAU;AACV,mBAAA;AACA,aAAS,iBAAiB,aAAa,eAAe;AACtD,aAAS,iBAAiB,aAAa,iBAAiB,EAAE,SAAS,MAAM;AACzE,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,iBAAiB,UAAU,cAAc,EAAE,SAAS,MAAM;AAAA,EACnE;AAEA,WAAS,aAAa;AACpB,cAAU;AACV,aAAS,oBAAoB,aAAa,eAAe;AACzD,aAAS,oBAAoB,aAAa,eAAe;AACzD,aAAS,oBAAoB,WAAW,aAAa;AACrD,WAAO,oBAAoB,UAAU,YAAY;AACjD,aAAS,OAAA;AACT,gBAAY,OAAA;AACZ,cAAU;AACV,iBAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM,MAAM;AAAA,IACZ,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,UAAU,OAAqB,EAAE,IAAI,gBAAgB,SAAS,OAAO;IACrE,UAAU,CAAC,WAAmB;AAC5B,uBAAiB,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC;AAAA,IACrD;AAAA,EAAA;AAEJ;"}
|