@remcostoeten/use-shortcut 1.3.0 → 2.0.0
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/CHANGELOG.md +8 -0
- package/README.md +33 -313
- package/dist/cli/index.mjs +88 -216
- package/dist/index.d.mts +39 -68
- package/dist/index.d.ts +39 -68
- package/dist/index.js +350 -361
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +351 -354
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
- package/src/__tests__/features.test.ts +43 -12
- package/src/builder.ts +37 -476
- package/src/constants.ts +59 -13
- package/src/formatter.ts +37 -22
- package/src/hook.ts +150 -31
- package/src/index.ts +1 -12
- package/src/parser.ts +6 -3
- package/src/runtime/binding.ts +136 -0
- package/src/runtime/conflicts.ts +43 -0
- package/src/runtime/debug.ts +6 -0
- package/src/runtime/guards.ts +82 -0
- package/src/runtime/keys.ts +63 -0
- package/src/runtime/listener.ts +142 -0
- package/src/runtime/recording.ts +39 -0
- package/src/runtime/types.ts +48 -0
- package/src/types.ts +16 -19
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/parser.ts","../src/formatter.ts","../src/builder.ts","../src/hook.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["export const Platform = {\n MAC: \"mac\",\n WINDOWS: \"windows\",\n LINUX: \"linux\",\n} as const\n\nexport type PlatformType = (typeof Platform)[keyof typeof Platform]\n\nexport function detectPlatform(): PlatformType {\n if (typeof navigator === \"undefined\") return Platform.WINDOWS\n const platform = navigator.platform.toLowerCase()\n if (platform.includes(\"mac\")) return Platform.MAC\n if (platform.includes(\"linux\")) return Platform.LINUX\n return Platform.WINDOWS\n}\n\nexport const ModifierKey = {\n META: \"meta\",\n CTRL: \"ctrl\",\n ALT: \"alt\",\n SHIFT: \"shift\",\n} as const\n\nexport type ModifierKeyType = (typeof ModifierKey)[keyof typeof ModifierKey]\n\nexport const ModifierAliases: Record<string, ModifierKeyType> = {\n command: ModifierKey.META,\n cmd: ModifierKey.META,\n \"⌘\": ModifierKey.META,\n meta: ModifierKey.META,\n win: ModifierKey.META,\n windows: ModifierKey.META,\n super: ModifierKey.META,\n mod: ModifierKey.META,\n control: ModifierKey.CTRL,\n ctrl: ModifierKey.CTRL,\n \"⌃\": ModifierKey.CTRL,\n ctl: ModifierKey.CTRL,\n alt: ModifierKey.ALT,\n option: ModifierKey.ALT,\n opt: ModifierKey.ALT,\n \"⌥\": ModifierKey.ALT,\n shift: ModifierKey.SHIFT,\n \"⇧\": ModifierKey.SHIFT,\n shft: ModifierKey.SHIFT,\n} as const\n\nexport const SpecialKeyMap: Record<string, string> = {\n up: \"ArrowUp\",\n down: \"ArrowDown\",\n left: \"ArrowLeft\",\n right: \"ArrowRight\",\n home: \"Home\",\n end: \"End\",\n pageup: \"PageUp\",\n pagedown: \"PageDown\",\n enter: \"Enter\",\n return: \"Enter\",\n space: \" \",\n spacebar: \" \",\n tab: \"Tab\",\n backspace: \"Backspace\",\n delete: \"Delete\",\n del: \"Delete\",\n escape: \"Escape\",\n esc: \"Escape\",\n f1: \"F1\",\n f2: \"F2\",\n f3: \"F3\",\n f4: \"F4\",\n f5: \"F5\",\n f6: \"F6\",\n f7: \"F7\",\n f8: \"F8\",\n f9: \"F9\",\n f10: \"F10\",\n f11: \"F11\",\n f12: \"F12\",\n plus: \"+\",\n minus: \"-\",\n comma: \",\",\n period: \".\",\n slash: \"/\",\n backslash: \"\\\\\",\n bracket: \"[\",\n closebracket: \"]\",\n} as const\n\nexport const ModifierDisplaySymbols: Record<PlatformType, Record<ModifierKeyType, string>> = {\n [Platform.MAC]: {\n [ModifierKey.META]: \"⌘\",\n [ModifierKey.CTRL]: \"⌃\",\n [ModifierKey.ALT]: \"⌥\",\n [ModifierKey.SHIFT]: \"⇧\",\n },\n [Platform.WINDOWS]: {\n [ModifierKey.META]: \"Ctrl\",\n [ModifierKey.CTRL]: \"Ctrl\",\n [ModifierKey.ALT]: \"Alt\",\n [ModifierKey.SHIFT]: \"Shift\",\n },\n [Platform.LINUX]: {\n [ModifierKey.META]: \"Super\",\n [ModifierKey.CTRL]: \"Ctrl\",\n [ModifierKey.ALT]: \"Alt\",\n [ModifierKey.SHIFT]: \"Shift\",\n },\n} as const\n\nexport const ModifierDisplayOrder: Record<PlatformType, ModifierKeyType[]> = {\n [Platform.MAC]: [ModifierKey.CTRL, ModifierKey.ALT, ModifierKey.SHIFT, ModifierKey.META],\n [Platform.WINDOWS]: [ModifierKey.META, ModifierKey.ALT, ModifierKey.SHIFT, ModifierKey.CTRL],\n [Platform.LINUX]: [ModifierKey.META, ModifierKey.ALT, ModifierKey.SHIFT, ModifierKey.CTRL],\n} as const\n","import { ModifierAliases, SpecialKeyMap, detectPlatform, Platform } from \"./constants\"\nimport type { ModifierState, ParsedShortcut } from \"./types\"\n\n/**\n * Parse a shortcut string into its components\n *\n * @param shortcut - Shortcut string (e.g., \"cmd+s\", \"ctrl+shift+p\")\n * @returns Parsed shortcut with modifiers, key, and original string\n *\n * @example\n * ```ts\n * const parsed = parseShortcut(\"cmd+s\")\n * // { modifiers: { meta: true, ... }, key: \"s\", original: \"cmd+s\" }\n * ```\n */\nexport function parseShortcut(shortcut: string): ParsedShortcut {\n const platform = detectPlatform()\n const normalized = shortcut.toLowerCase().trim()\n const parts = normalized.split(/[\\s+-]+/).filter(Boolean)\n\n if (parts.length === 0) {\n throw new Error(`Invalid shortcut: \"${shortcut}\"`)\n }\n\n const modifiers: ModifierState = {\n meta: false,\n ctrl: false,\n alt: false,\n shift: false,\n }\n\n let key = parts.pop()!\n\n for (const part of parts) {\n const modifierKey = ModifierAliases[part]\n\n if (modifierKey) {\n if (part === \"mod\") {\n if (platform === Platform.MAC) {\n modifiers.meta = true\n } else {\n modifiers.ctrl = true\n }\n } else {\n modifiers[modifierKey] = true\n }\n } else {\n key = part + key\n }\n }\n\n const normalizedKey = SpecialKeyMap[key] || key\n\n return {\n modifiers,\n key: normalizedKey.length === 1 ? normalizedKey.toLowerCase() : normalizedKey,\n original: shortcut,\n }\n}\n\n/**\n * Parse multiple shortcut strings\n *\n * @param shortcuts - Single shortcut or array of shortcuts\n * @returns Array of parsed shortcuts\n */\nexport function parseShortcuts(shortcuts: string | string[]): ParsedShortcut[] {\n const shortcutArray = Array.isArray(shortcuts) ? shortcuts : [shortcuts]\n return shortcutArray.map(parseShortcut)\n}\n\n/**\n * Extract modifier state from a keyboard event\n *\n * @param event - The keyboard event\n * @returns Object with meta, ctrl, alt, shift boolean flags\n */\nexport function getModifiersFromEvent(event: KeyboardEvent): ModifierState {\n return {\n meta: event.metaKey,\n ctrl: event.ctrlKey,\n alt: event.altKey,\n shift: event.shiftKey,\n }\n}\n\n/**\n * Check if a keyboard event matches a parsed shortcut\n *\n * @param event - The keyboard event to check\n * @param parsed - The parsed shortcut to match against\n * @returns `true` if the event matches the shortcut\n */\nexport function matchesShortcut(event: KeyboardEvent, parsed: ParsedShortcut): boolean {\n const eventModifiers = getModifiersFromEvent(event)\n const eventKey = event.key.toLowerCase()\n\n const modifiersMatch =\n eventModifiers.meta === parsed.modifiers.meta &&\n eventModifiers.ctrl === parsed.modifiers.ctrl &&\n eventModifiers.alt === parsed.modifiers.alt &&\n eventModifiers.shift === parsed.modifiers.shift\n\n const keyMatches = eventKey === parsed.key.toLowerCase()\n\n return modifiersMatch && keyMatches\n}\n\n/**\n * Check if a keyboard event matches any of the parsed shortcuts\n *\n * @param event - The keyboard event to check\n * @param parsedShortcuts - Array of parsed shortcuts to match against\n * @returns `true` if the event matches any shortcut\n */\nexport function matchesAnyShortcut(event: KeyboardEvent, parsedShortcuts: ParsedShortcut[]): boolean {\n return parsedShortcuts.some((parsed) => matchesShortcut(event, parsed))\n}\n\n","import {\n ModifierDisplayOrder,\n ModifierDisplaySymbols,\n Platform,\n detectPlatform,\n type ModifierKeyType,\n type PlatformType,\n} from \"./constants\"\nimport { parseShortcut } from \"./parser\"\n\n/**\n * Format a shortcut string for display with platform-aware symbols\n *\n * @param shortcut - Shortcut string (e.g., \"cmd+s\")\n * @param platform - Optional platform override (default: auto-detect)\n * @returns Formatted display string (e.g., \"⌘S\" on Mac, \"Ctrl+S\" on Windows)\n *\n * @example\n * ```ts\n * formatShortcut(\"cmd+s\") // \"⌘S\" on Mac, \"Ctrl+S\" on Windows\n * formatShortcut(\"ctrl+shift+p\", \"mac\") // \"⌃⇧P\"\n * ```\n */\nexport function formatShortcut(shortcut: string, platform?: PlatformType): string {\n const targetPlatform = platform ?? detectPlatform()\n const parsed = parseShortcut(shortcut)\n const symbols = ModifierDisplaySymbols[targetPlatform]\n const order = ModifierDisplayOrder[targetPlatform]\n\n const parts: string[] = []\n\n for (const modifier of order) {\n if (parsed.modifiers[modifier]) {\n parts.push(symbols[modifier])\n }\n }\n\n const displayKey = formatKey(parsed.key, targetPlatform)\n parts.push(displayKey)\n\n const separator = targetPlatform === Platform.MAC ? \"\" : \"+\"\n\n return parts.join(separator)\n}\n\nfunction formatKey(key: string, platform: PlatformType): string {\n const displayNames: Record<string, string> = {\n ArrowUp: \"↑\",\n ArrowDown: \"↓\",\n ArrowLeft: \"←\",\n ArrowRight: \"→\",\n Enter: platform === Platform.MAC ? \"↩\" : \"Enter\",\n Tab: platform === Platform.MAC ? \"⇥\" : \"Tab\",\n Escape: platform === Platform.MAC ? \"⎋\" : \"Esc\",\n Backspace: platform === Platform.MAC ? \"⌫\" : \"Backspace\",\n Delete: platform === Platform.MAC ? \"⌦\" : \"Del\",\n \" \": platform === Platform.MAC ? \"␣\" : \"Space\",\n Home: \"Home\",\n End: \"End\",\n PageUp: \"PgUp\",\n PageDown: \"PgDn\",\n }\n\n return displayNames[key] || key.toUpperCase()\n}\n\n/**\n * Get the modifier key symbols for a platform\n *\n * @param platform - Optional platform override (default: auto-detect)\n * @returns Object mapping modifier keys to display symbols\n *\n * @example\n * ```ts\n * getModifierSymbols(\"mac\") // { meta: \"⌘\", ctrl: \"⌃\", alt: \"⌥\", shift: \"⇧\" }\n * ```\n */\nexport function getModifierSymbols(platform?: PlatformType): Record<ModifierKeyType, string> {\n const targetPlatform = platform ?? detectPlatform()\n return ModifierDisplaySymbols[targetPlatform]\n}\n\n","import {\n detectPlatform,\n Platform,\n ModifierDisplaySymbols,\n ModifierKey,\n ModifierDisplayOrder,\n} from \"./constants\"\nimport { formatShortcut } from \"./formatter\"\nimport { parseShortcut, matchesShortcut } from \"./parser\"\nimport type {\n ActionKey,\n ModifierFlags,\n ShortcutHandler,\n HandlerOptions,\n ShortcutResult,\n UseShortcutOptions,\n ExceptPreset,\n ExceptPredicate,\n ShortcutBuilder as IShortcutBuilder,\n ShortcutScope,\n ShortcutConflict,\n ParsedShortcut,\n ShortcutRecordingOptions,\n} from \"./types\"\n\nconst MODIFIER_KEYS = new Set([\"ctrl\", \"shift\", \"alt\", \"cmd\", \"mod\"])\nconst IGNORED_TAGS = new Set([\"INPUT\", \"TEXTAREA\", \"SELECT\"])\n\nconst EXCEPT_PREDICATES: Record<ExceptPreset, ExceptPredicate> = {\n input: (e) => {\n const target = e.target as HTMLElement\n return IGNORED_TAGS.has(target.tagName)\n },\n editable: (e) => {\n const target = e.target as HTMLElement\n return target.isContentEditable\n },\n typing: (e) => {\n const target = e.target as HTMLElement\n return IGNORED_TAGS.has(target.tagName) || target.isContentEditable\n },\n modal: () => {\n return document.querySelector('[data-modal=\"true\"], [role=\"dialog\"]') !== null\n },\n disabled: (e) => {\n const target = e.target as HTMLElement\n return target.hasAttribute(\"disabled\") || target.getAttribute(\"aria-disabled\") === \"true\"\n },\n}\n\nfunction shouldExcept(event: KeyboardEvent, except?: ExceptPreset | ExceptPreset[] | ExceptPredicate): boolean {\n if (!except) return false\n\n if (typeof except === \"function\") {\n return except(event)\n }\n\n if (Array.isArray(except)) {\n return except.some((preset) => EXCEPT_PREDICATES[preset]?.(event))\n }\n\n return EXCEPT_PREDICATES[except]?.(event) ?? false\n}\n\ntype BuilderState = {\n modifiers: Partial<ModifierFlags>\n steps: string[]\n options: UseShortcutOptions\n except?: ExceptPreset | ExceptPreset[] | ExceptPredicate\n scopes?: ShortcutScope\n}\n\ntype RegistryEntry = {\n id: number\n userHandler: ShortcutHandler\n isEnabled: boolean\n attemptCallbacks: Set<(matched: boolean, event: KeyboardEvent) => void>\n parsedSteps: ParsedShortcut[]\n scopes: Set<string>\n progress: number\n lastMatchedAt: number\n except?: ExceptPreset | ExceptPreset[] | ExceptPredicate\n delay: number\n sequenceTimeout: number\n preventDefault: boolean\n stopPropagation: boolean\n stopOnMatch: boolean\n priority: number\n}\n\ntype ComboListener = {\n listener: (e: KeyboardEvent) => void\n entries: RegistryEntry[]\n unbind: () => void\n}\n\ntype ShortcutRegistry = {\n listeners: Map<string, ComboListener>\n options: UseShortcutOptions\n activeScopes: Set<string>\n nextId: number\n}\n\nfunction normalizeScopes(scopes?: ShortcutScope): string[] {\n if (!scopes) return []\n return (Array.isArray(scopes) ? scopes : [scopes])\n .map((scope) => scope.trim())\n .filter(Boolean)\n}\n\nfunction scopeMatch(requiredScopes: Set<string>, activeScopes: Set<string>): boolean {\n if (requiredScopes.size === 0) return true\n for (const required of requiredScopes) {\n if (activeScopes.has(required)) return true\n }\n return false\n}\n\nfunction getActiveModifierTokens(modifiers: Partial<ModifierFlags>): string[] {\n const platform = detectPlatform()\n const order = ModifierDisplayOrder[platform]\n\n return order\n .filter((key) => {\n if (key === ModifierKey.CTRL) return modifiers.ctrl\n if (key === ModifierKey.ALT) return modifiers.alt\n if (key === ModifierKey.SHIFT) return modifiers.shift\n if (key === ModifierKey.META) return modifiers.cmd\n return false\n })\n .map((key) => {\n if (key === ModifierKey.CTRL) return \"ctrl\"\n if (key === ModifierKey.ALT) return \"alt\"\n if (key === ModifierKey.SHIFT) return \"shift\"\n if (key === ModifierKey.META) return \"cmd\"\n return \"\"\n })\n}\n\nfunction buildComboString(modifiers: Partial<ModifierFlags>, key: string): string {\n const tokens = getActiveModifierTokens(modifiers)\n return [...tokens, key].join(\"+\")\n}\n\nfunction formatSequenceDisplay(steps: string[]): string {\n return steps.map((step) => formatShortcut(step)).join(\" then \")\n}\n\nfunction debugLog(debug: boolean | undefined, ...args: unknown[]) {\n if (debug) {\n console.log(\"[useShortcut]\", ...args)\n }\n}\n\nfunction canonicalizeParsed(parsed: ParsedShortcut): string {\n const modifiers: string[] = []\n if (parsed.modifiers.ctrl) modifiers.push(\"ctrl\")\n if (parsed.modifiers.alt) modifiers.push(\"alt\")\n if (parsed.modifiers.shift) modifiers.push(\"shift\")\n if (parsed.modifiers.meta) modifiers.push(\"cmd\")\n return [...modifiers, parsed.key.toLowerCase()].join(\"+\")\n}\n\nfunction isPureModifier(event: KeyboardEvent): boolean {\n const key = event.key.toLowerCase()\n return key === \"shift\" || key === \"control\" || key === \"alt\" || key === \"meta\"\n}\n\nfunction eventToCombo(event: KeyboardEvent): string {\n const platform = detectPlatform()\n const symbols = ModifierDisplaySymbols[platform]\n\n const modifiers: string[] = []\n if (event.ctrlKey) modifiers.push(symbols[ModifierKey.CTRL] === \"⌃\" ? \"ctrl\" : \"ctrl\")\n if (event.altKey) modifiers.push(\"alt\")\n if (event.shiftKey) modifiers.push(\"shift\")\n if (event.metaKey) modifiers.push(\"cmd\")\n\n const key = event.key.length === 1 ? event.key.toLowerCase() : event.key.toLowerCase()\n return [...modifiers, key].join(\"+\")\n}\n\nfunction isPrefix(a: ParsedShortcut[], b: ParsedShortcut[]): boolean {\n if (a.length > b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (canonicalizeParsed(a[i]) !== canonicalizeParsed(b[i])) {\n return false\n }\n }\n return true\n}\n\nfunction detectConflict(newSteps: ParsedShortcut[], existingSteps: ParsedShortcut[]): ShortcutConflict[\"reason\"] | null {\n const newCombo = newSteps.map(canonicalizeParsed).join(\" \")\n const existingCombo = existingSteps.map(canonicalizeParsed).join(\" \")\n\n if (newCombo === existingCombo) return \"exact\"\n if (isPrefix(newSteps, existingSteps) || isPrefix(existingSteps, newSteps)) {\n return \"sequence-prefix\"\n }\n\n return null\n}\n\nfunction emitConflict(registry: ShortcutRegistry, conflict: ShortcutConflict) {\n const conflictWarnings = registry.options.conflictWarnings ?? true\n\n if (registry.options.onConflict) {\n registry.options.onConflict(conflict)\n return\n }\n\n if (!conflictWarnings) return\n\n console.warn(\n `[useShortcut] Conflict detected (${conflict.reason}) between \"${conflict.combo}\" and \"${conflict.existingCombo}\"`,\n )\n}\n\nfunction sortEntries(entries: RegistryEntry[]): RegistryEntry[] {\n return [...entries].sort((a, b) => {\n if (b.priority !== a.priority) return b.priority - a.priority\n return a.id - b.id\n })\n}\n\nfunction createBinding(\n state: BuilderState,\n handler: ShortcutHandler,\n handlerOptions: HandlerOptions = {},\n registry: ShortcutRegistry,\n): ShortcutResult {\n const { options, except: stateExcept } = state\n\n const rawSteps = state.steps\n\n if (rawSteps.length === 0) {\n throw new Error('[useShortcut] No key specified. Use .key() to set the action key.')\n }\n\n const parsedSteps = rawSteps.map((step) => parseShortcut(step))\n const combo = parsedSteps.map(canonicalizeParsed).join(\" \")\n const display = formatSequenceDisplay(rawSteps)\n const debug = options.debug ?? false\n const except = stateExcept ?? handlerOptions.except\n\n for (const [existingCombo, listener] of registry.listeners.entries()) {\n for (const existing of listener.entries) {\n if (existingCombo === combo) continue\n const reason = detectConflict(parsedSteps, existing.parsedSteps)\n if (!reason) continue\n emitConflict(registry, { combo, existingCombo, reason })\n }\n }\n\n const isEnabled = !handlerOptions.disabled && !options.disabled\n const delay = handlerOptions.delay ?? options.delay ?? 0\n const sequenceTimeout = handlerOptions.sequenceTimeout ?? options.sequenceTimeout ?? 800\n const requiredScopes = new Set(normalizeScopes(state.scopes ?? handlerOptions.scopes))\n const attemptCallbacks = new Set<(matched: boolean, event: KeyboardEvent) => void>()\n\n debugLog(debug, \"Registering:\", combo, \"→\", display, {\n parsedSteps,\n except: !!except,\n scopes: [...requiredScopes],\n })\n\n const entry: RegistryEntry = {\n id: registry.nextId++,\n userHandler: handler,\n isEnabled,\n attemptCallbacks,\n parsedSteps,\n scopes: requiredScopes,\n progress: 0,\n lastMatchedAt: 0,\n except,\n delay,\n sequenceTimeout,\n preventDefault: handlerOptions.preventDefault !== false,\n stopPropagation: handlerOptions.stopPropagation ?? false,\n stopOnMatch: handlerOptions.stopOnMatch ?? false,\n priority: handlerOptions.priority ?? 0,\n }\n\n let comboListener = registry.listeners.get(combo)\n\n if (!comboListener) {\n const target = options.target ?? (typeof window !== \"undefined\" ? window : null)\n const eventType = options.eventType ?? \"keydown\"\n\n const listener = (event: KeyboardEvent) => {\n const runtimeOptions = registry.options\n if (runtimeOptions.disabled) return\n if (runtimeOptions.eventFilter && !runtimeOptions.eventFilter(event)) return\n\n const current = registry.listeners.get(combo)\n if (!current) return\n\n const orderedEntries = sortEntries(current.entries)\n\n for (const item of orderedEntries) {\n if (!item.isEnabled) continue\n\n if (!scopeMatch(item.scopes, registry.activeScopes)) {\n continue\n }\n\n if (runtimeOptions.ignoreInputs !== false && !item.except) {\n const targetEl = event.target as HTMLElement\n if (targetEl && (IGNORED_TAGS.has(targetEl.tagName) || targetEl.isContentEditable)) {\n continue\n }\n }\n\n if (shouldExcept(event, item.except)) {\n debugLog(debug, \"Skipped due to except condition:\", combo)\n continue\n }\n\n const expected = item.parsedSteps[item.progress]\n const now = Date.now()\n\n if (item.progress > 0 && now - item.lastMatchedAt > item.sequenceTimeout) {\n item.progress = 0\n }\n\n let matched = false\n\n if (matchesShortcut(event, expected)) {\n item.progress += 1\n item.lastMatchedAt = now\n\n if (item.progress === item.parsedSteps.length) {\n matched = true\n item.progress = 0\n }\n } else if (item.progress > 0 && matchesShortcut(event, item.parsedSteps[0])) {\n item.progress = 1\n item.lastMatchedAt = now\n } else {\n item.progress = 0\n }\n\n item.attemptCallbacks.forEach((cb) => cb(matched, event))\n\n if (!matched) continue\n\n debugLog(debug, \"MATCHED:\", combo, \"→\", display)\n\n if (item.preventDefault) {\n event.preventDefault()\n }\n\n if (item.stopPropagation) {\n event.stopPropagation()\n }\n\n const executeHandler = () => item.userHandler(event)\n\n if (item.delay > 0) {\n debugLog(debug, \"Delaying execution by\", item.delay, \"ms\")\n setTimeout(executeHandler, item.delay)\n } else {\n executeHandler()\n }\n\n if (item.stopOnMatch) {\n break\n }\n }\n }\n\n if (target) {\n target.addEventListener(eventType, listener as EventListener)\n debugLog(debug, \"Listener attached for:\", combo)\n }\n\n const unbind = () => {\n if (target) {\n target.removeEventListener(eventType, listener as EventListener)\n registry.listeners.delete(combo)\n debugLog(debug, \"Unregistered:\", combo)\n }\n }\n\n comboListener = {\n listener,\n entries: [],\n unbind,\n }\n\n registry.listeners.set(combo, comboListener)\n }\n\n comboListener.entries.push(entry)\n\n const unbindEntry = () => {\n const current = registry.listeners.get(combo)\n if (!current) return\n\n current.entries = current.entries.filter((item) => item.id !== entry.id)\n\n if (current.entries.length === 0) {\n current.unbind()\n }\n }\n\n return {\n unbind: unbindEntry,\n display,\n combo,\n trigger: () => handler(new KeyboardEvent(registry.options.eventType ?? \"keydown\")),\n get isEnabled() {\n return entry.isEnabled\n },\n enable: () => {\n entry.isEnabled = true\n },\n disable: () => {\n entry.isEnabled = false\n },\n onAttempt: (callback) => {\n entry.attemptCallbacks.add(callback)\n return () => entry.attemptCallbacks.delete(callback)\n },\n }\n}\n\nfunction createRecorder(options: UseShortcutOptions) {\n return (recordingOptions: ShortcutRecordingOptions = {}): Promise<string> => {\n return new Promise((resolve, reject) => {\n const target = recordingOptions.target ?? options.target ?? (typeof window !== \"undefined\" ? window : null)\n const eventType = recordingOptions.eventType ?? options.eventType ?? \"keydown\"\n\n if (!target) {\n reject(new Error(\"[useShortcut] Cannot record shortcut without a target.\"))\n return\n }\n\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n const listener = (event: Event) => {\n const keyboardEvent = event as KeyboardEvent\n if (isPureModifier(keyboardEvent)) return\n\n keyboardEvent.preventDefault()\n target.removeEventListener(eventType, listener as EventListener)\n if (timeout) clearTimeout(timeout)\n resolve(eventToCombo(keyboardEvent))\n }\n\n target.addEventListener(eventType, listener as EventListener, { once: false })\n\n const timeoutMs = recordingOptions.timeoutMs\n if (timeoutMs && timeoutMs > 0) {\n timeout = setTimeout(() => {\n target.removeEventListener(eventType, listener as EventListener)\n reject(new Error(`[useShortcut] Recording timed out after ${timeoutMs}ms.`))\n }, timeoutMs)\n }\n })\n }\n}\n\nexport function createShortcutBuilder(options: UseShortcutOptions = {}): {\n builder: IShortcutBuilder\n registry: ShortcutRegistry\n} {\n const registry: ShortcutRegistry = {\n listeners: new Map(),\n options,\n activeScopes: new Set(normalizeScopes(options.activeScopes)),\n nextId: 1,\n }\n\n debugLog(options.debug, \"Builder created with options:\", options)\n\n function createProxy(currentState: BuilderState): IShortcutBuilder {\n return new Proxy({} as IShortcutBuilder, {\n get(_, prop: string) {\n if (prop === \"__debug\") {\n return currentState.options.debug\n }\n\n if (MODIFIER_KEYS.has(prop)) {\n const platform = detectPlatform()\n const modKey = prop === \"mod\" ? (platform === Platform.MAC ? \"cmd\" : \"ctrl\") : prop\n\n const newState: BuilderState = {\n ...currentState,\n modifiers: { ...currentState.modifiers, [modKey]: true },\n }\n\n debugLog(currentState.options.debug, `Chain: +${prop} →`, newState.modifiers)\n\n return createProxy(newState)\n }\n\n if (prop === \"in\") {\n return (scopes: ShortcutScope) => {\n const nextScopes = [...normalizeScopes(currentState.scopes), ...normalizeScopes(scopes)]\n const newState: BuilderState = {\n ...currentState,\n scopes: nextScopes,\n }\n\n return createProxy(newState)\n }\n }\n\n if (prop === \"setScopes\") {\n return (scopes: ShortcutScope) => {\n registry.activeScopes = new Set(normalizeScopes(scopes))\n }\n }\n\n if (prop === \"enableScope\") {\n return (scope: string) => {\n if (!scope?.trim()) return\n registry.activeScopes.add(scope.trim())\n }\n }\n\n if (prop === \"disableScope\") {\n return (scope: string) => {\n if (!scope?.trim()) return\n registry.activeScopes.delete(scope.trim())\n }\n }\n\n if (prop === \"getScopes\") {\n return () => [...registry.activeScopes]\n }\n\n if (prop === \"isScopeActive\") {\n return (scope: string) => registry.activeScopes.has(scope)\n }\n\n if (prop === \"record\") {\n return createRecorder(registry.options)\n }\n\n if (prop === \"key\") {\n return (key: ActionKey) => {\n const nextStep = buildComboString(currentState.modifiers, key)\n const newState: BuilderState = {\n ...currentState,\n modifiers: {},\n steps: [...currentState.steps, nextStep],\n }\n\n debugLog(currentState.options.debug, `Chain: .key(\"${key}\")`)\n\n return createProxy(newState)\n }\n }\n\n if (prop === \"then\") {\n return (key: ActionKey | string) => {\n const nextStep = String(key).trim().toLowerCase()\n if (!nextStep) {\n throw new Error(\"[useShortcut] .then() requires a non-empty key or shortcut step.\")\n }\n\n const newState: BuilderState = {\n ...currentState,\n steps: [...currentState.steps, nextStep],\n }\n\n debugLog(currentState.options.debug, `Chain: .then(\"${nextStep}\")`)\n\n return createProxy(newState)\n }\n }\n\n if (prop === \"except\") {\n return (condition: ExceptPreset | ExceptPreset[] | ExceptPredicate) => {\n const newState: BuilderState = {\n ...currentState,\n except: condition,\n }\n\n debugLog(currentState.options.debug, \"Chain: .except()\", condition)\n\n return createProxy(newState)\n }\n }\n\n if (prop === \"on\") {\n return (handler: ShortcutHandler, handlerOptions?: HandlerOptions) => {\n return createBinding(currentState, handler, handlerOptions, registry)\n }\n }\n\n if (prop === \"handle\") {\n return (opts: HandlerOptions & { handler: ShortcutHandler }) => {\n const { handler, ...rest } = opts\n return createBinding(currentState, handler, rest, registry)\n }\n }\n\n return undefined\n },\n })\n }\n\n const initialState: BuilderState = {\n modifiers: {},\n steps: [],\n options,\n }\n\n return {\n builder: createProxy(initialState),\n registry,\n }\n}\n","\"use client\"\n\nimport { useEffect, useRef, useMemo } from \"react\"\nimport { createShortcutBuilder } from \"./builder\"\nimport type {\n ShortcutBuilder,\n UseShortcutOptions,\n ShortcutMap,\n ShortcutMapResult,\n ShortcutMapEntry,\n ShortcutGroup,\n ShortcutResult,\n} from \"./types\"\n\nfunction normalizeShortcutMapKeys(keys: ShortcutMapEntry[\"keys\"]): string[] {\n if (Array.isArray(keys)) {\n return keys.map((key) => key.trim()).filter(Boolean)\n }\n\n const trimmed = keys.trim()\n if (!trimmed) return []\n\n if (trimmed.includes(\" then \")) {\n return trimmed.split(/\\s+then\\s+/i).map((key) => key.trim()).filter(Boolean)\n }\n\n if (trimmed.includes(\" \") && !trimmed.includes(\"+\")) {\n return trimmed.split(/\\s+/).map((key) => key.trim()).filter(Boolean)\n }\n\n return [trimmed]\n}\n\nfunction applyStep(builder: any, step: string): any {\n const tokens = step\n .toLowerCase()\n .split(\"+\")\n .map((token) => token.trim())\n .filter(Boolean)\n\n if (tokens.length === 0) {\n throw new Error(\"[useShortcutMap] Invalid step: empty shortcut step\")\n }\n\n const key = tokens.pop()!\n let chain = builder\n\n for (const token of tokens) {\n if (token === \"ctrl\" || token === \"control\") {\n chain = chain.ctrl\n continue\n }\n\n if (token === \"shift\") {\n chain = chain.shift\n continue\n }\n\n if (token === \"alt\" || token === \"option\") {\n chain = chain.alt\n continue\n }\n\n if (token === \"cmd\" || token === \"command\" || token === \"meta\") {\n chain = chain.cmd\n continue\n }\n\n if (token === \"mod\") {\n chain = chain.mod\n continue\n }\n\n throw new Error(`[useShortcutMap] Unsupported modifier token \"${token}\" in step \"${step}\"`)\n }\n\n return chain.key(key)\n}\n\nexport function registerShortcutMap<T extends ShortcutMap>(\n builder: ShortcutBuilder,\n shortcutMap: T,\n): ShortcutMapResult<T> {\n const results = {} as ShortcutMapResult<T>\n\n for (const id of Object.keys(shortcutMap) as Array<keyof T>) {\n const entry = shortcutMap[id]\n const steps = normalizeShortcutMapKeys(entry.keys)\n\n if (steps.length === 0) {\n throw new Error(`[useShortcutMap] Shortcut \"${String(id)}\" has no key steps`)\n }\n\n let chain = applyStep(builder, steps[0])\n\n for (const step of steps.slice(1)) {\n chain = chain.then(step)\n }\n\n results[id] = chain.on(entry.handler, entry.options)\n }\n\n return results\n}\n\n/**\n * React hook for registering chainable keyboard shortcuts\n *\n * @param options - Configuration options for the hook\n * @returns A chainable shortcut builder (`$`)\n */\nexport function useShortcut(options: UseShortcutOptions = {}): ShortcutBuilder {\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n const { builder, registry } = useMemo(() => {\n return createShortcutBuilder(optionsRef.current)\n }, [])\n\n useEffect(() => {\n registry.options = optionsRef.current\n\n if (optionsRef.current.activeScopes !== undefined) {\n const scopes = Array.isArray(optionsRef.current.activeScopes)\n ? optionsRef.current.activeScopes\n : [optionsRef.current.activeScopes]\n\n registry.activeScopes = new Set(scopes.map((scope) => scope.trim()).filter(Boolean))\n }\n })\n\n useEffect(() => {\n return () => {\n registry.listeners.forEach((entry) => entry.unbind())\n registry.listeners.clear()\n }\n }, [registry])\n\n return builder as ShortcutBuilder\n}\n\n/**\n * Bulk registration helper for shortcut maps.\n */\nexport function useShortcutMap<T extends ShortcutMap>(\n shortcutMap: T,\n options: UseShortcutOptions = {},\n): ShortcutMapResult<T> {\n const $ = useShortcut(options)\n return registerShortcutMap($, shortcutMap)\n}\n\n/**\n * Create a shortcut builder for non-React usage\n *\n * Unlike `useShortcut`, this does not auto-cleanup - you must call `.unbind()` manually.\n *\n * @param options - Configuration options\n * @returns A chainable shortcut builder\n */\nexport function createShortcut(options: UseShortcutOptions = {}): ShortcutBuilder {\n const { builder } = createShortcutBuilder(options)\n return builder as ShortcutBuilder\n}\n\n/**\n * Bulk registration helper for non-React usage.\n */\nexport function createShortcutMap<T extends ShortcutMap>(\n shortcutMap: T,\n options: UseShortcutOptions = {},\n): ShortcutMapResult<T> {\n const builder = createShortcut(options)\n return registerShortcutMap(builder, shortcutMap)\n}\n\nexport function createShortcutGroup(): ShortcutGroup {\n const results: ShortcutResult[] = []\n\n return {\n add: (...entries: ShortcutResult[]) => {\n results.push(...entries)\n },\n addMany: (entries: ShortcutResult[] | Record<string, ShortcutResult>) => {\n if (Array.isArray(entries)) {\n results.push(...entries)\n return\n }\n\n results.push(...Object.values(entries))\n },\n unbindAll: () => {\n for (const entry of results) {\n entry.unbind()\n }\n results.length = 0\n },\n clear: () => {\n results.length = 0\n },\n getResults: () => [...results],\n }\n}\n\nexport function useShortcutGroup(): ShortcutGroup {\n const groupRef = useRef<ShortcutGroup | null>(null)\n\n if (!groupRef.current) {\n groupRef.current = createShortcutGroup()\n }\n\n return groupRef.current\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/parser.ts","../src/formatter.ts","../src/runtime/debug.ts","../src/runtime/keys.ts","../src/runtime/conflicts.ts","../src/runtime/guards.ts","../src/runtime/listener.ts","../src/runtime/binding.ts","../src/runtime/recording.ts","../src/builder.ts","../src/hook.ts"],"names":[],"mappings":";;;AACO,IAAM,EAAA,GAAK;AAAA,EACd,GAAA,EAAK,KAAA;AAAA,EACL,OAAA,EAAS,SAAA;AAAA,EACT,KAAA,EAAO;AACX,CAAA;AAKO,IAAM,QAAA,GAAW;AAExB,IAAI,eAAA,GAAuC,IAAA;AAMpC,SAAS,cAAA,GAA+B;AAC3C,EAAA,IAAI,iBAAiB,OAAO,eAAA;AAC5B,EAAA,IAAI,OAAO,cAAc,WAAA,EAAa;AAClC,IAAA,eAAA,GAAkB,EAAA,CAAG,OAAA;AACrB,IAAA,OAAO,eAAA;AAAA,EACX;AAEA,EAAA,MAAM,UAAA,GACF,SAAA,CAGF,aAAA,EAAe,QAAA,EAAU,WAAA,EAAY;AAEvC,EAAA,MAAM,YAAY,UAAA,IAAc,SAAA,CAAU,YAAY,SAAA,CAAU,SAAA,IAAa,IAAI,WAAA,EAAY;AAE7F,EAAA,IACI,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,IACpB,SAAS,QAAA,CAAS,QAAQ,CAAA,IAC1B,QAAA,CAAS,SAAS,MAAM,CAAA,IACxB,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAC7B;AACE,IAAA,eAAA,GAAkB,EAAA,CAAG,GAAA;AACrB,IAAA,OAAO,eAAA;AAAA,EACX;AAEA,EAAA,IAAI,SAAS,QAAA,CAAS,OAAO,KAAK,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AAC5D,IAAA,eAAA,GAAkB,EAAA,CAAG,KAAA;AACrB,IAAA,OAAO,eAAA;AAAA,EACX;AAEA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG;AAC1B,IAAA,eAAA,GAAkB,EAAA,CAAG,OAAA;AACrB,IAAA,OAAO,eAAA;AAAA,EACX;AAEA,EAAA,eAAA,GAAkB,EAAA,CAAG,OAAA;AACrB,EAAA,OAAO,eAAA;AACX;AAGO,IAAM,WAAA,GAAc;AAAA,EACvB,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,KAAA,EAAO;AACX;AAKO,IAAM,eAAA,GAAmD;AAAA,EAC5D,SAAS,WAAA,CAAY,IAAA;AAAA,EACrB,KAAK,WAAA,CAAY,IAAA;AAAA,EACjB,UAAK,WAAA,CAAY,IAAA;AAAA,EACjB,MAAM,WAAA,CAAY,IAAA;AAAA,EAClB,KAAK,WAAA,CAAY,IAAA;AAAA,EACjB,SAAS,WAAA,CAAY,IAAA;AAAA,EACrB,OAAO,WAAA,CAAY,IAAA;AAAA,EACnB,KAAK,WAAA,CAAY,IAAA;AAAA,EACjB,SAAS,WAAA,CAAY,IAAA;AAAA,EACrB,MAAM,WAAA,CAAY,IAAA;AAAA,EAClB,UAAK,WAAA,CAAY,IAAA;AAAA,EACjB,KAAK,WAAA,CAAY,IAAA;AAAA,EACjB,KAAK,WAAA,CAAY,GAAA;AAAA,EACjB,QAAQ,WAAA,CAAY,GAAA;AAAA,EACpB,KAAK,WAAA,CAAY,GAAA;AAAA,EACjB,UAAK,WAAA,CAAY,GAAA;AAAA,EACjB,OAAO,WAAA,CAAY,KAAA;AAAA,EACnB,UAAK,WAAA,CAAY,KAAA;AAAA,EACjB,MAAM,WAAA,CAAY;AACtB;AAGO,IAAM,aAAA,GAAwC;AAAA,EACjD,EAAA,EAAI,SAAA;AAAA,EACJ,IAAA,EAAM,WAAA;AAAA,EACN,IAAA,EAAM,WAAA;AAAA,EACN,KAAA,EAAO,YAAA;AAAA,EACP,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,QAAA;AAAA,EACR,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO,OAAA;AAAA,EACP,MAAA,EAAQ,OAAA;AAAA,EACR,KAAA,EAAO,GAAA;AAAA,EACP,QAAA,EAAU,GAAA;AAAA,EACV,GAAA,EAAK,KAAA;AAAA,EACL,SAAA,EAAW,WAAA;AAAA,EACX,MAAA,EAAQ,QAAA;AAAA,EACR,GAAA,EAAK,QAAA;AAAA,EACL,MAAA,EAAQ,QAAA;AAAA,EACR,GAAA,EAAK,QAAA;AAAA,EACL,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,IAAA,EAAM,GAAA;AAAA,EACN,KAAA,EAAO,GAAA;AAAA,EACP,KAAA,EAAO,GAAA;AAAA,EACP,MAAA,EAAQ,GAAA;AAAA,EACR,KAAA,EAAO,GAAA;AAAA,EACP,SAAA,EAAW,IAAA;AAAA,EACX,OAAA,EAAS,GAAA;AAAA,EACT,YAAA,EAAc;AAClB;AAGO,IAAM,sBAAA,GAAgF;AAAA,EACzF,CAAC,EAAA,CAAG,GAAG,GAAG;AAAA,IACN,CAAC,WAAA,CAAY,IAAI,GAAG,QAAA;AAAA,IACpB,CAAC,WAAA,CAAY,IAAI,GAAG,QAAA;AAAA,IACpB,CAAC,WAAA,CAAY,GAAG,GAAG,QAAA;AAAA,IACnB,CAAC,WAAA,CAAY,KAAK,GAAG;AAAA,GACzB;AAAA,EACA,CAAC,EAAA,CAAG,OAAO,GAAG;AAAA,IACV,CAAC,WAAA,CAAY,IAAI,GAAG,MAAA;AAAA,IACpB,CAAC,WAAA,CAAY,IAAI,GAAG,MAAA;AAAA,IACpB,CAAC,WAAA,CAAY,GAAG,GAAG,KAAA;AAAA,IACnB,CAAC,WAAA,CAAY,KAAK,GAAG;AAAA,GACzB;AAAA,EACA,CAAC,EAAA,CAAG,KAAK,GAAG;AAAA,IACR,CAAC,WAAA,CAAY,IAAI,GAAG,OAAA;AAAA,IACpB,CAAC,WAAA,CAAY,IAAI,GAAG,MAAA;AAAA,IACpB,CAAC,WAAA,CAAY,GAAG,GAAG,KAAA;AAAA,IACnB,CAAC,WAAA,CAAY,KAAK,GAAG;AAAA;AAE7B;AAGO,IAAM,oBAAA,GAAgE;AAAA,EACzE,CAAC,EAAA,CAAG,GAAG,GAAG,CAAC,WAAA,CAAY,IAAA,EAAM,WAAA,CAAY,GAAA,EAAK,WAAA,CAAY,KAAA,EAAO,WAAA,CAAY,IAAI,CAAA;AAAA,EACjF,CAAC,EAAA,CAAG,OAAO,GAAG,CAAC,WAAA,CAAY,IAAA,EAAM,WAAA,CAAY,GAAA,EAAK,WAAA,CAAY,KAAA,EAAO,WAAA,CAAY,IAAI,CAAA;AAAA,EACrF,CAAC,EAAA,CAAG,KAAK,GAAG,CAAC,WAAA,CAAY,IAAA,EAAM,WAAA,CAAY,GAAA,EAAK,WAAA,CAAY,KAAA,EAAO,WAAA,CAAY,IAAI;AACvF;;;AC5JA,SAAS,mBAAmB,GAAA,EAAqB;AAC7C,EAAA,OAAO,GAAA,KAAQ,GAAA,GAAM,OAAA,GAAU,GAAA,CAAI,WAAA,EAAY;AACnD;AAcO,SAAS,cAAc,QAAA,EAAkC;AAC5D,EAAA,MAAM,WAAW,cAAA,EAAe;AAChC,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,WAAA,EAAY,CAAE,IAAA,EAAK;AAC/C,EAAA,MAAM,QAAQ,UAAA,CAAW,KAAA,CAAM,SAAS,CAAA,CAAE,OAAO,OAAO,CAAA;AAExD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACpB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EACrD;AAEA,EAAA,MAAM,SAAA,GAA2B;AAAA,IAC7B,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAM,KAAA;AAAA,IACN,GAAA,EAAK,KAAA;AAAA,IACL,KAAA,EAAO;AAAA,GACX;AAEA,EAAA,IAAI,GAAA,GAAM,MAAM,GAAA,EAAI;AAEpB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACtB,IAAA,MAAM,WAAA,GAAc,gBAAgB,IAAI,CAAA;AAExC,IAAA,IAAI,WAAA,EAAa;AACb,MAAA,IAAI,SAAS,KAAA,EAAO;AAChB,QAAA,IAAI,QAAA,KAAa,SAAS,GAAA,EAAK;AAC3B,UAAA,SAAA,CAAU,IAAA,GAAO,IAAA;AAAA,QACrB,CAAA,MAAO;AACH,UAAA,SAAA,CAAU,IAAA,GAAO,IAAA;AAAA,QACrB;AAAA,MACJ,CAAA,MAAO;AACH,QAAA,SAAA,CAAU,WAAW,CAAA,GAAI,IAAA;AAAA,MAC7B;AAAA,IACJ,CAAA,MAAO;AACH,MAAA,GAAA,GAAM,IAAA,GAAO,GAAA;AAAA,IACjB;AAAA,EACJ;AAEA,EAAA,MAAM,aAAA,GAAgB,aAAA,CAAc,GAAG,CAAA,IAAK,GAAA;AAE5C,EAAA,OAAO;AAAA,IACH,SAAA;AAAA,IACA,KAAK,aAAA,CAAc,MAAA,KAAW,CAAA,GAAI,aAAA,CAAc,aAAY,GAAI,aAAA;AAAA,IAChE,QAAA,EAAU;AAAA,GACd;AACJ;AAQO,SAAS,eAAe,SAAA,EAAgD;AAC3E,EAAA,MAAM,gBAAgB,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,GAAI,SAAA,GAAY,CAAC,SAAS,CAAA;AACvE,EAAA,OAAO,aAAA,CAAc,IAAI,aAAa,CAAA;AAC1C;AAQO,SAAS,sBAAsB,KAAA,EAAqC;AACvE,EAAA,OAAO;AAAA,IACH,MAAM,KAAA,CAAM,OAAA;AAAA,IACZ,MAAM,KAAA,CAAM,OAAA;AAAA,IACZ,KAAK,KAAA,CAAM,MAAA;AAAA,IACX,OAAO,KAAA,CAAM;AAAA,GACjB;AACJ;AASO,SAAS,eAAA,CAAgB,OAAsB,MAAA,EAAiC;AACnF,EAAA,MAAM,cAAA,GAAiB,sBAAsB,KAAK,CAAA;AAClD,EAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,KAAA,CAAM,GAAG,CAAA;AAE7C,EAAA,MAAM,iBACF,cAAA,CAAe,IAAA,KAAS,OAAO,SAAA,CAAU,IAAA,IACzC,eAAe,IAAA,KAAS,MAAA,CAAO,UAAU,IAAA,IACzC,cAAA,CAAe,QAAQ,MAAA,CAAO,SAAA,CAAU,OACxC,cAAA,CAAe,KAAA,KAAU,OAAO,SAAA,CAAU,KAAA;AAE9C,EAAA,MAAM,UAAA,GAAa,QAAA,KAAa,kBAAA,CAAmB,MAAA,CAAO,GAAG,CAAA;AAE7D,EAAA,OAAO,cAAA,IAAkB,UAAA;AAC7B;AASO,SAAS,kBAAA,CAAmB,OAAsB,eAAA,EAA4C;AACjG,EAAA,OAAO,gBAAgB,IAAA,CAAK,CAAC,WAAW,eAAA,CAAgB,KAAA,EAAO,MAAM,CAAC,CAAA;AAC1E;;;AC/GA,IAAM,mBAAA,GAA8C;AAAA,EAChD,OAAA,EAAS,QAAA;AAAA,EACT,SAAA,EAAW,QAAA;AAAA,EACX,SAAA,EAAW,QAAA;AAAA,EACX,UAAA,EAAY,QAAA;AAAA,EACZ,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,MAAA;AAAA,EACR,QAAA,EAAU;AACd,CAAA;AAEA,IAAM,kBAAA,GAA6C;AAAA,EAC/C,GAAG,mBAAA;AAAA,EACH,KAAA,EAAO,QAAA;AAAA,EACP,GAAA,EAAK,QAAA;AAAA,EACL,MAAA,EAAQ,QAAA;AAAA,EACR,SAAA,EAAW,QAAA;AAAA,EACX,MAAA,EAAQ,QAAA;AAAA,EACR,GAAA,EAAK;AACT,CAAA;AAEA,IAAM,sBAAA,GAAiD;AAAA,EACnD,GAAG,mBAAA;AAAA,EACH,KAAA,EAAO,OAAA;AAAA,EACP,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,KAAA;AAAA,EACR,SAAA,EAAW,WAAA;AAAA,EACX,MAAA,EAAQ,KAAA;AAAA,EACR,GAAA,EAAK;AACT,CAAA;AAeO,SAAS,cAAA,CAAe,UAAkB,QAAA,EAAiC;AAC9E,EAAA,MAAM,cAAA,GAAiB,YAAY,cAAA,EAAe;AAClD,EAAA,MAAM,MAAA,GAAS,cAAc,QAAQ,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,uBAAuB,cAAc,CAAA;AACrD,EAAA,MAAM,KAAA,GAAQ,qBAAqB,cAAc,CAAA;AAEjD,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,KAAA,MAAW,YAAY,KAAA,EAAO;AAC1B,IAAA,IAAI,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA,EAAG;AAC5B,MAAA,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAAA,IAChC;AAAA,EACJ;AAEA,EAAA,MAAM,UAAA,GAAa,UAAA,CAAW,MAAA,CAAO,GAAA,EAAK,cAAc,CAAA;AACxD,EAAA,KAAA,CAAM,KAAK,UAAU,CAAA;AAErB,EAAA,MAAM,SAAA,GAAY,cAAA,KAAmB,EAAA,CAAG,GAAA,GAAM,EAAA,GAAK,GAAA;AAEnD,EAAA,OAAO,KAAA,CAAM,KAAK,SAAS,CAAA;AAC/B;AAEA,SAAS,UAAA,CAAW,KAAa,QAAA,EAAgC;AAC7D,EAAA,MAAM,YAAA,GAAe,QAAA,KAAa,EAAA,CAAG,GAAA,GAAM,kBAAA,GAAqB,sBAAA;AAEhE,EAAA,OAAO,YAAA,CAAa,GAAG,CAAA,IAAK,GAAA,CAAI,WAAA,EAAY;AAChD;;;AChFO,SAAS,SAAA,CAAU,UAA+B,IAAA,EAAiB;AACtE,EAAA,IAAI,KAAA,EAAO;AACP,IAAA,OAAA,CAAQ,GAAA,CAAI,eAAA,EAAiB,GAAG,IAAI,CAAA;AAAA,EACxC;AACJ;;;ACAO,SAAS,yBACZ,SAAA,EACQ;AACR,EAAA,MAAM,WAAW,cAAA,EAAe;AAChC,EAAA,MAAM,KAAA,GAAQ,qBAAqB,QAAQ,CAAA;AAC3C,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACrB,IAAA,IAAI,QAAQ,WAAA,CAAY,IAAA,IAAQ,UAAU,IAAA,EAAM,MAAA,CAAO,KAAK,MAAM,CAAA;AAClE,IAAA,IAAI,QAAQ,WAAA,CAAY,GAAA,IAAO,UAAU,GAAA,EAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAC/D,IAAA,IAAI,QAAQ,WAAA,CAAY,KAAA,IAAS,UAAU,KAAA,EAAO,MAAA,CAAO,KAAK,OAAO,CAAA;AACrE,IAAA,IAAI,QAAQ,WAAA,CAAY,IAAA,IAAQ,UAAU,GAAA,EAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,EACpE;AAEA,EAAA,OAAO,MAAA;AACX;AAEO,SAAS,iBAAA,CACZ,WACA,GAAA,EACM;AACN,EAAA,MAAM,MAAA,GAAS,yBAAyB,SAAS,CAAA;AACjD,EAAA,OAAO,CAAC,GAAG,MAAA,EAAQ,GAAG,CAAA,CAAE,KAAK,GAAG,CAAA;AACpC;AAEO,SAAS,uBAAuB,KAAA,EAAyB;AAC5D,EAAA,OAAO,KAAA,CAAM,IAAI,CAAA,IAAA,KAAQ,cAAA,CAAe,IAAI,CAAC,CAAA,CAAE,KAAK,QAAQ,CAAA;AAChE;AAEO,SAAS,oBAAoB,MAAA,EAAgC;AAChE,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,IAAI,MAAA,CAAO,SAAA,CAAU,IAAA,EAAM,SAAA,CAAU,KAAK,MAAM,CAAA;AAChD,EAAA,IAAI,MAAA,CAAO,SAAA,CAAU,GAAA,EAAK,SAAA,CAAU,KAAK,KAAK,CAAA;AAC9C,EAAA,IAAI,MAAA,CAAO,SAAA,CAAU,KAAA,EAAO,SAAA,CAAU,KAAK,OAAO,CAAA;AAClD,EAAA,IAAI,MAAA,CAAO,SAAA,CAAU,IAAA,EAAM,SAAA,CAAU,KAAK,KAAK,CAAA;AAC/C,EAAA,MAAM,GAAA,GACF,MAAA,CAAO,GAAA,KAAQ,GAAA,IAAO,MAAA,CAAO,QAAQ,UAAA,GAC/B,OAAA,GACA,MAAA,CAAO,GAAA,CAAI,WAAA,EAAY;AACjC,EAAA,OAAO,CAAC,GAAG,SAAA,EAAW,GAAG,CAAA,CAAE,KAAK,GAAG,CAAA;AACvC;AAEO,SAAS,cAAc,KAAA,EAA8B;AACxD,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,IAAI,KAAA,CAAM,OAAA,EAAS,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA;AACxC,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,KAAK,CAAA;AACtC,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAC1C,EAAA,IAAI,KAAA,CAAM,OAAA,EAAS,SAAA,CAAU,IAAA,CAAK,KAAK,CAAA;AAEvC,EAAA,MAAM,GAAA,GACF,KAAA,CAAM,GAAA,KAAQ,GAAA,IAAO,KAAA,CAAM,QAAQ,UAAA,GAC7B,OAAA,GACA,KAAA,CAAM,GAAA,CAAI,WAAA,EAAY;AAChC,EAAA,OAAO,CAAC,GAAG,SAAA,EAAW,GAAG,CAAA,CAAE,KAAK,GAAG,CAAA;AACvC;AAEO,SAAS,kBAAkB,KAAA,EAA8B;AAC5D,EAAA,OAAO,cAAc,KAAK,CAAA;AAC9B;;;ACzDA,SAAS,SAAA,CAAU,GAAa,CAAA,EAAsB;AAClD,EAAA,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,CAAE,MAAA,EAAQ,OAAO,KAAA;AAChC,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,KAAK,CAAA,EAAG;AAClC,IAAA,IAAI,CAAA,CAAE,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,EAAG;AACf,MAAA,OAAO,KAAA;AAAA,IACX;AAAA,EACJ;AACA,EAAA,OAAO,IAAA;AACX;AAEO,SAAS,eAAA,CAAgB,UAA4B,aAAA,EAAoE;AAC5H,EAAA,MAAM,iBAAA,GAAoB,QAAA,CAAS,GAAA,CAAI,mBAAmB,CAAA;AAC1D,EAAA,MAAM,sBAAA,GAAyB,aAAA,CAAc,GAAA,CAAI,mBAAmB,CAAA;AACpE,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,IAAA,CAAK,GAAG,CAAA;AAC3C,EAAA,MAAM,aAAA,GAAgB,sBAAA,CAAuB,IAAA,CAAK,GAAG,CAAA;AAErD,EAAA,IAAI,QAAA,KAAa,eAAe,OAAO,OAAA;AACvC,EAAA,IAAI,UAAU,iBAAA,EAAmB,sBAAsB,KAAK,SAAA,CAAU,sBAAA,EAAwB,iBAAiB,CAAA,EAAG;AAC9G,IAAA,OAAO,iBAAA;AAAA,EACX;AAEA,EAAA,OAAO,IAAA;AACX;AAEO,SAAS,aAAA,CAAc,UAA4B,QAAA,EAA4B;AAClF,EAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,OAAA,CAAQ,gBAAA,IAAoB,IAAA;AAE9D,EAAA,IAAI,QAAA,CAAS,QAAQ,UAAA,EAAY;AAC7B,IAAA,QAAA,CAAS,OAAA,CAAQ,WAAW,QAAQ,CAAA;AACpC,IAAA;AAAA,EACJ;AAEA,EAAA,IAAI,CAAC,gBAAA,EAAkB;AAEvB,EAAA,OAAA,CAAQ,IAAA;AAAA,IACJ,CAAA,iCAAA,EAAoC,SAAS,MAAM,CAAA,WAAA,EAAc,SAAS,KAAK,CAAA,OAAA,EAAU,SAAS,aAAa,CAAA,CAAA;AAAA,GACnH;AACJ;;;ACxCO,IAAM,gCAAgB,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,UAAA,EAAY,QAAQ,CAAC,CAAA;AAE7D,IAAM,kBAAA,GAA4D;AAAA,EACrE,OAAO,CAAA,CAAA,KAAK;AACR,IAAA,IAAI,EAAE,CAAA,CAAE,MAAA,YAAkB,WAAA,CAAA,EAAc,OAAO,KAAA;AAC/C,IAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,IAAA,OAAO,aAAA,CAAc,GAAA,CAAI,MAAA,CAAO,OAAO,CAAA;AAAA,EAC3C,CAAA;AAAA,EACA,UAAU,CAAA,CAAA,KAAK;AACX,IAAA,IAAI,EAAE,CAAA,CAAE,MAAA,YAAkB,WAAA,CAAA,EAAc,OAAO,KAAA;AAC/C,IAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,IAAA,OAAO,MAAA,CAAO,iBAAA;AAAA,EAClB,CAAA;AAAA,EACA,QAAQ,CAAA,CAAA,KAAK;AACT,IAAA,IAAI,EAAE,CAAA,CAAE,MAAA,YAAkB,WAAA,CAAA,EAAc,OAAO,KAAA;AAC/C,IAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,IAAA,OAAO,aAAA,CAAc,GAAA,CAAI,MAAA,CAAO,OAAO,KAAK,MAAA,CAAO,iBAAA;AAAA,EACvD,CAAA;AAAA,EACA,OAAO,MAAM;AACT,IAAA,IACI,OAAO,QAAA,KAAa,WAAA,IACpB,OAAO,SAAS,aAAA,KAAkB,UAAA;AAElC,MAAA,OAAO,KAAA;AACX,IAAA,OACI,QAAA,CAAS,aAAA,CAAc,sCAAsC,CAAA,KAC7D,IAAA;AAAA,EAER,CAAA;AAAA,EACA,UAAU,CAAA,CAAA,KAAK;AACX,IAAA,IAAI,EAAE,CAAA,CAAE,MAAA,YAAkB,WAAA,CAAA,EAAc,OAAO,KAAA;AAC/C,IAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,IAAA,OACI,OAAO,YAAA,CAAa,UAAU,KAC9B,MAAA,CAAO,YAAA,CAAa,eAAe,CAAA,KAAM,MAAA;AAAA,EAEjD;AACJ,CAAA;AAEO,SAAS,aAAA,CACZ,OACA,MAAA,EACO;AACP,EAAA,IAAI,CAAC,QAAQ,OAAO,KAAA;AAEpB,EAAA,IAAI,OAAO,WAAW,UAAA,EAAY;AAC9B,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACvB;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AACvB,IAAA,OAAO,OAAO,IAAA,CAAK,CAAA,MAAA,KAAU,mBAAmB,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAAA,EACpE;AAEA,EAAA,OAAO,kBAAA,CAAmB,MAAM,CAAA,GAAI,KAAK,CAAA,IAAK,KAAA;AAClD;AAEO,SAAS,iBAAiB,MAAA,EAAkC;AAC/D,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AACrB,EAAA,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,SAAS,CAAC,MAAM,CAAA,EAC3C,GAAA,CAAI,WAAS,KAAA,CAAM,IAAA,EAAM,CAAA,CACzB,OAAO,OAAO,CAAA;AACvB;AAEO,SAAS,WAAA,CACZ,gBACA,YAAA,EACO;AACP,EAAA,IAAI,cAAA,CAAe,IAAA,KAAS,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,KAAA,MAAW,YAAY,cAAA,EAAgB;AACnC,IAAA,IAAI,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,EAAG,OAAO,IAAA;AAAA,EAC3C;AACA,EAAA,OAAO,KAAA;AACX;AAEO,SAAS,gBAAgB,KAAA,EAA+B;AAC3D,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,WAAA,EAAY;AAClC,EAAA,OACI,QAAQ,OAAA,IAAW,GAAA,KAAQ,SAAA,IAAa,GAAA,KAAQ,SAAS,GAAA,KAAQ,MAAA;AAEzE;;;AC1EA,SAAS,aAAa,OAAA,EAA2C;AAC7D,EAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,CAAA,EAAG,OAAO,OAAA;AAEhC,EAAA,OAAO,CAAC,GAAG,OAAO,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAC/B,IAAA,IAAI,EAAE,QAAA,KAAa,CAAA,CAAE,UAAU,OAAO,CAAA,CAAE,WAAW,CAAA,CAAE,QAAA;AACrD,IAAA,OAAO,CAAA,CAAE,KAAK,CAAA,CAAE,EAAA;AAAA,EACpB,CAAC,CAAA;AACL;AAEA,SAAS,sBAAA,CAAuB,UAA4B,KAAA,EAAsB;AAC9E,EAAA,MAAM,iBAAiB,QAAA,CAAS,OAAA;AAChC,EAAA,IAAI,eAAe,QAAA,EAAU;AAC7B,EAAA,IAAI,eAAe,WAAA,IAAe,CAAC,cAAA,CAAe,WAAA,CAAY,KAAK,CAAA,EAAG;AAEtE,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAY;AACxC,EAAA,MAAM,kBAAkB,QAAA,CAAS,cAAA,CAAe,GAAA,CAAI,iBAAA,CAAkB,KAAK,CAAC,CAAA;AAC5E,EAAA,IAAI,eAAA,EAAiB;AACjB,IAAA,KAAA,MAAW,KAAA,IAAS,eAAA,EAAiB,eAAA,CAAgB,GAAA,CAAI,KAAK,CAAA;AAAA,EAClE;AACA,EAAA,KAAA,MAAW,KAAA,IAAS,SAAS,oBAAA,EAAsB;AAC/C,IAAA,eAAA,CAAgB,IAAI,KAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,KAAA,MAAW,SAAS,eAAA,EAAiB;AACjC,IAAA,MAAM,YAAA,GAAe,QAAA,CAAS,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AACjD,IAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,IAAA,MAAM,cAAA,GAAiB,aAAa,YAAY,CAAA;AAEhD,IAAA,KAAA,MAAW,QAAQ,cAAA,EAAgB;AAC/B,MAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,MAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,MAAA,EAAQ,QAAA,CAAS,YAAY,CAAA,EAAG;AAClD,QAAA;AAAA,MACJ;AAEA,MAAA,IAAI,cAAA,CAAe,YAAA,KAAiB,KAAA,IAAS,CAAC,KAAK,MAAA,EAAQ;AACvD,QAAA,MAAM,WAAW,KAAA,CAAM,MAAA;AACvB,QAAA,IAAI,aAAa,aAAA,CAAc,GAAA,CAAI,SAAS,OAAO,CAAA,IAAK,SAAS,iBAAA,CAAA,EAAoB;AACjF,UAAA;AAAA,QACJ;AAAA,MACJ;AAEA,MAAA,IAAI,aAAA,CAAc,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA,EAAG;AACnC,QAAA,SAAA,CAAU,cAAA,CAAe,KAAA,EAAO,kCAAA,EAAoC,KAAK,CAAA;AACzE,QAAA;AAAA,MACJ;AAEA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAC/C,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,MAAA,IAAI,KAAK,QAAA,GAAW,CAAA,IAAK,MAAM,IAAA,CAAK,aAAA,GAAgB,KAAK,eAAA,EAAiB;AACtE,QAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAAA,MACpB;AAEA,MAAA,IAAI,OAAA,GAAU,KAAA;AAEd,MAAA,IAAI,eAAA,CAAgB,KAAA,EAAO,QAAQ,CAAA,EAAG;AAClC,QAAA,IAAA,CAAK,QAAA,IAAY,CAAA;AACjB,QAAA,IAAA,CAAK,aAAA,GAAgB,GAAA;AAErB,QAAA,IAAI,IAAA,CAAK,QAAA,KAAa,IAAA,CAAK,WAAA,CAAY,MAAA,EAAQ;AAC3C,UAAA,OAAA,GAAU,IAAA;AACV,UAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAAA,QACpB;AAAA,MACJ,CAAA,MAAA,IAAW,IAAA,CAAK,QAAA,GAAW,CAAA,IAAK,eAAA,CAAgB,OAAO,IAAA,CAAK,WAAA,CAAY,CAAC,CAAC,CAAA,EAAG;AACzE,QAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAChB,QAAA,IAAA,CAAK,aAAA,GAAgB,GAAA;AAAA,MACzB,CAAA,MAAO;AACH,QAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAAA,MACpB;AAEA,MAAA,KAAA,MAAW,EAAA,IAAM,KAAK,gBAAA,EAAkB;AACpC,QAAA,EAAA,CAAG,SAAS,KAAK,CAAA;AAAA,MACrB;AAEA,MAAA,IAAI,CAAC,OAAA,EAAS;AAEd,MAAA,SAAA,CAAU,cAAA,CAAe,KAAA,EAAO,UAAA,EAAY,KAAK,CAAA;AAEjD,MAAA,IAAI,KAAK,cAAA,EAAgB;AACrB,QAAA,KAAA,CAAM,cAAA,EAAe;AAAA,MACzB;AAEA,MAAA,IAAI,KAAK,eAAA,EAAiB;AACtB,QAAA,KAAA,CAAM,eAAA,EAAgB;AAAA,MAC1B;AAEA,MAAA,MAAM,cAAA,GAAiB,MAAM,IAAA,CAAK,WAAA,CAAY,KAAK,CAAA;AAEnD,MAAA,IAAI,IAAA,CAAK,QAAQ,CAAA,EAAG;AAChB,QAAA,SAAA,CAAU,cAAA,CAAe,KAAA,EAAO,uBAAA,EAAyB,IAAA,CAAK,OAAO,IAAI,CAAA;AACzE,QAAA,UAAA,CAAW,cAAA,EAAgB,KAAK,KAAK,CAAA;AAAA,MACzC,CAAA,MAAO;AACH,QAAA,cAAA,EAAe;AAAA,MACnB;AAEA,MAAA,IAAI,KAAK,WAAA,EAAa;AAClB,QAAA;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,IAAI,aAAa,IAAA,CAAK,CAAC,UAAU,KAAA,CAAM,QAAA,GAAW,CAAC,CAAA,EAAG;AAClD,MAAA,QAAA,CAAS,oBAAA,CAAqB,IAAI,KAAK,CAAA;AAAA,IAC3C,CAAA,MAAO;AACH,MAAA,QAAA,CAAS,oBAAA,CAAqB,OAAO,KAAK,CAAA;AAAA,IAC9C;AAAA,EACJ;AACJ;AAEO,SAAS,wBAAwB,QAAA,EAA4B;AAChE,EAAA,IAAI,SAAS,QAAA,EAAU;AAEvB,EAAA,MAAM,SAAS,QAAA,CAAS,OAAA,CAAQ,WAAW,OAAO,MAAA,KAAW,cAAc,MAAA,GAAS,IAAA,CAAA;AACpF,EAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,OAAA,CAAQ,SAAA,IAAa,SAAA;AAChD,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAyB,sBAAA,CAAuB,UAAU,KAAK,CAAA;AACjF,EAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,QAAyB,CAAA;AAE5D,EAAA,QAAA,CAAS,QAAA,GAAW,QAAA;AACpB,EAAA,QAAA,CAAS,cAAA,GAAiB,MAAA;AAC1B,EAAA,QAAA,CAAS,iBAAA,GAAoB,SAAA;AAE7B,EAAA,SAAA,CAAU,QAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,mBAAmB,CAAA;AACzD;AAEO,SAAS,wBAAwB,QAAA,EAA4B;AAChE,EAAA,IAAI,CAAC,QAAA,CAAS,QAAA,IAAY,CAAC,SAAS,cAAA,EAAgB;AAEpD,EAAA,QAAA,CAAS,cAAA,CAAe,mBAAA,CAAoB,QAAA,CAAS,iBAAA,EAAmB,SAAS,QAAyB,CAAA;AAC1G,EAAA,QAAA,CAAS,QAAA,GAAW,IAAA;AACpB,EAAA,QAAA,CAAS,cAAA,GAAiB,IAAA;AAC1B,EAAA,SAAA,CAAU,QAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,mBAAmB,CAAA;AACzD;;;ACnIO,SAAS,eACZ,KAAA,EACA,OAAA,EACA,cAAA,GAAiC,IACjC,QAAA,EACc;AACd,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,WAAA,EAAY,GAAI,KAAA;AAEzC,EAAA,MAAM,WAAW,KAAA,CAAM,KAAA;AAEvB,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACvB,IAAA,MAAM,IAAI,MAAM,mEAAmE,CAAA;AAAA,EACvF;AAEA,EAAA,MAAM,cAAc,QAAA,CAAS,GAAA,CAAI,CAAC,IAAA,KAAS,aAAA,CAAc,IAAI,CAAC,CAAA;AAC9D,EAAA,MAAM,QAAQ,WAAA,CAAY,GAAA,CAAI,mBAAmB,CAAA,CAAE,KAAK,GAAG,CAAA;AAC3D,EAAA,MAAM,OAAA,GAAU,uBAAuB,QAAQ,CAAA;AAC/C,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,KAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,eAAe,cAAA,CAAe,MAAA;AAE7C,EAAA,KAAA,MAAW,CAAC,aAAA,EAAe,OAAO,KAAK,QAAA,CAAS,SAAA,CAAU,SAAQ,EAAG;AACjE,IAAA,KAAA,MAAW,YAAY,OAAA,EAAS;AAC5B,MAAA,IAAI,kBAAkB,KAAA,EAAO;AAC7B,MAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,WAAA,EAAa,QAAA,CAAS,WAAW,CAAA;AAChE,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,aAAA,CAAc,QAAA,EAAU,EAAE,KAAA,EAAO,aAAA,EAAe,QAAQ,CAAA;AAAA,IAC5D;AAAA,EACJ;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,cAAA,CAAe,QAAA,IAAY,CAAC,OAAA,CAAQ,QAAA;AACvD,EAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,KAAA,IAAS,OAAA,CAAQ,KAAA,IAAS,CAAA;AACvD,EAAA,MAAM,eAAA,GAAkB,cAAA,CAAe,eAAA,IAAmB,OAAA,CAAQ,eAAA,IAAmB,GAAA;AACrF,EAAA,MAAM,cAAA,GAAiB,IAAI,GAAA,CAAI,gBAAA,CAAiB,MAAM,MAAA,IAAU,cAAA,CAAe,MAAM,CAAC,CAAA;AACtF,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAsD;AAEnF,EAAA,SAAA,CAAU,KAAA,EAAO,cAAA,EAAgB,KAAA,EAAO,QAAA,EAAK,OAAA,EAAS;AAAA,IAClD,WAAA;AAAA,IACA,MAAA,EAAQ,CAAC,CAAC,MAAA;AAAA,IACV,MAAA,EAAQ,CAAC,GAAG,cAAc;AAAA,GAC7B,CAAA;AAED,EAAA,MAAM,KAAA,GAAuB;AAAA,IACzB,IAAI,QAAA,CAAS,MAAA,EAAA;AAAA,IACb,WAAA,EAAa,OAAA;AAAA,IACb,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA,EAAQ,cAAA;AAAA,IACR,QAAA,EAAU,CAAA;AAAA,IACV,aAAA,EAAe,CAAA;AAAA,IACf,MAAA;AAAA,IACA,KAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAA,EAAgB,eAAe,cAAA,KAAmB,KAAA;AAAA,IAClD,eAAA,EAAiB,eAAe,eAAA,IAAmB,KAAA;AAAA,IACnD,WAAA,EAAa,eAAe,WAAA,IAAe,KAAA;AAAA,IAC3C,QAAA,EAAU,eAAe,QAAA,IAAY;AAAA,GACzC;AAEA,EAAA,MAAM,YAAA,GAAe,QAAA,CAAS,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AACjD,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,YAAA,CAAa,KAAK,KAAK,CAAA;AAAA,EAC3B,CAAA,MAAO;AACH,IAAA,QAAA,CAAS,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,CAAC,KAAK,CAAC,CAAA;AAErC,IAAA,MAAM,SAAA,GAAY,mBAAA,CAAoB,WAAA,CAAY,CAAC,CAAC,CAAA;AACpD,IAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA;AAC3D,IAAA,IAAI,aAAA,EAAe;AACf,MAAA,aAAA,CAAc,IAAI,KAAK,CAAA;AAAA,IAC3B,CAAA,MAAO;AACH,MAAA,QAAA,CAAS,cAAA,CAAe,IAAI,SAAA,kBAAW,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;AAAA,IAC3D;AAAA,EACJ;AAEA,EAAA,uBAAA,CAAwB,QAAQ,CAAA;AAEhC,EAAA,MAAM,cAAc,MAAM;AACtB,IAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AACnD,IAAA,IAAI,CAAC,cAAA,EAAgB;AAErB,IAAA,MAAM,WAAA,GAAc,eAAe,MAAA,CAAO,CAAC,SAAS,IAAA,CAAK,EAAA,KAAO,MAAM,EAAE,CAAA;AAExE,IAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC1B,MAAA,QAAA,CAAS,SAAA,CAAU,OAAO,KAAK,CAAA;AAC/B,MAAA,QAAA,CAAS,oBAAA,CAAqB,OAAO,KAAK,CAAA;AAE1C,MAAA,MAAM,SAAA,GAAY,mBAAA,CAAoB,WAAA,CAAY,CAAC,CAAC,CAAA;AACpD,MAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA;AAC3D,MAAA,IAAI,aAAA,EAAe;AACf,QAAA,aAAA,CAAc,OAAO,KAAK,CAAA;AAC1B,QAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC1B,UAAA,QAAA,CAAS,cAAA,CAAe,OAAO,SAAS,CAAA;AAAA,QAC5C;AAAA,MACJ;AAEA,MAAA,SAAA,CAAU,KAAA,EAAO,iBAAiB,KAAK,CAAA;AAAA,IAC3C,CAAA,MAAO;AACH,MAAA,QAAA,CAAS,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,WAAW,CAAA;AAAA,IAC7C;AAEA,IAAA,IAAI,QAAA,CAAS,SAAA,CAAU,IAAA,KAAS,CAAA,EAAG;AAC/B,MAAA,uBAAA,CAAwB,QAAQ,CAAA;AAAA,IACpC;AAAA,EACJ,CAAA;AAEA,EAAA,OAAO;AAAA,IACH,MAAA,EAAQ,WAAA;AAAA,IACR,OAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,cAAc,QAAA,CAAS,OAAA,CAAQ,SAAA,IAAa,SAAS,CAAC,CAAA;AAAA,IACjF,IAAI,SAAA,GAAY;AACZ,MAAA,OAAO,KAAA,CAAM,SAAA;AAAA,IACjB,CAAA;AAAA,IACA,QAAQ,MAAM;AACV,MAAA,KAAA,CAAM,SAAA,GAAY,IAAA;AAAA,IACtB,CAAA;AAAA,IACA,SAAS,MAAM;AACX,MAAA,KAAA,CAAM,SAAA,GAAY,KAAA;AAAA,IACtB,CAAA;AAAA,IACA,SAAA,EAAW,CAAC,QAAA,KAAa;AACrB,MAAA,KAAA,CAAM,gBAAA,CAAiB,IAAI,QAAQ,CAAA;AACnC,MAAA,OAAO,MAAM,KAAA,CAAM,gBAAA,CAAiB,MAAA,CAAO,QAAQ,CAAA;AAAA,IACvD;AAAA,GACJ;AACJ;;;AClIO,SAAS,gBAAgB,OAAA,EAA6B;AACzD,EAAA,OAAO,CAAC,gBAAA,GAA6C,EAAC,KAAuB;AACzE,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACpC,MAAA,MAAM,MAAA,GAAS,iBAAiB,MAAA,IAAU,OAAA,CAAQ,WAAW,OAAO,MAAA,KAAW,cAAc,MAAA,GAAS,IAAA,CAAA;AACtG,MAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,SAAA,IAAa,OAAA,CAAQ,SAAA,IAAa,SAAA;AAErE,MAAA,IAAI,CAAC,MAAA,EAAQ;AACT,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,wDAAwD,CAAC,CAAA;AAC1E,QAAA;AAAA,MACJ;AAEA,MAAA,IAAI,OAAA;AAEJ,MAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAiB;AAC/B,QAAA,MAAM,aAAA,GAAgB,KAAA;AACtB,QAAA,IAAI,eAAA,CAAgB,aAAa,CAAA,EAAG;AAEpC,QAAA,aAAA,CAAc,cAAA,EAAe;AAC7B,QAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,QAAyB,CAAA;AAC/D,QAAA,IAAI,OAAA,eAAsB,OAAO,CAAA;AACjC,QAAA,OAAA,CAAQ,aAAA,CAAc,aAAa,CAAC,CAAA;AAAA,MACxC,CAAA;AAEA,MAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,QAAyB,CAAA;AAE5D,MAAA,MAAM,YAAY,gBAAA,CAAiB,SAAA;AACnC,MAAA,IAAI,SAAA,IAAa,YAAY,CAAA,EAAG;AAC5B,QAAA,OAAA,GAAU,WAAW,MAAM;AACvB,UAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,QAAyB,CAAA;AAC/D,UAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,wCAAA,EAA2C,SAAS,KAAK,CAAC,CAAA;AAAA,QAC/E,GAAG,SAAS,CAAA;AAAA,MAChB;AAAA,IACJ,CAAC,CAAA;AAAA,EACL,CAAA;AACJ;;;ACnBA,IAAM,cAAA,uBAAqB,GAAA,CAAI,CAAC,QAAQ,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC,CAAA;AAE9D,SAAS,sBAAA,CAAuB,OAAA,GAA8B,EAAC,EAGpE;AACE,EAAA,MAAM,QAAA,GAA6B;AAAA,IAC/B,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB,cAAA,sBAAoB,GAAA,EAAI;AAAA,IACxB,oBAAA,sBAA0B,GAAA,EAAI;AAAA,IAC9B,OAAA;AAAA,IACA,cAAc,IAAI,GAAA,CAAI,gBAAA,CAAiB,OAAA,CAAQ,YAAY,CAAC,CAAA;AAAA,IAC5D,MAAA,EAAQ,CAAA;AAAA,IACR,QAAA,EAAU,IAAA;AAAA,IACV,cAAA,EAAgB,IAAA;AAAA,IAChB,iBAAA,EAAmB,QAAQ,SAAA,IAAa;AAAA,GAC5C;AAEA,EAAA,SAAA,CAAU,OAAA,CAAQ,KAAA,EAAO,+BAAA,EAAiC,OAAO,CAAA;AAEjE,EAAA,SAAS,aAAa,YAAA,EAA8C;AAChE,IAAA,OAAO,IAAI,KAAA,CAAM,EAAC,EAAuB;AAAA,MACrC,GAAA,CAAI,GAAG,IAAA,EAAc;AACjB,QAAA,IAAI,SAAS,SAAA,EAAW;AACpB,UAAA,OAAO,aAAa,OAAA,CAAQ,KAAA;AAAA,QAChC;AAEA,QAAA,IAAI,cAAA,CAAe,GAAA,CAAI,IAAI,CAAA,EAAG;AAC1B,UAAA,MAAM,WAAW,cAAA,EAAe;AAChC,UAAA,MAAM,SAAS,IAAA,KAAS,KAAA,GAAS,aAAa,QAAA,CAAS,GAAA,GAAM,QAAQ,MAAA,GAAU,IAAA;AAE/E,UAAA,MAAM,QAAA,GAAyB;AAAA,YAC3B,GAAG,YAAA;AAAA,YACH,SAAA,EAAW,EAAE,GAAG,YAAA,CAAa,WAAW,CAAC,MAAM,GAAG,IAAA;AAAK,WAC3D;AAEA,UAAA,SAAA,CAAU,aAAa,OAAA,CAAQ,KAAA,EAAO,WAAW,IAAI,CAAA,OAAA,CAAA,EAAM,SAAS,SAAS,CAAA;AAE7E,UAAA,OAAO,aAAa,QAAQ,CAAA;AAAA,QAChC;AAEA,QAAA,IAAI,SAAS,IAAA,EAAM;AACf,UAAA,OAAO,CAAC,MAAA,KAA0B;AAC9B,YAAA,MAAM,UAAA,GAAa,CAAC,GAAG,gBAAA,CAAiB,YAAA,CAAa,MAAM,CAAA,EAAG,GAAG,gBAAA,CAAiB,MAAM,CAAC,CAAA;AACzF,YAAA,MAAM,QAAA,GAAyB;AAAA,cAC3B,GAAG,YAAA;AAAA,cACH,MAAA,EAAQ;AAAA,aACZ;AAEA,YAAA,OAAO,aAAa,QAAQ,CAAA;AAAA,UAChC,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,WAAA,EAAa;AACtB,UAAA,OAAO,CAAC,MAAA,KAA0B;AAC9B,YAAA,QAAA,CAAS,YAAA,GAAe,IAAI,GAAA,CAAI,gBAAA,CAAiB,MAAM,CAAC,CAAA;AAAA,UAC5D,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,aAAA,EAAe;AACxB,UAAA,OAAO,CAAC,KAAA,KAAkB;AACtB,YAAA,IAAI,CAAC,KAAA,EAAO,IAAA,EAAK,EAAG;AACpB,YAAA,QAAA,CAAS,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM,CAAA;AAAA,UAC1C,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,cAAA,EAAgB;AACzB,UAAA,OAAO,CAAC,KAAA,KAAkB;AACtB,YAAA,IAAI,CAAC,KAAA,EAAO,IAAA,EAAK,EAAG;AACpB,YAAA,QAAA,CAAS,YAAA,CAAa,MAAA,CAAO,KAAA,CAAM,IAAA,EAAM,CAAA;AAAA,UAC7C,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,WAAA,EAAa;AACtB,UAAA,OAAO,MAAM,CAAC,GAAG,QAAA,CAAS,YAAY,CAAA;AAAA,QAC1C;AAEA,QAAA,IAAI,SAAS,eAAA,EAAiB;AAC1B,UAAA,OAAO,CAAC,KAAA,KAAkB,QAAA,CAAS,YAAA,CAAa,IAAI,KAAK,CAAA;AAAA,QAC7D;AAEA,QAAA,IAAI,SAAS,QAAA,EAAU;AACnB,UAAA,OAAO,eAAA,CAAgB,SAAS,OAAO,CAAA;AAAA,QAC3C;AAEA,QAAA,IAAI,SAAS,KAAA,EAAO;AAChB,UAAA,OAAO,CAAC,GAAA,KAAmB;AACvB,YAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,YAAA,CAAa,SAAA,EAAW,GAAG,CAAA;AAC9D,YAAA,MAAM,QAAA,GAAyB;AAAA,cAC3B,GAAG,YAAA;AAAA,cACH,WAAW,EAAC;AAAA,cACZ,KAAA,EAAO,CAAC,GAAG,YAAA,CAAa,OAAO,QAAQ;AAAA,aAC3C;AAEA,YAAA,SAAA,CAAU,YAAA,CAAa,OAAA,CAAQ,KAAA,EAAO,CAAA,aAAA,EAAgB,GAAG,CAAA,EAAA,CAAI,CAAA;AAE7D,YAAA,OAAO,aAAa,QAAQ,CAAA;AAAA,UAChC,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,MAAA,EAAQ;AACjB,UAAA,OAAO,CAAC,GAAA,KAA4B;AAChC,YAAA,MAAM,WAAW,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AAChD,YAAA,IAAI,CAAC,QAAA,EAAU;AACX,cAAA,MAAM,IAAI,MAAM,kEAAkE,CAAA;AAAA,YACtF;AAEA,YAAA,MAAM,QAAA,GAAyB;AAAA,cAC3B,GAAG,YAAA;AAAA,cACH,KAAA,EAAO,CAAC,GAAG,YAAA,CAAa,OAAO,QAAQ;AAAA,aAC3C;AAEA,YAAA,SAAA,CAAU,YAAA,CAAa,OAAA,CAAQ,KAAA,EAAO,CAAA,cAAA,EAAiB,QAAQ,CAAA,EAAA,CAAI,CAAA;AAEnE,YAAA,OAAO,aAAa,QAAQ,CAAA;AAAA,UAChC,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,QAAA,EAAU;AACnB,UAAA,OAAO,CAAC,SAAA,KAA+D;AACnE,YAAA,MAAM,QAAA,GAAyB;AAAA,cAC3B,GAAG,YAAA;AAAA,cACH,MAAA,EAAQ;AAAA,aACZ;AAEA,YAAA,SAAA,CAAU,YAAA,CAAa,OAAA,CAAQ,KAAA,EAAO,kBAAA,EAAoB,SAAS,CAAA;AAEnE,YAAA,OAAO,aAAa,QAAQ,CAAA;AAAA,UAChC,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,IAAA,EAAM;AACf,UAAA,OAAO,CAAC,SAA0B,cAAA,KAAoC;AAClE,YAAA,OAAO,cAAA,CAAe,YAAA,EAAc,OAAA,EAAS,cAAA,EAAgB,QAAQ,CAAA;AAAA,UACzE,CAAA;AAAA,QACJ;AAEA,QAAA,IAAI,SAAS,QAAA,EAAU;AACnB,UAAA,OAAO,CAAC,IAAA,KAAwD;AAC5D,YAAA,MAAM,EAAE,OAAA,EAAS,GAAG,IAAA,EAAK,GAAI,IAAA;AAC7B,YAAA,OAAO,cAAA,CAAe,YAAA,EAAc,OAAA,EAAS,IAAA,EAAM,QAAQ,CAAA;AAAA,UAC/D,CAAA;AAAA,QACJ;AAEA,QAAA,OAAO,MAAA;AAAA,MACX;AAAA,KACH,CAAA;AAAA,EACL;AAEA,EAAA,MAAM,YAAA,GAA6B;AAAA,IAC/B,WAAW,EAAC;AAAA,IACZ,OAAO,EAAC;AAAA,IACR;AAAA,GACJ;AAEA,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,aAAa,YAAY,CAAA;AAAA,IAClC;AAAA,GACJ;AACJ;;;ACQO,SAAS,WAAA,CAAY,OAAA,GAA8B,EAAC,EAAoB;AAC3E,EAAA,MAAM,UAAA,GAAa,OAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAErB,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAS,GAAI,QAAQ,MAAM;AACxC,IAAA,OAAO,sBAAA,CAAuB,WAAW,OAAO,CAAA;AAAA,EACpD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,QAAA,CAAS,UAAU,UAAA,CAAW,OAAA;AAE9B,IAAA,IAAI,UAAA,CAAW,OAAA,CAAQ,YAAA,KAAiB,MAAA,EAAW;AAC/C,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,OAAA,CAAQ,YAAY,CAAA,GACtD,UAAA,CAAW,OAAA,CAAQ,YAAA,GACnB,CAAC,UAAA,CAAW,QAAQ,YAAY,CAAA;AAEtC,MAAA,QAAA,CAAS,YAAA,GAAe,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU,KAAA,CAAM,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,IACvF;AAAA,EACJ,CAAA,EAAG,CAAC,QAAA,EAAU,OAAO,CAAC,CAAA;AAEtB,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,OAAO,MAAM;AACT,MAAA,QAAA,CAAS,UAAU,KAAA,EAAM;AACzB,MAAA,QAAA,CAAS,eAAe,KAAA,EAAM;AAC9B,MAAA,QAAA,CAAS,qBAAqB,KAAA,EAAM;AAEpC,MAAA,IAAI,QAAA,CAAS,QAAA,IAAY,QAAA,CAAS,cAAA,EAAgB;AAC9C,QAAA,QAAA,CAAS,cAAA,CAAe,mBAAA,CAAoB,QAAA,CAAS,iBAAA,EAAmB,SAAS,QAAyB,CAAA;AAC1G,QAAA,QAAA,CAAS,QAAA,GAAW,IAAA;AACpB,QAAA,QAAA,CAAS,cAAA,GAAiB,IAAA;AAAA,MAC9B;AAAA,IACJ,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,OAAO,OAAA;AACX","file":"index.mjs","sourcesContent":["/** Supported runtime OS identifiers used by formatter and parser normalization. */\nexport const OS = {\n MAC: \"mac\",\n WINDOWS: \"windows\",\n LINUX: \"linux\",\n} as const\n\nexport type PlatformType = (typeof OS)[keyof typeof OS]\n\n/** Public platform constant alias (`Platform.MAC`, `Platform.WINDOWS`, `Platform.LINUX`). */\nexport const Platform = OS\n\nlet _cachedPlatform: PlatformType | null = null\n\n/**\n * Detect the current OS platform for modifier normalization and display formatting.\n * Result is memoized for the page lifecycle.\n */\nexport function detectPlatform(): PlatformType {\n if (_cachedPlatform) return _cachedPlatform\n if (typeof navigator === \"undefined\") {\n _cachedPlatform = OS.WINDOWS\n return _cachedPlatform\n }\n\n const uaPlatform = (\n navigator as Navigator & {\n userAgentData?: { platform?: string }\n }\n ).userAgentData?.platform?.toLowerCase()\n\n const platform = (uaPlatform ?? navigator.platform ?? navigator.userAgent ?? \"\").toLowerCase()\n\n if (\n platform.includes(\"mac\")\n || platform.includes(\"iphone\")\n || platform.includes(\"ipad\")\n || platform.includes(\"ipod\")\n ) {\n _cachedPlatform = OS.MAC\n return _cachedPlatform\n }\n\n if (platform.includes(\"linux\") || platform.includes(\"android\")) {\n _cachedPlatform = OS.LINUX\n return _cachedPlatform\n }\n\n if (platform.includes(\"win\")) {\n _cachedPlatform = OS.WINDOWS\n return _cachedPlatform\n }\n\n _cachedPlatform = OS.WINDOWS\n return _cachedPlatform\n}\n\n/** Canonical modifier token names used internally across parsing/formatting. */\nexport const ModifierKey = {\n META: \"meta\",\n CTRL: \"ctrl\",\n ALT: \"alt\",\n SHIFT: \"shift\",\n} as const\n\nexport type ModifierKeyType = (typeof ModifierKey)[keyof typeof ModifierKey]\n\n/** Alias map from user-facing modifier tokens to canonical modifier keys. */\nexport const ModifierAliases: Record<string, ModifierKeyType> = {\n command: ModifierKey.META,\n cmd: ModifierKey.META,\n \"⌘\": ModifierKey.META,\n meta: ModifierKey.META,\n win: ModifierKey.META,\n windows: ModifierKey.META,\n super: ModifierKey.META,\n mod: ModifierKey.META,\n control: ModifierKey.CTRL,\n ctrl: ModifierKey.CTRL,\n \"⌃\": ModifierKey.CTRL,\n ctl: ModifierKey.CTRL,\n alt: ModifierKey.ALT,\n option: ModifierKey.ALT,\n opt: ModifierKey.ALT,\n \"⌥\": ModifierKey.ALT,\n shift: ModifierKey.SHIFT,\n \"⇧\": ModifierKey.SHIFT,\n shft: ModifierKey.SHIFT,\n} as const\n\n/** Alias map from human shortcut key tokens to `KeyboardEvent.key`-compatible values. */\nexport const SpecialKeyMap: Record<string, string> = {\n up: \"ArrowUp\",\n down: \"ArrowDown\",\n left: \"ArrowLeft\",\n right: \"ArrowRight\",\n home: \"Home\",\n end: \"End\",\n pageup: \"PageUp\",\n pagedown: \"PageDown\",\n enter: \"Enter\",\n return: \"Enter\",\n space: \" \",\n spacebar: \" \",\n tab: \"Tab\",\n backspace: \"Backspace\",\n delete: \"Delete\",\n del: \"Delete\",\n escape: \"Escape\",\n esc: \"Escape\",\n f1: \"F1\",\n f2: \"F2\",\n f3: \"F3\",\n f4: \"F4\",\n f5: \"F5\",\n f6: \"F6\",\n f7: \"F7\",\n f8: \"F8\",\n f9: \"F9\",\n f10: \"F10\",\n f11: \"F11\",\n f12: \"F12\",\n plus: \"+\",\n minus: \"-\",\n comma: \",\",\n period: \".\",\n slash: \"/\",\n backslash: \"\\\\\",\n bracket: \"[\",\n closebracket: \"]\",\n} as const\n\n/** Platform-specific display labels/symbols for modifier keys. */\nexport const ModifierDisplaySymbols: Record<PlatformType, Record<ModifierKeyType, string>> = {\n [OS.MAC]: {\n [ModifierKey.META]: \"⌘\",\n [ModifierKey.CTRL]: \"⌃\",\n [ModifierKey.ALT]: \"⌥\",\n [ModifierKey.SHIFT]: \"⇧\",\n },\n [OS.WINDOWS]: {\n [ModifierKey.META]: \"Ctrl\",\n [ModifierKey.CTRL]: \"Ctrl\",\n [ModifierKey.ALT]: \"Alt\",\n [ModifierKey.SHIFT]: \"Shift\",\n },\n [OS.LINUX]: {\n [ModifierKey.META]: \"Super\",\n [ModifierKey.CTRL]: \"Ctrl\",\n [ModifierKey.ALT]: \"Alt\",\n [ModifierKey.SHIFT]: \"Shift\",\n },\n} as const\n\n/** Platform-specific canonical order for modifier rendering and combo normalization. */\nexport const ModifierDisplayOrder: Record<PlatformType, ModifierKeyType[]> = {\n [OS.MAC]: [ModifierKey.CTRL, ModifierKey.ALT, ModifierKey.SHIFT, ModifierKey.META],\n [OS.WINDOWS]: [ModifierKey.META, ModifierKey.ALT, ModifierKey.SHIFT, ModifierKey.CTRL],\n [OS.LINUX]: [ModifierKey.META, ModifierKey.ALT, ModifierKey.SHIFT, ModifierKey.CTRL],\n} as const\n","import { ModifierAliases, SpecialKeyMap, detectPlatform, Platform } from \"./constants\"\nimport type { ModifierState, ParsedShortcut } from \"./types\"\n\nfunction _normalizeKeyToken(key: string): string {\n return key === \" \" ? \"space\" : key.toLowerCase()\n}\n\n/**\n * Parse a shortcut string into its components\n *\n * @param shortcut - Shortcut string (e.g., \"cmd+s\", \"ctrl+shift+p\")\n * @returns Parsed shortcut with modifiers, key, and original string\n *\n * @example\n * ```ts\n * const parsed = parseShortcut(\"cmd+s\")\n * // { modifiers: { meta: true, ... }, key: \"s\", original: \"cmd+s\" }\n * ```\n */\nexport function parseShortcut(shortcut: string): ParsedShortcut {\n const platform = detectPlatform()\n const normalized = shortcut.toLowerCase().trim()\n const parts = normalized.split(/[\\s+-]+/).filter(Boolean)\n\n if (parts.length === 0) {\n throw new Error(`Invalid shortcut: \"${shortcut}\"`)\n }\n\n const modifiers: ModifierState = {\n meta: false,\n ctrl: false,\n alt: false,\n shift: false,\n }\n\n let key = parts.pop()!\n\n for (const part of parts) {\n const modifierKey = ModifierAliases[part]\n\n if (modifierKey) {\n if (part === \"mod\") {\n if (platform === Platform.MAC) {\n modifiers.meta = true\n } else {\n modifiers.ctrl = true\n }\n } else {\n modifiers[modifierKey] = true\n }\n } else {\n key = part + key\n }\n }\n\n const normalizedKey = SpecialKeyMap[key] || key\n\n return {\n modifiers,\n key: normalizedKey.length === 1 ? normalizedKey.toLowerCase() : normalizedKey,\n original: shortcut,\n }\n}\n\n/**\n * Parse multiple shortcut strings\n *\n * @param shortcuts - Single shortcut or array of shortcuts\n * @returns Array of parsed shortcuts\n */\nexport function parseShortcuts(shortcuts: string | string[]): ParsedShortcut[] {\n const shortcutArray = Array.isArray(shortcuts) ? shortcuts : [shortcuts]\n return shortcutArray.map(parseShortcut)\n}\n\n/**\n * Extract modifier state from a keyboard event\n *\n * @param event - The keyboard event\n * @returns Object with meta, ctrl, alt, shift boolean flags\n */\nexport function getModifiersFromEvent(event: KeyboardEvent): ModifierState {\n return {\n meta: event.metaKey,\n ctrl: event.ctrlKey,\n alt: event.altKey,\n shift: event.shiftKey,\n }\n}\n\n/**\n * Check if a keyboard event matches a parsed shortcut\n *\n * @param event - The keyboard event to check\n * @param parsed - The parsed shortcut to match against\n * @returns `true` if the event matches the shortcut\n */\nexport function matchesShortcut(event: KeyboardEvent, parsed: ParsedShortcut): boolean {\n const eventModifiers = getModifiersFromEvent(event)\n const eventKey = _normalizeKeyToken(event.key)\n\n const modifiersMatch =\n eventModifiers.meta === parsed.modifiers.meta &&\n eventModifiers.ctrl === parsed.modifiers.ctrl &&\n eventModifiers.alt === parsed.modifiers.alt &&\n eventModifiers.shift === parsed.modifiers.shift\n\n const keyMatches = eventKey === _normalizeKeyToken(parsed.key)\n\n return modifiersMatch && keyMatches\n}\n\n/**\n * Check if a keyboard event matches any of the parsed shortcuts\n *\n * @param event - The keyboard event to check\n * @param parsedShortcuts - Array of parsed shortcuts to match against\n * @returns `true` if the event matches any shortcut\n */\nexport function matchesAnyShortcut(event: KeyboardEvent, parsedShortcuts: ParsedShortcut[]): boolean {\n return parsedShortcuts.some((parsed) => matchesShortcut(event, parsed))\n}\n","import {\n ModifierDisplayOrder,\n ModifierDisplaySymbols,\n OS,\n detectPlatform,\n type ModifierKeyType,\n type PlatformType,\n} from \"./constants\"\nimport { parseShortcut } from \"./parser\"\n\nconst _BASE_DISPLAY_NAMES: Record<string, string> = {\n ArrowUp: \"↑\",\n ArrowDown: \"↓\",\n ArrowLeft: \"←\",\n ArrowRight: \"→\",\n Home: \"Home\",\n End: \"End\",\n PageUp: \"PgUp\",\n PageDown: \"PgDn\",\n}\n\nconst _MAC_DISPLAY_NAMES: Record<string, string> = {\n ..._BASE_DISPLAY_NAMES,\n Enter: \"↩\",\n Tab: \"⇥\",\n Escape: \"⎋\",\n Backspace: \"⌫\",\n Delete: \"⌦\",\n \" \": \"␣\",\n}\n\nconst _NON_MAC_DISPLAY_NAMES: Record<string, string> = {\n ..._BASE_DISPLAY_NAMES,\n Enter: \"Enter\",\n Tab: \"Tab\",\n Escape: \"Esc\",\n Backspace: \"Backspace\",\n Delete: \"Del\",\n \" \": \"Space\",\n}\n\n/**\n * Format a shortcut string for display with platform-aware symbols\n *\n * @param shortcut - Shortcut string (e.g., \"cmd+s\")\n * @param platform - Optional platform override (default: auto-detect)\n * @returns Formatted display string (e.g., \"⌘S\" on Mac, \"Ctrl+S\" on Windows)\n *\n * @example\n * ```ts\n * formatShortcut(\"cmd+s\") // \"⌘S\" on Mac, \"Ctrl+S\" on Windows\n * formatShortcut(\"ctrl+shift+p\", \"mac\") // \"⌃⇧P\"\n * ```\n */\nexport function formatShortcut(shortcut: string, platform?: PlatformType): string {\n const targetPlatform = platform ?? detectPlatform()\n const parsed = parseShortcut(shortcut)\n const symbols = ModifierDisplaySymbols[targetPlatform]\n const order = ModifierDisplayOrder[targetPlatform]\n\n const parts: string[] = []\n\n for (const modifier of order) {\n if (parsed.modifiers[modifier]) {\n parts.push(symbols[modifier])\n }\n }\n\n const displayKey = _formatKey(parsed.key, targetPlatform)\n parts.push(displayKey)\n\n const separator = targetPlatform === OS.MAC ? \"\" : \"+\"\n\n return parts.join(separator)\n}\n\nfunction _formatKey(key: string, platform: PlatformType): string {\n const displayNames = platform === OS.MAC ? _MAC_DISPLAY_NAMES : _NON_MAC_DISPLAY_NAMES\n\n return displayNames[key] || key.toUpperCase()\n}\n\n/**\n * Get the modifier key symbols for a platform\n *\n * @param platform - Optional platform override (default: auto-detect)\n * @returns Object mapping modifier keys to display symbols\n *\n * @example\n * ```ts\n * getModifierSymbols(\"mac\") // { meta: \"⌘\", ctrl: \"⌃\", alt: \"⌥\", shift: \"⇧\" }\n * ```-\n */\nexport function getModifierSymbols(platform?: PlatformType): Record<ModifierKeyType, string> {\n const targetPlatform = platform ?? detectPlatform()\n return ModifierDisplaySymbols[targetPlatform]\n}\n","export function _debugLog(debug: boolean | undefined, ...args: unknown[]) {\n if (debug) {\n console.log(\"[useShortcut]\", ...args)\n }\n}\n\n","import { detectPlatform, ModifierDisplayOrder, ModifierKey } from \"../constants\"\nimport { formatShortcut } from \"../formatter\"\nimport type { ModifierFlags, ParsedShortcut } from \"../types\"\n\nexport function _getActiveModifierTokens(\n modifiers: Partial<ModifierFlags>\n): string[] {\n const platform = detectPlatform()\n const order = ModifierDisplayOrder[platform]\n const tokens: string[] = []\n\n for (const key of order) {\n if (key === ModifierKey.CTRL && modifiers.ctrl) tokens.push(\"ctrl\")\n if (key === ModifierKey.ALT && modifiers.alt) tokens.push(\"alt\")\n if (key === ModifierKey.SHIFT && modifiers.shift) tokens.push(\"shift\")\n if (key === ModifierKey.META && modifiers.cmd) tokens.push(\"cmd\")\n }\n\n return tokens\n}\n\nexport function _buildComboString(\n modifiers: Partial<ModifierFlags>,\n key: string\n): string {\n const tokens = _getActiveModifierTokens(modifiers)\n return [...tokens, key].join(\"+\")\n}\n\nexport function _formatSequenceDisplay(steps: string[]): string {\n return steps.map(step => formatShortcut(step)).join(\" then \")\n}\n\nexport function _canonicalizeParsed(parsed: ParsedShortcut): string {\n const modifiers: string[] = []\n if (parsed.modifiers.ctrl) modifiers.push(\"ctrl\")\n if (parsed.modifiers.alt) modifiers.push(\"alt\")\n if (parsed.modifiers.shift) modifiers.push(\"shift\")\n if (parsed.modifiers.meta) modifiers.push(\"cmd\")\n const key =\n parsed.key === \" \" || parsed.key === \"Spacebar\"\n ? \"space\"\n : parsed.key.toLowerCase()\n return [...modifiers, key].join(\"+\")\n}\n\nexport function _eventToCombo(event: KeyboardEvent): string {\n const modifiers: string[] = []\n if (event.ctrlKey) modifiers.push(\"ctrl\")\n if (event.altKey) modifiers.push(\"alt\")\n if (event.shiftKey) modifiers.push(\"shift\")\n if (event.metaKey) modifiers.push(\"cmd\")\n\n const key =\n event.key === \" \" || event.key === \"Spacebar\"\n ? \"space\"\n : event.key.toLowerCase()\n return [...modifiers, key].join(\"+\")\n}\n\nexport function _eventToMatchStep(event: KeyboardEvent): string {\n return _eventToCombo(event)\n}\n","import type { ParsedShortcut, ShortcutConflict } from \"../types\"\nimport type { ShortcutRegistry } from \"./types\"\n\nimport { _canonicalizeParsed } from \"./keys\"\n\nfunction _isPrefix(a: string[], b: string[]): boolean {\n if (a.length > b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) {\n return false\n }\n }\n return true\n}\n\nexport function _detectConflict(newSteps: ParsedShortcut[], existingSteps: ParsedShortcut[]): ShortcutConflict[\"reason\"] | null {\n const newCanonicalSteps = newSteps.map(_canonicalizeParsed)\n const existingCanonicalSteps = existingSteps.map(_canonicalizeParsed)\n const newCombo = newCanonicalSteps.join(\" \")\n const existingCombo = existingCanonicalSteps.join(\" \")\n\n if (newCombo === existingCombo) return \"exact\"\n if (_isPrefix(newCanonicalSteps, existingCanonicalSteps) || _isPrefix(existingCanonicalSteps, newCanonicalSteps)) {\n return \"sequence-prefix\"\n }\n\n return null\n}\n\nexport function _emitConflict(registry: ShortcutRegistry, conflict: ShortcutConflict) {\n const conflictWarnings = registry.options.conflictWarnings ?? true\n\n if (registry.options.onConflict) {\n registry.options.onConflict(conflict)\n return\n }\n\n if (!conflictWarnings) return\n\n console.warn(\n `[useShortcut] Conflict detected (${conflict.reason}) between \"${conflict.combo}\" and \"${conflict.existingCombo}\"`,\n )\n}\n","import type { ExceptPreset, ExceptPredicate, ShortcutScope } from \"../types\"\n\nexport const _IGNORED_TAGS = new Set([\"INPUT\", \"TEXTAREA\", \"SELECT\"])\n\nexport const _EXCEPT_PREDICATES: Record<ExceptPreset, ExceptPredicate> = {\n input: e => {\n if (!(e.target instanceof HTMLElement)) return false\n const target = e.target\n return _IGNORED_TAGS.has(target.tagName)\n },\n editable: e => {\n if (!(e.target instanceof HTMLElement)) return false\n const target = e.target\n return target.isContentEditable\n },\n typing: e => {\n if (!(e.target instanceof HTMLElement)) return false\n const target = e.target\n return _IGNORED_TAGS.has(target.tagName) || target.isContentEditable\n },\n modal: () => {\n if (\n typeof document === \"undefined\" ||\n typeof document.querySelector !== \"function\"\n )\n return false\n return (\n document.querySelector('[data-modal=\"true\"], [role=\"dialog\"]') !==\n null\n )\n },\n disabled: e => {\n if (!(e.target instanceof HTMLElement)) return false\n const target = e.target\n return (\n target.hasAttribute(\"disabled\") ||\n target.getAttribute(\"aria-disabled\") === \"true\"\n )\n }\n}\n\nexport function _shouldExcept(\n event: KeyboardEvent,\n except?: ExceptPreset | ExceptPreset[] | ExceptPredicate\n): boolean {\n if (!except) return false\n\n if (typeof except === \"function\") {\n return except(event)\n }\n\n if (Array.isArray(except)) {\n return except.some(preset => _EXCEPT_PREDICATES[preset]?.(event))\n }\n\n return _EXCEPT_PREDICATES[except]?.(event) ?? false\n}\n\nexport function _normalizeScopes(scopes?: ShortcutScope): string[] {\n if (!scopes) return []\n return (Array.isArray(scopes) ? scopes : [scopes])\n .map(scope => scope.trim())\n .filter(Boolean)\n}\n\nexport function _scopeMatch(\n requiredScopes: Set<string>,\n activeScopes: Set<string>\n): boolean {\n if (requiredScopes.size === 0) return true\n for (const required of requiredScopes) {\n if (activeScopes.has(required)) return true\n }\n return false\n}\n\nexport function _isPureModifier(event: KeyboardEvent): boolean {\n const key = event.key.toLowerCase()\n return (\n key === \"shift\" || key === \"control\" || key === \"alt\" || key === \"meta\"\n )\n}\n","import { matchesShortcut } from \"../parser\"\n\nimport { _debugLog } from \"./debug\"\nimport { _eventToMatchStep } from \"./keys\"\nimport { _IGNORED_TAGS, _scopeMatch, _shouldExcept } from \"./guards\"\nimport type { RegistryEntry, ShortcutRegistry } from \"./types\"\n\nfunction _sortEntries(entries: RegistryEntry[]): RegistryEntry[] {\n if (entries.length <= 1) return entries\n\n return [...entries].sort((a, b) => {\n if (b.priority !== a.priority) return b.priority - a.priority\n return a.id - b.id\n })\n}\n\nfunction _dispatchRegistryEvent(registry: ShortcutRegistry, event: KeyboardEvent) {\n const runtimeOptions = registry.options\n if (runtimeOptions.disabled) return\n if (runtimeOptions.eventFilter && !runtimeOptions.eventFilter(event)) return\n\n const candidateCombos = new Set<string>()\n const firstStepCombos = registry.firstStepIndex.get(_eventToMatchStep(event))\n if (firstStepCombos) {\n for (const combo of firstStepCombos) candidateCombos.add(combo)\n }\n for (const combo of registry.activeSequenceCombos) {\n candidateCombos.add(combo)\n }\n\n for (const combo of candidateCombos) {\n const comboEntries = registry.listeners.get(combo)\n if (!comboEntries) continue\n\n const orderedEntries = _sortEntries(comboEntries)\n\n for (const item of orderedEntries) {\n if (!item.isEnabled) continue\n\n if (!_scopeMatch(item.scopes, registry.activeScopes)) {\n continue\n }\n\n if (runtimeOptions.ignoreInputs !== false && !item.except) {\n const targetEl = event.target as HTMLElement\n if (targetEl && (_IGNORED_TAGS.has(targetEl.tagName) || targetEl.isContentEditable)) {\n continue\n }\n }\n\n if (_shouldExcept(event, item.except)) {\n _debugLog(runtimeOptions.debug, \"Skipped due to except condition:\", combo)\n continue\n }\n\n const expected = item.parsedSteps[item.progress]\n const now = Date.now()\n\n if (item.progress > 0 && now - item.lastMatchedAt > item.sequenceTimeout) {\n item.progress = 0\n }\n\n let matched = false\n\n if (matchesShortcut(event, expected)) {\n item.progress += 1\n item.lastMatchedAt = now\n\n if (item.progress === item.parsedSteps.length) {\n matched = true\n item.progress = 0\n }\n } else if (item.progress > 0 && matchesShortcut(event, item.parsedSteps[0])) {\n item.progress = 1\n item.lastMatchedAt = now\n } else {\n item.progress = 0\n }\n\n for (const cb of item.attemptCallbacks) {\n cb(matched, event)\n }\n\n if (!matched) continue\n\n _debugLog(runtimeOptions.debug, \"MATCHED:\", combo)\n\n if (item.preventDefault) {\n event.preventDefault()\n }\n\n if (item.stopPropagation) {\n event.stopPropagation()\n }\n\n const executeHandler = () => item.userHandler(event)\n\n if (item.delay > 0) {\n _debugLog(runtimeOptions.debug, \"Delaying execution by\", item.delay, \"ms\")\n setTimeout(executeHandler, item.delay)\n } else {\n executeHandler()\n }\n\n if (item.stopOnMatch) {\n break\n }\n }\n\n if (comboEntries.some((entry) => entry.progress > 0)) {\n registry.activeSequenceCombos.add(combo)\n } else {\n registry.activeSequenceCombos.delete(combo)\n }\n }\n}\n\nexport function _attachRegistryListener(registry: ShortcutRegistry) {\n if (registry.listener) return\n\n const target = registry.options.target ?? (typeof window !== \"undefined\" ? window : null)\n if (!target) return\n\n const eventType = registry.options.eventType ?? \"keydown\"\n const listener = (event: KeyboardEvent) => _dispatchRegistryEvent(registry, event)\n target.addEventListener(eventType, listener as EventListener)\n\n registry.listener = listener\n registry.listenerTarget = target\n registry.listenerEventType = eventType\n\n _debugLog(registry.options.debug, \"Listener attached\")\n}\n\nexport function _detachRegistryListener(registry: ShortcutRegistry) {\n if (!registry.listener || !registry.listenerTarget) return\n\n registry.listenerTarget.removeEventListener(registry.listenerEventType, registry.listener as EventListener)\n registry.listener = null\n registry.listenerTarget = null\n _debugLog(registry.options.debug, \"Listener detached\")\n}\n","import { parseShortcut } from \"../parser\"\nimport type { HandlerOptions, ShortcutHandler, ShortcutResult } from \"../types\"\n\nimport { _debugLog } from \"./debug\"\nimport { _detectConflict, _emitConflict } from \"./conflicts\"\nimport { _canonicalizeParsed, _formatSequenceDisplay } from \"./keys\"\nimport { _normalizeScopes } from \"./guards\"\nimport { _attachRegistryListener, _detachRegistryListener } from \"./listener\"\nimport type { BuilderState, RegistryEntry, ShortcutRegistry } from \"./types\"\n\nexport function _createBinding(\n state: BuilderState,\n handler: ShortcutHandler,\n handlerOptions: HandlerOptions = {},\n registry: ShortcutRegistry,\n): ShortcutResult {\n const { options, except: stateExcept } = state\n\n const rawSteps = state.steps\n\n if (rawSteps.length === 0) {\n throw new Error('[useShortcut] No key specified. Use .key() to set the action key.')\n }\n\n const parsedSteps = rawSteps.map((step) => parseShortcut(step))\n const combo = parsedSteps.map(_canonicalizeParsed).join(\" \")\n const display = _formatSequenceDisplay(rawSteps)\n const debug = options.debug ?? false\n const except = stateExcept ?? handlerOptions.except\n\n for (const [existingCombo, entries] of registry.listeners.entries()) {\n for (const existing of entries) {\n if (existingCombo === combo) continue\n const reason = _detectConflict(parsedSteps, existing.parsedSteps)\n if (!reason) continue\n _emitConflict(registry, { combo, existingCombo, reason })\n }\n }\n\n const isEnabled = !handlerOptions.disabled && !options.disabled\n const delay = handlerOptions.delay ?? options.delay ?? 0\n const sequenceTimeout = handlerOptions.sequenceTimeout ?? options.sequenceTimeout ?? 800\n const requiredScopes = new Set(_normalizeScopes(state.scopes ?? handlerOptions.scopes))\n const attemptCallbacks = new Set<(matched: boolean, event: KeyboardEvent) => void>()\n\n _debugLog(debug, \"Registering:\", combo, \"→\", display, {\n parsedSteps,\n except: !!except,\n scopes: [...requiredScopes],\n })\n\n const entry: RegistryEntry = {\n id: registry.nextId++,\n userHandler: handler,\n isEnabled,\n attemptCallbacks,\n parsedSteps,\n scopes: requiredScopes,\n progress: 0,\n lastMatchedAt: 0,\n except,\n delay,\n sequenceTimeout,\n preventDefault: handlerOptions.preventDefault !== false,\n stopPropagation: handlerOptions.stopPropagation ?? false,\n stopOnMatch: handlerOptions.stopOnMatch ?? false,\n priority: handlerOptions.priority ?? 0,\n }\n\n const comboEntries = registry.listeners.get(combo)\n if (comboEntries) {\n comboEntries.push(entry)\n } else {\n registry.listeners.set(combo, [entry])\n\n const firstStep = _canonicalizeParsed(parsedSteps[0])\n const indexedCombos = registry.firstStepIndex.get(firstStep)\n if (indexedCombos) {\n indexedCombos.add(combo)\n } else {\n registry.firstStepIndex.set(firstStep, new Set([combo]))\n }\n }\n\n _attachRegistryListener(registry)\n\n const unbindEntry = () => {\n const currentEntries = registry.listeners.get(combo)\n if (!currentEntries) return\n\n const nextEntries = currentEntries.filter((item) => item.id !== entry.id)\n\n if (nextEntries.length === 0) {\n registry.listeners.delete(combo)\n registry.activeSequenceCombos.delete(combo)\n\n const firstStep = _canonicalizeParsed(parsedSteps[0])\n const indexedCombos = registry.firstStepIndex.get(firstStep)\n if (indexedCombos) {\n indexedCombos.delete(combo)\n if (indexedCombos.size === 0) {\n registry.firstStepIndex.delete(firstStep)\n }\n }\n\n _debugLog(debug, \"Unregistered:\", combo)\n } else {\n registry.listeners.set(combo, nextEntries)\n }\n\n if (registry.listeners.size === 0) {\n _detachRegistryListener(registry)\n }\n }\n\n return {\n unbind: unbindEntry,\n display,\n combo,\n trigger: () => handler(new KeyboardEvent(registry.options.eventType ?? \"keydown\")),\n get isEnabled() {\n return entry.isEnabled\n },\n enable: () => {\n entry.isEnabled = true\n },\n disable: () => {\n entry.isEnabled = false\n },\n onAttempt: (callback) => {\n entry.attemptCallbacks.add(callback)\n return () => entry.attemptCallbacks.delete(callback)\n },\n }\n}\n\n","import type { ShortcutRecordingOptions, UseShortcutOptions } from \"../types\"\nimport { _eventToCombo } from \"./keys\"\nimport { _isPureModifier } from \"./guards\"\n\nexport function _createRecorder(options: UseShortcutOptions) {\n return (recordingOptions: ShortcutRecordingOptions = {}): Promise<string> => {\n return new Promise((resolve, reject) => {\n const target = recordingOptions.target ?? options.target ?? (typeof window !== \"undefined\" ? window : null)\n const eventType = recordingOptions.eventType ?? options.eventType ?? \"keydown\"\n\n if (!target) {\n reject(new Error(\"[useShortcut] Cannot record shortcut without a target.\"))\n return\n }\n\n let timeout: ReturnType<typeof setTimeout> | undefined\n\n const listener = (event: Event) => {\n const keyboardEvent = event as KeyboardEvent\n if (_isPureModifier(keyboardEvent)) return\n\n keyboardEvent.preventDefault()\n target.removeEventListener(eventType, listener as EventListener)\n if (timeout) clearTimeout(timeout)\n resolve(_eventToCombo(keyboardEvent))\n }\n\n target.addEventListener(eventType, listener as EventListener)\n\n const timeoutMs = recordingOptions.timeoutMs\n if (timeoutMs && timeoutMs > 0) {\n timeout = setTimeout(() => {\n target.removeEventListener(eventType, listener as EventListener)\n reject(new Error(`[useShortcut] Recording timed out after ${timeoutMs}ms.`))\n }, timeoutMs)\n }\n })\n }\n}\n","import { detectPlatform, Platform } from \"./constants\"\nimport type {\n ActionKey,\n HandlerOptions,\n ShortcutBuilder as IShortcutBuilder,\n ShortcutScope,\n UseShortcutOptions,\n ExceptPreset,\n ExceptPredicate,\n ShortcutHandler,\n} from \"./types\"\n\nimport { _createBinding } from \"./runtime/binding\"\nimport { _debugLog } from \"./runtime/debug\"\nimport { _normalizeScopes } from \"./runtime/guards\"\nimport { _buildComboString } from \"./runtime/keys\"\nimport { _createRecorder } from \"./runtime/recording\"\nimport type { BuilderState, ShortcutRegistry } from \"./runtime/types\"\n\nconst _MODIFIER_KEYS = new Set([\"ctrl\", \"shift\", \"alt\", \"cmd\", \"mod\"])\n\nexport function _createShortcutBuilder(options: UseShortcutOptions = {}): {\n builder: IShortcutBuilder\n registry: ShortcutRegistry\n} {\n const registry: ShortcutRegistry = {\n listeners: new Map(),\n firstStepIndex: new Map(),\n activeSequenceCombos: new Set(),\n options,\n activeScopes: new Set(_normalizeScopes(options.activeScopes)),\n nextId: 1,\n listener: null,\n listenerTarget: null,\n listenerEventType: options.eventType ?? \"keydown\",\n }\n\n _debugLog(options.debug, \"Builder created with options:\", options)\n\n function _createProxy(currentState: BuilderState): IShortcutBuilder {\n return new Proxy({} as IShortcutBuilder, {\n get(_, prop: string) {\n if (prop === \"__debug\") {\n return currentState.options.debug\n }\n\n if (_MODIFIER_KEYS.has(prop)) {\n const platform = detectPlatform()\n const modKey = prop === \"mod\" ? (platform === Platform.MAC ? \"cmd\" : \"ctrl\") : prop\n\n const newState: BuilderState = {\n ...currentState,\n modifiers: { ...currentState.modifiers, [modKey]: true },\n }\n\n _debugLog(currentState.options.debug, `Chain: +${prop} →`, newState.modifiers)\n\n return _createProxy(newState)\n }\n\n if (prop === \"in\") {\n return (scopes: ShortcutScope) => {\n const nextScopes = [..._normalizeScopes(currentState.scopes), ..._normalizeScopes(scopes)]\n const newState: BuilderState = {\n ...currentState,\n scopes: nextScopes,\n }\n\n return _createProxy(newState)\n }\n }\n\n if (prop === \"setScopes\") {\n return (scopes: ShortcutScope) => {\n registry.activeScopes = new Set(_normalizeScopes(scopes))\n }\n }\n\n if (prop === \"enableScope\") {\n return (scope: string) => {\n if (!scope?.trim()) return\n registry.activeScopes.add(scope.trim())\n }\n }\n\n if (prop === \"disableScope\") {\n return (scope: string) => {\n if (!scope?.trim()) return\n registry.activeScopes.delete(scope.trim())\n }\n }\n\n if (prop === \"getScopes\") {\n return () => [...registry.activeScopes]\n }\n\n if (prop === \"isScopeActive\") {\n return (scope: string) => registry.activeScopes.has(scope)\n }\n\n if (prop === \"record\") {\n return _createRecorder(registry.options)\n }\n\n if (prop === \"key\") {\n return (key: ActionKey) => {\n const nextStep = _buildComboString(currentState.modifiers, key)\n const newState: BuilderState = {\n ...currentState,\n modifiers: {},\n steps: [...currentState.steps, nextStep],\n }\n\n _debugLog(currentState.options.debug, `Chain: .key(\"${key}\")`)\n\n return _createProxy(newState)\n }\n }\n\n if (prop === \"then\") {\n return (key: ActionKey | string) => {\n const nextStep = String(key).trim().toLowerCase()\n if (!nextStep) {\n throw new Error(\"[useShortcut] .then() requires a non-empty key or shortcut step.\")\n }\n\n const newState: BuilderState = {\n ...currentState,\n steps: [...currentState.steps, nextStep],\n }\n\n _debugLog(currentState.options.debug, `Chain: .then(\"${nextStep}\")`)\n\n return _createProxy(newState)\n }\n }\n\n if (prop === \"except\") {\n return (condition: ExceptPreset | ExceptPreset[] | ExceptPredicate) => {\n const newState: BuilderState = {\n ...currentState,\n except: condition,\n }\n\n _debugLog(currentState.options.debug, \"Chain: .except()\", condition)\n\n return _createProxy(newState)\n }\n }\n\n if (prop === \"on\") {\n return (handler: ShortcutHandler, handlerOptions?: HandlerOptions) => {\n return _createBinding(currentState, handler, handlerOptions, registry)\n }\n }\n\n if (prop === \"handle\") {\n return (opts: HandlerOptions & { handler: ShortcutHandler }) => {\n const { handler, ...rest } = opts\n return _createBinding(currentState, handler, rest, registry)\n }\n }\n\n return undefined\n },\n })\n }\n\n const initialState: BuilderState = {\n modifiers: {},\n steps: [],\n options,\n }\n\n return {\n builder: _createProxy(initialState),\n registry,\n }\n}\n","\"use client\"\n\nimport { useEffect, useRef, useMemo } from \"react\"\nimport { _createShortcutBuilder } from \"./builder\"\nimport type {\n ShortcutBuilder,\n UseShortcutOptions,\n ShortcutMap,\n ShortcutMapResult,\n ShortcutMapEntry,\n ShortcutGroup,\n ShortcutResult,\n ShortcutHandler,\n HandlerOptions,\n ActionKey,\n} from \"./types\"\n\ntype ShortcutMapSequenceChain = {\n then: (step: string) => ShortcutMapSequenceChain\n on: (handler: ShortcutHandler, options?: HandlerOptions) => ShortcutResult\n}\n\ntype ShortcutMapChain = {\n ctrl: ShortcutMapChain\n shift: ShortcutMapChain\n alt: ShortcutMapChain\n cmd: ShortcutMapChain\n mod: ShortcutMapChain\n key: (key: ActionKey) => ShortcutMapSequenceChain\n}\n\nfunction _areShortcutMapKeysEqual(a: ShortcutMapEntry[\"keys\"], b: ShortcutMapEntry[\"keys\"]): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false\n }\n return true\n }\n\n if (!Array.isArray(a) && !Array.isArray(b)) {\n return a === b\n }\n\n return false\n}\n\nfunction _areShortcutMapsEquivalent(a: ShortcutMap, b: ShortcutMap): boolean {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n if (aKeys.length !== bKeys.length) return false\n\n for (const key of aKeys) {\n const aEntry = a[key]\n const bEntry = b[key]\n if (!bEntry) return false\n if (!_areShortcutMapKeysEqual(aEntry.keys, bEntry.keys)) return false\n if (aEntry.handler !== bEntry.handler) return false\n if (aEntry.options !== bEntry.options) return false\n }\n\n return true\n}\n\nfunction _normalizeShortcutMapKeys(keys: ShortcutMapEntry[\"keys\"]): string[] {\n if (Array.isArray(keys)) {\n return keys.map((key) => key.trim()).filter(Boolean)\n }\n\n const trimmed = keys.trim()\n if (!trimmed) return []\n\n if (trimmed.includes(\" then \")) {\n return trimmed.split(/\\s+then\\s+/i).map((key) => key.trim()).filter(Boolean)\n }\n\n if (trimmed.includes(\" \") && !trimmed.includes(\"+\")) {\n return trimmed.split(/\\s+/).map((key) => key.trim()).filter(Boolean)\n }\n\n return [trimmed]\n}\n\nfunction _applyStep(builder: ShortcutMapChain, step: string): ShortcutMapSequenceChain {\n const tokens = step\n .toLowerCase()\n .split(\"+\")\n .map((token) => token.trim())\n .filter(Boolean)\n\n if (tokens.length === 0) {\n throw new Error(\"[useShortcutMap] Invalid step: empty shortcut step\")\n }\n\n const key = tokens.pop()!\n let chain = builder\n\n for (const token of tokens) {\n if (token === \"ctrl\" || token === \"control\") {\n chain = chain.ctrl\n continue\n }\n\n if (token === \"shift\") {\n chain = chain.shift\n continue\n }\n\n if (token === \"alt\" || token === \"option\") {\n chain = chain.alt\n continue\n }\n\n if (token === \"cmd\" || token === \"command\" || token === \"meta\") {\n chain = chain.cmd\n continue\n }\n\n if (token === \"mod\") {\n chain = chain.mod\n continue\n }\n\n throw new Error(`[useShortcutMap] Unsupported modifier token \"${token}\" in step \"${step}\"`)\n }\n\n return chain.key(key as ActionKey)\n}\n\n/**\n * Registers an object-based shortcut map in one call and returns per-action handles.\n *\n * @param builder - Builder returned by `useShortcut()`\n * @param shortcutMap - Record of action ids to key bindings, handlers, and options\n * @returns A result map with one `ShortcutResult` per shortcut id\n *\n * @example\n * ```ts\n * const $ = useShortcut()\n * const results = registerShortcutMap($, {\n * save: { keys: \"mod+s\", handler: onSave },\n * nav: { keys: [\"g\", \"d\"], handler: onGoDashboard },\n * })\n * ```\n */\nexport function registerShortcutMap<T extends ShortcutMap>(\n builder: ShortcutBuilder,\n shortcutMap: T,\n): ShortcutMapResult<T> {\n const results = {} as ShortcutMapResult<T>\n\n for (const id of Object.keys(shortcutMap) as Array<keyof T>) {\n const entry = shortcutMap[id]\n const steps = _normalizeShortcutMapKeys(entry.keys)\n\n if (steps.length === 0) {\n throw new Error(`[useShortcutMap] Shortcut \"${String(id)}\" has no key steps`)\n }\n\n let chain = _applyStep(builder, steps[0])\n\n for (const step of steps.slice(1)) {\n chain = chain.then(step)\n }\n\n results[id] = chain.on(entry.handler, entry.options)\n }\n\n return results\n}\n\n/**\n * React hook for registering chainable keyboard shortcuts\n *\n * @param options - Configuration options for the hook\n * @returns A chainable shortcut builder (`$`)\n *\n * @example\n * ```ts\n * const $ = useShortcut({ activeScopes: [\"editor\"] })\n * $.mod.key(\"s\").on((event) => {\n * event.preventDefault()\n * saveDocument()\n * })\n * ```\n */\nexport function useShortcut(options: UseShortcutOptions = {}): ShortcutBuilder {\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n const { builder, registry } = useMemo(() => {\n return _createShortcutBuilder(optionsRef.current)\n }, [])\n\n useEffect(() => {\n registry.options = optionsRef.current\n\n if (optionsRef.current.activeScopes !== undefined) {\n const scopes = Array.isArray(optionsRef.current.activeScopes)\n ? optionsRef.current.activeScopes\n : [optionsRef.current.activeScopes]\n\n registry.activeScopes = new Set(scopes.map((scope) => scope.trim()).filter(Boolean))\n }\n }, [registry, options])\n\n useEffect(() => {\n return () => {\n registry.listeners.clear()\n registry.firstStepIndex.clear()\n registry.activeSequenceCombos.clear()\n\n if (registry.listener && registry.listenerTarget) {\n registry.listenerTarget.removeEventListener(registry.listenerEventType, registry.listener as EventListener)\n registry.listener = null\n registry.listenerTarget = null\n }\n }\n }, [registry])\n\n return builder as ShortcutBuilder\n}\n\n/**\n * React hook that registers a shortcut map and automatically unbinds on cleanup.\n *\n * @param shortcutMap - Record of action ids to key bindings, handlers, and options\n * @param options - Same options as `useShortcut()`\n * @returns A map of `ShortcutResult` keyed by your shortcut ids\n *\n * @example\n * ```ts\n * const mapResults = useShortcutMap({\n * save: { keys: \"mod+s\", handler: onSave },\n * close: { keys: \"escape\", handler: onClose },\n * })\n * ```\n */\nexport function useShortcutMap<T extends ShortcutMap>(\n shortcutMap: T,\n options: UseShortcutOptions = {},\n): ShortcutMapResult<T> {\n const $ = useShortcut(options)\n const stableShortcutMapRef = useRef(shortcutMap)\n if (!_areShortcutMapsEquivalent(stableShortcutMapRef.current, shortcutMap)) {\n stableShortcutMapRef.current = shortcutMap\n }\n\n const stableShortcutMap = stableShortcutMapRef.current\n const resultsRef = useRef<ShortcutMapResult<T>>({} as ShortcutMapResult<T>)\n\n useEffect(() => {\n const registrations = registerShortcutMap($, stableShortcutMap)\n const results = resultsRef.current\n for (const key of Object.keys(results)) {\n delete (results as Record<string, unknown>)[key]\n }\n Object.assign(results, registrations)\n\n return () => {\n for (const result of Object.values(registrations)) {\n result.unbind()\n }\n for (const key of Object.keys(results)) {\n delete (results as Record<string, unknown>)[key]\n }\n }\n }, [$, stableShortcutMap])\n\n return resultsRef.current\n}\n\n/**\n * Creates an imperative group controller for many shortcut registrations.\n *\n * @returns A `ShortcutGroup` that can add and unbind multiple shortcuts together\n *\n * @example\n * ```ts\n * const group = createShortcutGroup()\n * group.add($.mod.key(\"s\").on(onSave))\n * group.add($.key(\"escape\").on(onClose))\n * group.unbindAll()\n * ```\n */\nexport function createShortcutGroup(): ShortcutGroup {\n const results: ShortcutResult[] = []\n\n return {\n add: (...entries: ShortcutResult[]) => {\n results.push(...entries)\n },\n addMany: (entries: ShortcutResult[] | Record<string, ShortcutResult>) => {\n if (Array.isArray(entries)) {\n results.push(...entries)\n return\n }\n\n results.push(...Object.values(entries))\n },\n unbindAll: () => {\n for (const entry of results) {\n entry.unbind()\n }\n results.length = 0\n },\n clear: () => {\n results.length = 0\n },\n getResults: () => [...results],\n }\n}\n\n/**\n * React hook that returns a stable `ShortcutGroup` instance.\n *\n * @returns A memoized `ShortcutGroup` tied to the component lifecycle\n *\n * @example\n * ```ts\n * const group = useShortcutGroup()\n * ```\n */\nexport function useShortcutGroup(): ShortcutGroup {\n const groupRef = useRef<ShortcutGroup | null>(null)\n\n if (!groupRef.current) {\n groupRef.current = createShortcutGroup()\n }\n\n return groupRef.current\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remcostoeten/use-shortcut",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Beautiful, intuitive, chainable syntax for executing keyboard shortcuts in React and Next.js with perfect TypeScript IntelliSense.",
|
|
5
5
|
"author": "Remco Stoeten",
|
|
6
6
|
"license": "MIT",
|
|
@@ -59,6 +59,8 @@
|
|
|
59
59
|
"dev": "tsup --watch",
|
|
60
60
|
"test": "vitest run --environment jsdom",
|
|
61
61
|
"typecheck": "tsc --noEmit",
|
|
62
|
+
"docs:api": "node scripts/generate-api-reference.mjs",
|
|
63
|
+
"docs:check": "bun run docs:api && node scripts/docs-check.mjs",
|
|
62
64
|
"clean": "rm -rf dist",
|
|
63
65
|
"prepublishOnly": "npm run build"
|
|
64
66
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from "vitest"
|
|
2
|
-
import {
|
|
2
|
+
import { _createShortcutBuilder } from "../builder"
|
|
3
|
+
import { registerShortcutMap, createShortcutGroup } from "../hook"
|
|
4
|
+
import type { ShortcutBuilder, UseShortcutOptions } from "../types"
|
|
3
5
|
|
|
4
6
|
function dispatchKey(key: string, options: KeyboardEventInit = {}) {
|
|
5
7
|
window.dispatchEvent(
|
|
@@ -12,13 +14,22 @@ function dispatchKey(key: string, options: KeyboardEventInit = {}) {
|
|
|
12
14
|
)
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
function createTestShortcut(options: UseShortcutOptions = {}): ShortcutBuilder {
|
|
18
|
+
const { builder } = _createShortcutBuilder({
|
|
19
|
+
target: window,
|
|
20
|
+
...options,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
return builder as ShortcutBuilder
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
describe("advanced shortcut features", () => {
|
|
16
27
|
beforeEach(() => {
|
|
17
28
|
document.body.innerHTML = ""
|
|
18
29
|
})
|
|
19
30
|
|
|
20
31
|
it("supports multi-key sequences with .then()", () => {
|
|
21
|
-
const $ =
|
|
32
|
+
const $ = createTestShortcut({ ignoreInputs: false })
|
|
22
33
|
const handler = vi.fn()
|
|
23
34
|
|
|
24
35
|
$.key("g").then("d").on(handler)
|
|
@@ -31,7 +42,7 @@ describe("advanced shortcut features", () => {
|
|
|
31
42
|
})
|
|
32
43
|
|
|
33
44
|
it("supports named scopes with runtime activation", () => {
|
|
34
|
-
const $ =
|
|
45
|
+
const $ = createTestShortcut({ ignoreInputs: false, activeScopes: "navigation" })
|
|
35
46
|
const handler = vi.fn()
|
|
36
47
|
|
|
37
48
|
$.in("editor").mod.key("s").on(handler)
|
|
@@ -46,7 +57,7 @@ describe("advanced shortcut features", () => {
|
|
|
46
57
|
|
|
47
58
|
it("reports sequence overlap conflicts", () => {
|
|
48
59
|
const onConflict = vi.fn()
|
|
49
|
-
const $ =
|
|
60
|
+
const $ = createTestShortcut({ ignoreInputs: false, onConflict })
|
|
50
61
|
|
|
51
62
|
$.key("g").on(() => {})
|
|
52
63
|
$.key("g").then("d").on(() => {})
|
|
@@ -55,16 +66,17 @@ describe("advanced shortcut features", () => {
|
|
|
55
66
|
expect(onConflict.mock.calls[0][0].reason).toBe("sequence-prefix")
|
|
56
67
|
})
|
|
57
68
|
|
|
58
|
-
it("registers shortcuts in bulk with
|
|
69
|
+
it("registers shortcuts in bulk with registerShortcutMap", () => {
|
|
59
70
|
const save = vi.fn()
|
|
60
71
|
const undo = vi.fn()
|
|
72
|
+
const $ = createTestShortcut({ ignoreInputs: false })
|
|
61
73
|
|
|
62
|
-
|
|
74
|
+
registerShortcutMap(
|
|
75
|
+
$,
|
|
63
76
|
{
|
|
64
77
|
save: { keys: "mod+s", handler: save },
|
|
65
78
|
undo: { keys: "mod+z", handler: undo },
|
|
66
79
|
},
|
|
67
|
-
{ target: window, ignoreInputs: false },
|
|
68
80
|
)
|
|
69
81
|
|
|
70
82
|
dispatchKey("s", { ctrlKey: true })
|
|
@@ -75,7 +87,7 @@ describe("advanced shortcut features", () => {
|
|
|
75
87
|
})
|
|
76
88
|
|
|
77
89
|
it("records the next key combo", async () => {
|
|
78
|
-
const $ =
|
|
90
|
+
const $ = createTestShortcut()
|
|
79
91
|
|
|
80
92
|
const recordPromise = $.record({ timeoutMs: 1000 })
|
|
81
93
|
dispatchKey("k", { ctrlKey: true })
|
|
@@ -83,8 +95,28 @@ describe("advanced shortcut features", () => {
|
|
|
83
95
|
await expect(recordPromise).resolves.toBe("ctrl+k")
|
|
84
96
|
})
|
|
85
97
|
|
|
98
|
+
it("records space key combos as parseable tokens", async () => {
|
|
99
|
+
const $ = createTestShortcut()
|
|
100
|
+
|
|
101
|
+
const recordPromise = $.record({ timeoutMs: 1000 })
|
|
102
|
+
dispatchKey(" ", { ctrlKey: true })
|
|
103
|
+
|
|
104
|
+
await expect(recordPromise).resolves.toBe("ctrl+space")
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it("matches ctrl+space shortcuts", () => {
|
|
108
|
+
const $ = createTestShortcut({ ignoreInputs: false })
|
|
109
|
+
const handler = vi.fn()
|
|
110
|
+
|
|
111
|
+
$.mod.key("space").on(handler)
|
|
112
|
+
|
|
113
|
+
dispatchKey(" ", { ctrlKey: true })
|
|
114
|
+
|
|
115
|
+
expect(handler).toHaveBeenCalledTimes(1)
|
|
116
|
+
})
|
|
117
|
+
|
|
86
118
|
it("respects priority and stopOnMatch for overlapping combos", () => {
|
|
87
|
-
const $ =
|
|
119
|
+
const $ = createTestShortcut({ ignoreInputs: false })
|
|
88
120
|
const primary = vi.fn()
|
|
89
121
|
const secondary = vi.fn()
|
|
90
122
|
|
|
@@ -99,8 +131,7 @@ describe("advanced shortcut features", () => {
|
|
|
99
131
|
|
|
100
132
|
it("applies global eventFilter before handlers", () => {
|
|
101
133
|
const handler = vi.fn()
|
|
102
|
-
const $ =
|
|
103
|
-
target: window,
|
|
134
|
+
const $ = createTestShortcut({
|
|
104
135
|
ignoreInputs: false,
|
|
105
136
|
eventFilter: (event) => event.key !== "x",
|
|
106
137
|
})
|
|
@@ -115,7 +146,7 @@ describe("advanced shortcut features", () => {
|
|
|
115
146
|
})
|
|
116
147
|
|
|
117
148
|
it("supports shortcut groups for cleanup", () => {
|
|
118
|
-
const $ =
|
|
149
|
+
const $ = createTestShortcut({ ignoreInputs: false })
|
|
119
150
|
const group = createShortcutGroup()
|
|
120
151
|
const handler = vi.fn()
|
|
121
152
|
|