{"version":3,"file":"menu.cjs","names":[],"sources":["../src/overlay/menu/menu.ts"],"sourcesContent":["import { restoreFocus } from '@vielzeug/focus';\nimport type { Placement } from '@vielzeug/orbit';\nimport {\n  bind,\n  createStableId,\n  define,\n  getHost,\n  html,\n  onCleanup,\n  onMounted,\n  prop,\n  useEmit,\n  useSlots,\n  watchEffect,\n} from '@vielzeug/ore';\nimport { computed, watch as rippleWatch, signal } from '@vielzeug/ripple';\nimport {\n  createDropdownPositioner,\n  createInteraction,\n  createListControl,\n  createOutsidePointerDismissal,\n  type DropdownCloseReason,\n  lifecycleSignal,\n  type OverlayOpenChangeDetail,\n  type OverlayOpenReason,\n} from '../../core';\nimport { disablableBundle, MENU_SIZE_PRESET, sizableBundle } from '../../shared';\nimport { colorThemeMixin, forcedColorsMixin, sizeVariantMixin } from '../../styles';\nimport type { ComponentSize } from '../../types';\nimport componentStyles from './menu.css?inline';\nimport menuItemStyles from './menu-item.css?inline';\nimport menuSeparatorStyles from './menu-separator.css?inline';\n\n// ── Types ─────────────────────────────────────────────────────────────\n\nexport interface MenuSelectDetail {\n  checked?: boolean;\n  value: string;\n}\n\nexport type OreMenuItemType = 'checkbox' | 'radio';\n\nexport type OreMenuEvents = {\n  'open-change': OverlayOpenChangeDetail;\n  select: MenuSelectDetail;\n};\n\nexport type OreMenuItemProps = {\n  checked?: boolean;\n  disabled?: boolean;\n  type?: OreMenuItemType;\n  value?: string;\n};\n\nexport type OreMenuProps = {\n  /** Initial uncontrolled open state. Ignored when `open` is set. */\n  'default-open'?: boolean;\n  disabled?: boolean;\n  /** Controlled open state. */\n  open?: boolean;\n  placement?: 'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end';\n  size?: ComponentSize;\n};\n\n// ── Styles ─────────────────────────────────────────────────────────────\n\n// ── Menu Item Component ─────────────────────────────────────────────────────────────\n\n/**\n * A selectable action item used inside `<ore-menu>`.\n *\n * @element ore-menu-item\n *\n * @attr {boolean} checked - Checked state for `checkbox` and `radio` item types\n * @attr {boolean} disabled - Disables selection and pointer interaction\n * @attr {'checkbox'|'radio'} type - Optional checkable menu item mode\n * @attr {string} value - Value emitted by parent menu on selection\n *\n * @slot - Item label/content\n * @slot icon - Optional leading icon content\n *\n * @cssprop --menu-item-hover-bg - Background on hover\n * @cssprop --menu-item-focus-color - Text color when keyboard-focused\n * @cssprop --menu-item-focus-bg - Background when keyboard-focused\n * @cssprop --menu-item-selection-bg - Background for checkbox/radio items (unselected)\n * @cssprop --menu-item-checked-color - Text color when checked\n * @cssprop --menu-item-checked-bg - Background when checked\n *\n * @part item - Root item container element.\n * @part item-label - Label text container.\n * @part icon-slot - Leading icon slot container.\n *\n * @example\n * ```html\n * <ore-menu-item value=\"edit\">Edit</ore-menu-item>\n * <ore-menu-item value=\"delete\" disabled>Delete</ore-menu-item>\n * <ore-menu-item type=\"checkbox\" value=\"wrap\" checked>Word wrap</ore-menu-item>\n * <ore-menu-item type=\"radio\" value=\"left\">Align left</ore-menu-item>\n * ```\n */\nexport const MENU_ITEM_TAG = 'ore-menu-item' as const;\ndefine<OreMenuItemProps>(MENU_ITEM_TAG, {\n  props: {\n    checked: prop.bool(false),\n    disabled: prop.bool(false),\n    type: prop.string<OreMenuItemType>(),\n    value: prop.string(),\n  },\n  setup(props) {\n    const isCheckable = () => props.type.value === 'checkbox' || props.type.value === 'radio';\n    const isChecked = () => isCheckable() && props.checked.value;\n    const itemRole = () => {\n      if (props.type.value === 'checkbox') return 'menuitemcheckbox';\n\n      if (props.type.value === 'radio') return 'menuitemradio';\n\n      return 'menuitem';\n    };\n    const itemClass = () => {\n      const type = props.type.value;\n\n      return [\n        'item',\n        type === 'checkbox' ? 'is-checkbox' : '',\n        type === 'radio' ? 'is-radio' : '',\n        isChecked() ? 'is-checked' : '',\n      ]\n        .filter(Boolean)\n        .join(' ');\n    };\n\n    return isCheckable()\n      ? html`\n          <div\n            class=\"${itemClass}\"\n            tabindex=\"-1\"\n            role=\"${itemRole}\"\n            aria-checked=\"${() => String(isChecked())}\"\n            aria-disabled=\"${props.disabled}\">\n            <span class=\"item-check\" aria-hidden=\"true\"></span>\n            <span class=\"icon-slot\"><slot name=\"icon\"></slot></span>\n            <span class=\"item-label\"><slot></slot></span>\n          </div>\n        `\n      : html`\n          <div class=\"item\" tabindex=\"-1\" role=\"menuitem\" aria-disabled=\"${props.disabled}\">\n            <span class=\"icon-slot\"><slot name=\"icon\"></slot></span>\n            <span class=\"item-label\"><slot></slot></span>\n          </div>\n        `;\n  },\n  styles: [colorThemeMixin, menuItemStyles],\n});\n\n// ── Menu Separator ─────────────────────────────────────────────────────────────\n\n/**\n * Visual separator used to group menu items inside `<ore-menu>`.\n *\n * @element ore-menu-separator\n *\n * @example\n * ```html\n * <ore-menu-item value=\"cut\">Cut</ore-menu-item>\n * <ore-menu-separator></ore-menu-separator>\n * <ore-menu-item value=\"paste\">Paste</ore-menu-item>\n * ```\n */\nexport const SEPARATOR_TAG = 'ore-menu-separator' as const;\ndefine(SEPARATOR_TAG, {\n  setup() {\n    return html``;\n  },\n  styles: [menuSeparatorStyles],\n});\n\n// ── Menu Component ─────────────────────────────────────────────────────────────\n\nconst isCheckableItemType = (value: string | null): value is OreMenuItemType =>\n  value === 'checkbox' || value === 'radio';\n\nconst parseOptionalBool = (value: string | null): boolean | undefined =>\n  value == null ? undefined : value === '' || value === 'true';\n\n/**\n * Action dropdown menu triggered by a slotted trigger element.\n *\n * @element ore-menu\n * @element ore-menu-item - Clickable menu option (place in default slot)\n * @element ore-menu-separator - Visual divider between menu groups\n *\n * @attr {boolean} disabled - Disables opening and keyboard interaction\n * @attr {boolean} open - Controlled open state\n * @attr {boolean} default-open - Initial uncontrolled open state\n * @attr {string} placement - Panel placement: 'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end' (default: 'bottom-start')\n * @attr {string} size - Size: 'sm' | 'md' | 'lg'\n *\n * @fires open-change - Fired when the menu state changes. detail: { open, reason }\n * @fires select - Fired when an item is selected. detail: { value: string, checked?: boolean }\n *\n * @slot trigger - Trigger element that toggles menu visibility\n * @slot - Menu content (`<ore-menu-item>` and `<ore-menu-separator>`)\n *\n * @part panel - Floating menu panel container\n *\n * @cssprop --menu-panel-bg - Background of the floating panel\n * @cssprop --menu-panel-border-color - Border color of the floating panel\n * @cssprop --menu-panel-shadow - Box shadow of the floating panel\n * @cssprop --menu-panel-blur - Backdrop blur amount for the floating panel\n * @cssprop --menu-panel-min-width - Minimum width of the floating panel\n * @cssprop --menu-panel-max-height - Maximum height of the floating panel before it scrolls\n * @cssprop --menu-panel-radius - Border radius of the floating panel\n *\n * @example\n * ```html\n * <ore-menu>\n *   <button slot=\"trigger\">Actions</button>\n *   <ore-menu-item value=\"edit\">Edit</ore-menu-item>\n *   <ore-menu-item value=\"delete\">Delete</ore-menu-item>\n * </ore-menu>\n * ```\n */\nexport const MENU_TAG = 'ore-menu' as const;\ndefine<OreMenuProps>(MENU_TAG, {\n  props: {\n    ...sizableBundle,\n    ...disablableBundle,\n    'default-open': prop.bool(false),\n    open: { default: undefined as boolean | undefined, parse: parseOptionalBool },\n    placement: prop.oneOf(\n      ['bottom', 'bottom-start', 'bottom-end', 'top', 'top-start', 'top-end'] as const,\n      'bottom-start',\n    ),\n  },\n  setup(props) {\n    const el = getHost();\n    const emit = useEmit<OreMenuEvents>();\n    const slots = useSlots();\n    const watch = watchEffect;\n\n    const menuId = createStableId('menu');\n    const isDisabled = computed(() => Boolean(props.disabled.value));\n    const abortSignal = lifecycleSignal(onCleanup);\n    let triggerEl: HTMLElement | null = null;\n    let panelEl: HTMLElement | null = null;\n    let cleanupTrigger: (() => void) | null = null;\n\n    // ── Helpers ───────────────────────────────────────────────────────────────\n    function getItems(): HTMLElement[] {\n      return Array.from(el.querySelectorAll<HTMLElement>('ore-menu-item:not([disabled])'));\n    }\n\n    function getItemFocusable(item: HTMLElement | null | undefined): HTMLElement | null {\n      if (!item) return null;\n\n      return item.shadowRoot?.querySelector<HTMLElement>('[role^=\"menuitem\"]') ?? item;\n    }\n\n    function getFocusedItemIndex(): number {\n      const items = getItems();\n\n      return items.findIndex((item) => {\n        const focusable = getItemFocusable(item);\n\n        return item === document.activeElement || focusable === document.activeElement;\n      });\n    }\n\n    const isOpenSignal = signal(false);\n    let stopPositioning: (() => void) | null = null;\n    const positioner = createDropdownPositioner({\n      getFloating: () => panelEl,\n      getPlacement: () => (props.placement.value ?? 'bottom-start') as Placement,\n      getReference: () => triggerEl,\n      matchWidth: false,\n      offsetPx: 4,\n      padding: 6,\n    });\n    const list = createListControl<HTMLElement>({\n      disabled: computed(() => !isOpenSignal.value),\n      getItems: getItems,\n      isItemDisabled: (item) => item.hasAttribute('disabled'),\n      onNavigate: ({ item }) => {\n        getItemFocusable(item)?.focus();\n      },\n      signal: abortSignal,\n    });\n\n    const close = (reason: DropdownCloseReason = 'programmatic', shouldRestoreFocus = true): void => {\n      if (!isOpenSignal.value) return;\n\n      isOpenSignal.value = false;\n      list.reset();\n      stopPositioning?.();\n      stopPositioning = null;\n\n      if (shouldRestoreFocus) restoreFocus(() => triggerEl);\n\n      emit('open-change', { open: false, reason });\n    };\n\n    const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n      if (isDisabled.value || isOpenSignal.value) return;\n\n      isOpenSignal.value = true;\n      positioner.update();\n      stopPositioning = positioner.startAutoUpdate?.() ?? null;\n      emit('open-change', { open: true, reason });\n    };\n\n    const toggle = (): void => {\n      if (isOpenSignal.value) close('trigger');\n      else open('click');\n    };\n\n    createOutsidePointerDismissal({\n      getTargets: () => [el, panelEl],\n      isActive: () => isOpenSignal.value,\n      onDismiss: () => close('outsideClick'),\n      signal: abortSignal,\n    });\n\n    let initialized = false;\n\n    rippleWatch(\n      props.open,\n      (value) => {\n        if (value === undefined) {\n          if (!initialized) {\n            if (props['default-open'].value) open('programmatic');\n          } else {\n            close('programmatic');\n          }\n        } else if (value) {\n          open('programmatic');\n        } else {\n          close('programmatic');\n        }\n\n        initialized = true;\n      },\n      { immediate: true },\n    );\n    abortSignal.addEventListener(\n      'abort',\n      () => {\n        if (!isOpenSignal.value) return;\n\n        isOpenSignal.value = false;\n        list.reset();\n        stopPositioning?.();\n        stopPositioning = null;\n      },\n      { once: true },\n    );\n\n    const activateItem = (item: HTMLElement): void => {\n      const type = item.getAttribute('type');\n      const isCheckable = isCheckableItemType(type);\n\n      if (type === 'checkbox') {\n        item.toggleAttribute('checked', !item.hasAttribute('checked'));\n      } else if (type === 'radio') {\n        for (const radio of el.querySelectorAll<HTMLElement>('ore-menu-item[type=\"radio\"]')) {\n          radio.toggleAttribute('checked', radio === item);\n        }\n      }\n\n      const value = item.getAttribute('value') ?? '';\n      const checked = isCheckable ? item.hasAttribute('checked') : undefined;\n\n      emit('select', { checked, value });\n\n      if (!isCheckable) {\n        close('programmatic');\n      }\n    };\n\n    const openFromKeyboardPress = createInteraction({\n      keys: ['Enter', ' ', 'ArrowDown'],\n      onPress: () => {\n        open('keyboard');\n        requestAnimationFrame(() => list.set(0));\n      },\n    });\n\n    const activateFocusedFromKeyboardPress = createInteraction({\n      onPress: () => {\n        const focused = list.getActiveItem();\n\n        if (focused) activateItem(focused);\n      },\n    });\n\n    // ── Keyboard Navigation ───────────────────────────────────────────────────\n    function handleMenuKeydown(e: KeyboardEvent) {\n      if (isDisabled.value) return;\n\n      const open = isOpenSignal.value;\n\n      // When closed: open on Enter / Space / ArrowDown\n      if (!open) {\n        openFromKeyboardPress.handleKeydown(e);\n\n        return;\n      }\n\n      const currentFocusedIndex = getFocusedItemIndex();\n\n      if (currentFocusedIndex >= 0) list.set(currentFocusedIndex);\n\n      if (e.key === 'Escape') {\n        e.preventDefault();\n        close('escape');\n\n        return;\n      }\n\n      if (list.handleKeydown(e)) return;\n\n      // When open: navigate and activate\n      if (e.key === ' ' || e.key === 'Enter') {\n        activateFocusedFromKeyboardPress.handleKeydown(e);\n\n        return;\n      }\n\n      if (e.key === 'Tab') {\n        close('programmatic');\n      }\n    }\n\n    // ── Lifecycle ─────────────────────────────────────────────────────────────\n    bind({\n      on: {\n        click: (e: MouseEvent) => {\n          const path = e.composedPath();\n\n          if (!isOpenSignal.value) return;\n\n          const itemFromPath = path.find(\n            (node): node is HTMLElement => node instanceof HTMLElement && node.tagName === 'ORE-MENU-ITEM',\n          );\n          const item = itemFromPath ?? (e.target as HTMLElement | null)?.closest<HTMLElement>('ore-menu-item') ?? null;\n\n          if (!item || item.hasAttribute('disabled')) return;\n\n          activateItem(item);\n        },\n      },\n    });\n\n    watch(() => {\n      const open = isOpenSignal.value;\n\n      if (!panelEl) return;\n\n      panelEl.toggleAttribute('data-open', open);\n    });\n\n    function resolveTrigger() {\n      cleanupTrigger?.();\n      cleanupTrigger = null;\n\n      const assigned = slots.elements('trigger').value;\n\n      triggerEl = (assigned?.[0] as HTMLElement | undefined) ?? null;\n\n      if (!triggerEl) return;\n\n      const cleanups: Array<() => void> = [];\n      const removeAria = bind(\n        {\n          aria: {\n            controls: () => menuId,\n            disabled: () => isDisabled.value,\n            expanded: () => String(isOpenSignal.value),\n            haspopup: 'menu',\n          },\n        },\n        { target: triggerEl },\n      );\n\n      const onTriggerClick = (event: MouseEvent) => {\n        event.stopPropagation();\n\n        if (isDisabled.value) return;\n\n        toggle();\n      };\n      const onTriggerKeydown = (event: KeyboardEvent) => {\n        handleMenuKeydown(event);\n      };\n\n      triggerEl.addEventListener('click', onTriggerClick);\n      triggerEl.addEventListener('keydown', onTriggerKeydown);\n      cleanups.push(() => triggerEl?.removeEventListener('click', onTriggerClick));\n      cleanups.push(() => triggerEl?.removeEventListener('keydown', onTriggerKeydown));\n\n      cleanupTrigger = () => {\n        removeAria();\n\n        for (const cleanup of cleanups) cleanup();\n      };\n    }\n\n    rippleWatch(slots.elements('trigger'), resolveTrigger, { immediate: true });\n\n    onMounted(() => {\n      resolveTrigger();\n\n      return () => {\n        cleanupTrigger?.();\n        cleanupTrigger = null;\n      };\n    });\n\n    return html`\n      <slot name=\"trigger\"></slot>\n      <div\n        class=\"menu-panel\"\n        part=\"panel\"\n        id=\"${menuId}\"\n        role=\"menu\"\n        aria-orientation=\"vertical\"\n        @keydown=\"${handleMenuKeydown}\"\n        ref=\"${(el: HTMLElement | null) => {\n          panelEl = el;\n          panelEl?.toggleAttribute('data-open', isOpenSignal.value);\n        }}\">\n        <slot></slot>\n      </div>\n    `;\n  },\n  styles: [componentStyles, sizeVariantMixin(MENU_SIZE_PRESET), forcedColorsMixin],\n});\n"],"mappings":"6mBAoGA,IAAa,EAAgB,iBAC7B,EAAA,EAAA,OAAA,CAAyB,EAAe,CACtC,MAAO,CACL,QAAS,EAAA,KAAK,KAAK,EAAK,EACxB,SAAU,EAAA,KAAK,KAAK,EAAK,EACzB,KAAM,EAAA,KAAK,OAAwB,EACnC,MAAO,EAAA,KAAK,OAAO,CACrB,EACA,MAAM,EAAO,CACX,IAAM,MAAoB,EAAM,KAAK,QAAU,YAAc,EAAM,KAAK,QAAU,QAC5E,MAAkB,EAAY,GAAK,EAAM,QAAQ,MAqBvD,OAAO,EAAY,EACf,EAAA,IAAI;;yBAdgB,CACtB,IAAM,EAAO,EAAM,KAAK,MAExB,MAAO,CACL,OACA,IAAS,WAAa,cAAgB,GACtC,IAAS,QAAU,WAAa,GAChC,EAAU,EAAI,aAAe,EAC/B,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,CACb,EAK2B;;wBAtBrB,EAAM,KAAK,QAAU,WAAmB,mBAExC,EAAM,KAAK,QAAU,QAAgB,gBAElC,WAoBgB;gCACK,OAAO,EAAU,CAAC,EAAE;6BACzB,EAAM,SAAS;;;;;UAMpC,EAAA,IAAI;2EAC+D,EAAM,SAAS;;;;SAKxF,EACA,OAAQ,CAAC,EAAA,gBAAiB,EAAA,OAAc,CAC1C,CAAC,EAgBD,IAAa,EAAgB,sBAC7B,EAAA,EAAA,OAAA,CAAO,EAAe,CACpB,OAAQ,CACN,MAAO,GAAA,IAAI,EACb,EACA,OAAQ,CAAC,EAAA,OAAmB,CAC9B,CAAC,EAID,IAAM,EAAuB,GAC3B,IAAU,YAAc,IAAU,QAE9B,EAAqB,GACzB,GAAS,KAAO,IAAA,GAAY,IAAU,IAAM,IAAU,OAwC3C,EAAW,YACxB,EAAA,EAAA,OAAA,CAAqB,EAAU,CAC7B,MAAO,CACL,GAAG,EAAA,cACH,GAAG,EAAA,iBACH,eAAgB,EAAA,KAAK,KAAK,EAAK,EAC/B,KAAM,CAAE,QAAS,IAAA,GAAkC,MAAO,CAAkB,EAC5E,UAAW,EAAA,KAAK,MACd,CAAC,SAAU,eAAgB,aAAc,MAAO,YAAa,SAAS,EACtE,cACF,CACF,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EACb,GAAA,EAAO,EAAA,QAAA,CAAuB,EAC9B,GAAA,EAAQ,EAAA,SAAA,CAAS,EACjB,EAAQ,EAAA,YAER,GAAA,EAAS,EAAA,eAAA,CAAe,MAAM,EAC9B,GAAA,EAAa,EAAA,SAAA,KAAe,EAAQ,EAAM,SAAS,KAAM,EACzD,EAAc,EAAA,gBAAgB,EAAA,SAAS,EACzC,EAAgC,KAChC,EAA8B,KAC9B,EAAsC,KAG1C,SAAS,GAA0B,CACjC,OAAO,MAAM,KAAK,EAAG,iBAA8B,+BAA+B,CAAC,CACrF,CAEA,SAAS,EAAiB,EAA0D,CAGlF,OAFK,EAEE,EAAK,YAAY,cAA2B,oBAAoB,GAAK,EAF1D,IAGpB,CAEA,SAAS,GAA8B,CAGrC,OAFc,EAEP,CAAA,CAAM,UAAW,GAAS,CAC/B,IAAM,EAAY,EAAiB,CAAI,EAEvC,OAAO,IAAS,SAAS,eAAiB,IAAc,SAAS,aACnE,CAAC,CACH,CAEA,IAAM,GAAA,EAAe,EAAA,OAAA,CAAO,EAAK,EAC7B,EAAuC,KACrC,EAAa,EAAA,yBAAyB,CAC1C,gBAAmB,EACnB,iBAAqB,EAAM,UAAU,OAAS,eAC9C,iBAAoB,EACpB,WAAY,GACZ,SAAU,EACV,QAAS,CACX,CAAC,EACK,EAAO,EAAA,kBAA+B,CAC1C,UAAA,EAAU,EAAA,SAAA,KAAe,CAAC,EAAa,KAAK,EAClC,WACV,eAAiB,GAAS,EAAK,aAAa,UAAU,EACtD,YAAa,CAAE,UAAW,CACxB,EAAiB,CAAI,CAAC,EAAE,MAAM,CAChC,EACA,OAAQ,CACV,CAAC,EAEK,GAAS,EAA8B,eAAgB,EAAqB,KAAe,CAC1F,EAAa,QAElB,EAAa,MAAQ,GACrB,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,KAEd,IAAoB,EAAA,EAAA,aAAA,KAAmB,CAAS,EAEpD,EAAK,cAAe,CAAE,KAAM,GAAO,QAAO,CAAC,EAC7C,EAEM,GAAQ,EAA4B,iBAAyB,CAC7D,EAAW,OAAS,EAAa,QAErC,EAAa,MAAQ,GACrB,EAAW,OAAO,EAClB,EAAkB,EAAW,kBAAkB,GAAK,KACpD,EAAK,cAAe,CAAE,KAAM,GAAM,QAAO,CAAC,EAC5C,EAEM,MAAqB,CACrB,EAAa,MAAO,EAAM,SAAS,EAClC,EAAK,OAAO,CACnB,EAEA,EAAA,8BAA8B,CAC5B,eAAkB,CAAC,EAAI,CAAO,EAC9B,aAAgB,EAAa,MAC7B,cAAiB,EAAM,cAAc,EACrC,OAAQ,CACV,CAAC,EAED,IAAI,EAAc,IAElB,EAAA,EAAA,MAAA,CACE,EAAM,KACL,GAAU,CACL,IAAU,IAAA,GACP,EAGH,EAAM,cAAc,EAFhB,EAAM,eAAe,CAAC,OAAO,EAAK,cAAc,EAI7C,EACT,EAAK,cAAc,EAEnB,EAAM,cAAc,EAGtB,EAAc,EAChB,EACA,CAAE,UAAW,EAAK,CACpB,EACA,EAAY,iBACV,YACM,CACC,EAAa,QAElB,EAAa,MAAQ,GACrB,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,KACpB,EACA,CAAE,KAAM,EAAK,CACf,EAEA,IAAM,EAAgB,GAA4B,CAChD,IAAM,EAAO,EAAK,aAAa,MAAM,EAC/B,EAAc,EAAoB,CAAI,EAE5C,GAAI,IAAS,WACX,EAAK,gBAAgB,UAAW,CAAC,EAAK,aAAa,SAAS,CAAC,OACxD,GAAI,IAAS,QAClB,IAAK,IAAM,KAAS,EAAG,iBAA8B,6BAA6B,EAChF,EAAM,gBAAgB,UAAW,IAAU,CAAI,EAInD,IAAM,EAAQ,EAAK,aAAa,OAAO,GAAK,GACtC,EAAU,EAAc,EAAK,aAAa,SAAS,EAAI,IAAA,GAE7D,EAAK,SAAU,CAAE,UAAS,OAAM,CAAC,EAE5B,GACH,EAAM,cAAc,CAExB,EAEM,EAAwB,EAAA,kBAAkB,CAC9C,KAAM,CAAC,QAAS,IAAK,WAAW,EAChC,YAAe,CACb,EAAK,UAAU,EACf,0BAA4B,EAAK,IAAI,CAAC,CAAC,CACzC,CACF,CAAC,EAEK,EAAmC,EAAA,kBAAkB,CACzD,YAAe,CACb,IAAM,EAAU,EAAK,cAAc,EAE/B,GAAS,EAAa,CAAO,CACnC,CACF,CAAC,EAGD,SAAS,EAAkB,EAAkB,CAC3C,GAAI,EAAW,MAAO,OAKtB,GAAI,CAHS,EAAa,MAGf,CACT,EAAsB,cAAc,CAAC,EAErC,MACF,CAEA,IAAM,EAAsB,EAAoB,EAIhD,GAFI,GAAuB,GAAG,EAAK,IAAI,CAAmB,EAEtD,EAAE,MAAQ,SAAU,CACtB,EAAE,eAAe,EACjB,EAAM,QAAQ,EAEd,MACF,CAEI,MAAK,cAAc,CAAC,EAGxB,IAAI,EAAE,MAAQ,KAAO,EAAE,MAAQ,QAAS,CACtC,EAAiC,cAAc,CAAC,EAEhD,MACF,CAEI,EAAE,MAAQ,OACZ,EAAM,cAAc,CAHtB,CAKF,EAGA,EAAA,EAAA,KAAA,CAAK,CACH,GAAI,CACF,MAAQ,GAAkB,CACxB,IAAM,EAAO,EAAE,aAAa,EAE5B,GAAI,CAAC,EAAa,MAAO,OAKzB,IAAM,EAHe,EAAK,KACvB,GAA8B,aAAgB,aAAe,EAAK,UAAY,eAEpE,GAAiB,EAAE,QAA+B,QAAqB,eAAe,GAAK,KAEpG,CAAC,GAAQ,EAAK,aAAa,UAAU,GAEzC,EAAa,CAAI,CACnB,CACF,CACF,CAAC,EAED,MAAY,CACV,IAAM,EAAO,EAAa,MAErB,GAEL,EAAQ,gBAAgB,YAAa,CAAI,CAC3C,CAAC,EAED,SAAS,GAAiB,CAQxB,GAPA,IAAiB,EACjB,EAAiB,KAIjB,EAFiB,EAAM,SAAS,SAAS,CAAC,CAAC,QAEnB,IAAkC,KAEtD,CAAC,EAAW,OAEhB,IAAM,EAA8B,CAAC,EAC/B,GAAA,EAAa,EAAA,KAAA,CACjB,CACE,KAAM,CACJ,aAAgB,EAChB,aAAgB,EAAW,MAC3B,aAAgB,OAAO,EAAa,KAAK,EACzC,SAAU,MACZ,CACF,EACA,CAAE,OAAQ,CAAU,CACtB,EAEM,EAAkB,GAAsB,CAC5C,EAAM,gBAAgB,EAElB,GAAW,OAEf,EAAO,CACT,EACM,EAAoB,GAAyB,CACjD,EAAkB,CAAK,CACzB,EAEA,EAAU,iBAAiB,QAAS,CAAc,EAClD,EAAU,iBAAiB,UAAW,CAAgB,EACtD,EAAS,SAAW,GAAW,oBAAoB,QAAS,CAAc,CAAC,EAC3E,EAAS,SAAW,GAAW,oBAAoB,UAAW,CAAgB,CAAC,EAE/E,MAAuB,CACrB,EAAW,EAEX,IAAK,IAAM,KAAW,EAAU,EAAQ,CAC1C,CACF,CAaA,OAXA,EAAA,EAAA,MAAA,CAAY,EAAM,SAAS,SAAS,EAAG,EAAgB,CAAE,UAAW,EAAK,CAAC,GAE1E,EAAA,EAAA,UAAA,MACE,EAAe,MAEF,CACX,IAAiB,EACjB,EAAiB,IACnB,EACD,EAEM,EAAA,IAAI;;;;;cAKD,EAAO;;;oBAGD,EAAkB;eACtB,GAA2B,CACjC,EAAU,EACV,GAAS,gBAAgB,YAAa,EAAa,KAAK,CAC1D,EAAE;;;KAIR,EACA,OAAQ,CAAC,EAAA,QAAiB,EAAA,iBAAiB,EAAA,gBAAgB,EAAG,EAAA,iBAAiB,CACjF,CAAC"}