{"version":3,"file":"useSubOrganisations-CUSteO0e.mjs","names":[],"sources":["../src/components/form/OctopusSelect.vue","../src/components/form/OctopusSelect.vue","../src/helper/slugify.ts","../src/components/composable/useSubOrganisations.ts"],"sourcesContent":["<template>\n    <div\n        ref=\"containerRef\"\n        class=\"octopus-select\"\n        :class=\"{ 'form-margin': label }\"\n    >\n        <label\n            v-if=\"label\"\n            :for=\"computedId\"\n            class=\"form-label\"\n        >\n            {{ label }}\n        </label>\n\n        <div\n            class=\"octopus-select-field\"\n            :class=\"{ disabled, open: isOpen, noBorder }\"\n            @click=\"openDropdown\"\n        >\n            <span\n                v-show=\"selectedLabel && !isOpen\"\n                class=\"octopus-select-value\"\n            >{{ selectedLabel }}</span>\n            <input\n                v-show=\"!selectedLabel || isOpen\"\n                :id=\"computedId\"\n                ref=\"inputRef\"\n                v-model=\"searchQuery\"\n                type=\"text\"\n                class=\"octopus-select-input\"\n                :placeholder=\"inputPlaceholder\"\n                :disabled=\"disabled\"\n                @focus=\"openDropdown\"\n                @input=\"handleInput\"\n            >\n            <button\n                class=\"btn-transparent octopus-select-chevron\"\n                :disabled=\"disabled\"\n                @click.stop=\"toggleDropdown\"\n            >\n                <ChevronDownIcon />\n            </button>\n        </div>\n\n        <Teleport :to=\"teleportTarget\">\n            <div\n                v-if=\"isOpen\"\n                ref=\"dropdownRef\"\n                class=\"octopus-select-dropdown\"\n                :class=\"dropdownClass\"\n                :style=\"dropdownStyle\"\n            >\n                <div class=\"octopus-select-options\">\n                    <button\n                        v-for=\"(option, index) in visibleOptions\"\n                        :key=\"index\"\n                        class=\"octopus-select-option\"\n                        :class=\"{ selected: isSelected(option) }\"\n                        @click=\"selectOption(option)\"\n                    >\n                        {{ getLabel(option) }}\n                    </button>\n                    <span v-if=\"visibleOptions.length === 0\" class=\"text-indic px-2\">\n                        {{ t('No elements found. Consider changing the search query.') }}\n                    </span>\n                </div>\n            </div>\n        </Teleport>\n    </div>\n</template>\n\n<script setup lang=\"ts\" generic=\"T\">\nimport { type CSSProperties, computed, nextTick, onMounted, onUnmounted, ref, toRaw, watch } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport ChevronDownIcon from 'vue-material-design-icons/ChevronDown.vue';\nimport { useOctopusDropdown } from '../composable/form/useOctopusDropdown';\n\nconst props = withDefaults(defineProps<{\n    /** Optional label displayed above the field. */\n    label?: string;\n    /** Currently selected item. Bind with `v-model:value`. */\n    value?: T;\n    /** Full list of options to display or filter. */\n    options: T[];\n    /** Key of each option object to use as the ID. */\n    optionKey?: keyof T;\n    /** Key of each option object to use as the display label. */\n    optionLabel: keyof T & string;\n    /** Disables the field when true. */\n    disabled?: boolean;\n    /** Placeholder shown in the input when no item is selected. Defaults to the translated \"Search\" string. */\n    placeholder?: string;\n    /** Disable the border around the input. */\n    noBorder?: boolean;\n    /** When true (default), clicking the already-selected option clears the selection. */\n    allowDeselect?: boolean;\n    /** When true, the option matching the current value is moved to the top of the list\n     *  the moment the dropdown opens. This is a snapshot taken at open time — it does not\n     *  live-reorder while the dropdown stays open, only on the next closed→open transition. */\n    pullSelectedToTop?: boolean;\n}>(), {\n    label: undefined,\n    value: undefined,\n    optionKey: undefined,\n    placeholder: undefined,\n    allowDeselect: true,\n});\n\nconst emit = defineEmits<{\n    /** Emitted when the selection changes. */\n    (e: 'update:value', value: T | undefined): void;\n    /** Emitted on every input change. When listened to, the parent is responsible for\n     *  updating `options`; otherwise the component filters `options` client-side. */\n    (e: 'search', query: string): void;\n}>();\n\nconst { t } = useI18n();\n\n// Ref on the teleported dropdown div — passed as ignored element to useOctopusDropdown\n// so clicks inside the dropdown don't trigger the click-outside handler.\nconst dropdownRef = ref<HTMLElement | null>(null);\n\nconst {\n    searchQuery,\n    isOpen,\n    containerRef,\n    inputRef,\n    teleportTarget,\n    computedId,\n    displayedOptions,\n    inputPlaceholder,\n    getLabel,\n    openDropdown,\n    closeDropdown,\n    toggleDropdown,\n    handleInput,\n} = useOctopusDropdown(props, (query) => emit('search', query), 'select', [dropdownRef]);\n\n// Position of the teleported dropdown (position: fixed, anchored below the trigger field)\nconst dropdownStyle = ref<CSSProperties>({});\n\nfunction updateDropdownPosition(): void {\n    if (!containerRef.value) { return; }\n    const rect = containerRef.value.getBoundingClientRect();\n    dropdownStyle.value = {\n        position: 'fixed',\n        top: `${rect.bottom + 2}px`,\n        left: `${rect.left}px`,\n        width: `${rect.width}px`,\n    };\n}\n\n// Value snapshot captured the instant the dropdown opens, used only to freeze the\n// sort order when pullSelectedToTop is set — does not react to later `value` changes\n// while the dropdown stays open.\nconst pinnedValue = ref<T | undefined>(undefined);\n\nwatch(isOpen, (val) => {\n    if (val) {\n        pinnedValue.value = props.value;\n        nextTick(updateDropdownPosition);\n    }\n});\n\nonMounted(() => {\n    // Keep the teleported dropdown aligned when the page scrolls or the viewport resizes\n    window.addEventListener('scroll', updateDropdownPosition, true);\n    window.addEventListener('resize', updateDropdownPosition);\n});\n\nonUnmounted(() => {\n    window.removeEventListener('scroll', updateDropdownPosition, true);\n    window.removeEventListener('resize', updateDropdownPosition);\n});\n\nconst selectedLabel = computed(() =>\n    props.value !== undefined ? getLabel(props.value) : undefined\n);\n\nfunction isSelected(option: T): boolean {\n    if (props.value === undefined) {\n        return false;\n    }\n    if (props.optionKey) {\n        return props.value[props.optionKey] === option[props.optionKey];\n    }\n    return toRaw(props.value as object) === toRaw(option as object);\n}\n\nfunction isPinned(option: T): boolean {\n    if (pinnedValue.value === undefined) {\n        return false;\n    }\n    if (props.optionKey) {\n        return pinnedValue.value[props.optionKey] === option[props.optionKey];\n    }\n    return toRaw(pinnedValue.value as object) === toRaw(option as object);\n}\n\nconst visibleOptions = computed<T[]>(() => {\n    if (!props.pullSelectedToTop) {\n        return displayedOptions.value;\n    }\n    return [...displayedOptions.value.filter(isPinned), ...displayedOptions.value.filter((option) => !isPinned(option))];\n});\n\nfunction selectOption(option: T): void {\n    if (isSelected(option) && props.allowDeselect) {\n        emit('update:value', undefined);\n    } else {\n        emit('update:value', option);\n    }\n    closeDropdown();\n}\n</script>\n\n<style scoped lang=\"scss\">\n.octopus-select {\n    position: relative;\n\n    .octopus-select-field {\n        display: flex;\n        align-items: center;\n        border: 1px solid var(--octopus-border-default);\n        border-radius: var(--octopus-border-radius);\n        background: white;\n        cursor: pointer;\n\n        &.open {\n            border-color: var(--octopus-primary);\n        }\n\n        &.disabled {\n            background: var(--octopus-secondary-lighter);\n            cursor: default;\n        }\n\n        &.noBorder {\n            border: none;\n        }\n    }\n\n    .octopus-select-value {\n        flex: 1;\n        min-width: 0;\n        overflow: hidden;\n        text-overflow: ellipsis;\n        white-space: nowrap;\n        padding: 0.4rem 0.5rem;\n        padding-right: 0;\n        height: 2rem;\n    }\n\n    .octopus-select-input {\n        flex: 1;\n        border: none;\n        background: transparent;\n        padding: 0.4rem 0.5rem;\n        height: 2rem;\n        outline: none;\n        cursor: inherit;\n        min-width: 0;\n    }\n\n    .octopus-select-chevron {\n        padding: 0.25rem 0.5rem;\n        display: flex;\n        align-items: center;\n    }\n\n}\n\n// Dropdown is teleported to body — scoped rules must be top-level so that [data-v-xxxx]\n// is matched directly on the element rather than via a descendant-of-.octopus-select selector.\n.octopus-select-dropdown {\n    z-index: 100;\n    background: white;\n    border: 1px solid var(--octopus-border-default);\n    border-radius: var(--octopus-border-radius);\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n    padding: 0.25rem 0;\n}\n\n.octopus-select-options {\n    max-height: 14rem;\n    overflow-y: auto;\n}\n\n.octopus-select-option {\n    display: block;\n    width: 100%;\n    text-align: left;\n    padding: 0.25rem 0.5rem;\n    border: none;\n    background: transparent;\n    cursor: pointer;\n\n    &:hover {\n        background: var(--octopus-secondary-lighter);\n    }\n\n    &.selected {\n        font-weight: 600;\n        color: var(--octopus-primary);\n    }\n}\n</style>\n","<template>\n    <div\n        ref=\"containerRef\"\n        class=\"octopus-select\"\n        :class=\"{ 'form-margin': label }\"\n    >\n        <label\n            v-if=\"label\"\n            :for=\"computedId\"\n            class=\"form-label\"\n        >\n            {{ label }}\n        </label>\n\n        <div\n            class=\"octopus-select-field\"\n            :class=\"{ disabled, open: isOpen, noBorder }\"\n            @click=\"openDropdown\"\n        >\n            <span\n                v-show=\"selectedLabel && !isOpen\"\n                class=\"octopus-select-value\"\n            >{{ selectedLabel }}</span>\n            <input\n                v-show=\"!selectedLabel || isOpen\"\n                :id=\"computedId\"\n                ref=\"inputRef\"\n                v-model=\"searchQuery\"\n                type=\"text\"\n                class=\"octopus-select-input\"\n                :placeholder=\"inputPlaceholder\"\n                :disabled=\"disabled\"\n                @focus=\"openDropdown\"\n                @input=\"handleInput\"\n            >\n            <button\n                class=\"btn-transparent octopus-select-chevron\"\n                :disabled=\"disabled\"\n                @click.stop=\"toggleDropdown\"\n            >\n                <ChevronDownIcon />\n            </button>\n        </div>\n\n        <Teleport :to=\"teleportTarget\">\n            <div\n                v-if=\"isOpen\"\n                ref=\"dropdownRef\"\n                class=\"octopus-select-dropdown\"\n                :class=\"dropdownClass\"\n                :style=\"dropdownStyle\"\n            >\n                <div class=\"octopus-select-options\">\n                    <button\n                        v-for=\"(option, index) in visibleOptions\"\n                        :key=\"index\"\n                        class=\"octopus-select-option\"\n                        :class=\"{ selected: isSelected(option) }\"\n                        @click=\"selectOption(option)\"\n                    >\n                        {{ getLabel(option) }}\n                    </button>\n                    <span v-if=\"visibleOptions.length === 0\" class=\"text-indic px-2\">\n                        {{ t('No elements found. Consider changing the search query.') }}\n                    </span>\n                </div>\n            </div>\n        </Teleport>\n    </div>\n</template>\n\n<script setup lang=\"ts\" generic=\"T\">\nimport { type CSSProperties, computed, nextTick, onMounted, onUnmounted, ref, toRaw, watch } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport ChevronDownIcon from 'vue-material-design-icons/ChevronDown.vue';\nimport { useOctopusDropdown } from '../composable/form/useOctopusDropdown';\n\nconst props = withDefaults(defineProps<{\n    /** Optional label displayed above the field. */\n    label?: string;\n    /** Currently selected item. Bind with `v-model:value`. */\n    value?: T;\n    /** Full list of options to display or filter. */\n    options: T[];\n    /** Key of each option object to use as the ID. */\n    optionKey?: keyof T;\n    /** Key of each option object to use as the display label. */\n    optionLabel: keyof T & string;\n    /** Disables the field when true. */\n    disabled?: boolean;\n    /** Placeholder shown in the input when no item is selected. Defaults to the translated \"Search\" string. */\n    placeholder?: string;\n    /** Disable the border around the input. */\n    noBorder?: boolean;\n    /** When true (default), clicking the already-selected option clears the selection. */\n    allowDeselect?: boolean;\n    /** When true, the option matching the current value is moved to the top of the list\n     *  the moment the dropdown opens. This is a snapshot taken at open time — it does not\n     *  live-reorder while the dropdown stays open, only on the next closed→open transition. */\n    pullSelectedToTop?: boolean;\n}>(), {\n    label: undefined,\n    value: undefined,\n    optionKey: undefined,\n    placeholder: undefined,\n    allowDeselect: true,\n});\n\nconst emit = defineEmits<{\n    /** Emitted when the selection changes. */\n    (e: 'update:value', value: T | undefined): void;\n    /** Emitted on every input change. When listened to, the parent is responsible for\n     *  updating `options`; otherwise the component filters `options` client-side. */\n    (e: 'search', query: string): void;\n}>();\n\nconst { t } = useI18n();\n\n// Ref on the teleported dropdown div — passed as ignored element to useOctopusDropdown\n// so clicks inside the dropdown don't trigger the click-outside handler.\nconst dropdownRef = ref<HTMLElement | null>(null);\n\nconst {\n    searchQuery,\n    isOpen,\n    containerRef,\n    inputRef,\n    teleportTarget,\n    computedId,\n    displayedOptions,\n    inputPlaceholder,\n    getLabel,\n    openDropdown,\n    closeDropdown,\n    toggleDropdown,\n    handleInput,\n} = useOctopusDropdown(props, (query) => emit('search', query), 'select', [dropdownRef]);\n\n// Position of the teleported dropdown (position: fixed, anchored below the trigger field)\nconst dropdownStyle = ref<CSSProperties>({});\n\nfunction updateDropdownPosition(): void {\n    if (!containerRef.value) { return; }\n    const rect = containerRef.value.getBoundingClientRect();\n    dropdownStyle.value = {\n        position: 'fixed',\n        top: `${rect.bottom + 2}px`,\n        left: `${rect.left}px`,\n        width: `${rect.width}px`,\n    };\n}\n\n// Value snapshot captured the instant the dropdown opens, used only to freeze the\n// sort order when pullSelectedToTop is set — does not react to later `value` changes\n// while the dropdown stays open.\nconst pinnedValue = ref<T | undefined>(undefined);\n\nwatch(isOpen, (val) => {\n    if (val) {\n        pinnedValue.value = props.value;\n        nextTick(updateDropdownPosition);\n    }\n});\n\nonMounted(() => {\n    // Keep the teleported dropdown aligned when the page scrolls or the viewport resizes\n    window.addEventListener('scroll', updateDropdownPosition, true);\n    window.addEventListener('resize', updateDropdownPosition);\n});\n\nonUnmounted(() => {\n    window.removeEventListener('scroll', updateDropdownPosition, true);\n    window.removeEventListener('resize', updateDropdownPosition);\n});\n\nconst selectedLabel = computed(() =>\n    props.value !== undefined ? getLabel(props.value) : undefined\n);\n\nfunction isSelected(option: T): boolean {\n    if (props.value === undefined) {\n        return false;\n    }\n    if (props.optionKey) {\n        return props.value[props.optionKey] === option[props.optionKey];\n    }\n    return toRaw(props.value as object) === toRaw(option as object);\n}\n\nfunction isPinned(option: T): boolean {\n    if (pinnedValue.value === undefined) {\n        return false;\n    }\n    if (props.optionKey) {\n        return pinnedValue.value[props.optionKey] === option[props.optionKey];\n    }\n    return toRaw(pinnedValue.value as object) === toRaw(option as object);\n}\n\nconst visibleOptions = computed<T[]>(() => {\n    if (!props.pullSelectedToTop) {\n        return displayedOptions.value;\n    }\n    return [...displayedOptions.value.filter(isPinned), ...displayedOptions.value.filter((option) => !isPinned(option))];\n});\n\nfunction selectOption(option: T): void {\n    if (isSelected(option) && props.allowDeselect) {\n        emit('update:value', undefined);\n    } else {\n        emit('update:value', option);\n    }\n    closeDropdown();\n}\n</script>\n\n<style scoped lang=\"scss\">\n.octopus-select {\n    position: relative;\n\n    .octopus-select-field {\n        display: flex;\n        align-items: center;\n        border: 1px solid var(--octopus-border-default);\n        border-radius: var(--octopus-border-radius);\n        background: white;\n        cursor: pointer;\n\n        &.open {\n            border-color: var(--octopus-primary);\n        }\n\n        &.disabled {\n            background: var(--octopus-secondary-lighter);\n            cursor: default;\n        }\n\n        &.noBorder {\n            border: none;\n        }\n    }\n\n    .octopus-select-value {\n        flex: 1;\n        min-width: 0;\n        overflow: hidden;\n        text-overflow: ellipsis;\n        white-space: nowrap;\n        padding: 0.4rem 0.5rem;\n        padding-right: 0;\n        height: 2rem;\n    }\n\n    .octopus-select-input {\n        flex: 1;\n        border: none;\n        background: transparent;\n        padding: 0.4rem 0.5rem;\n        height: 2rem;\n        outline: none;\n        cursor: inherit;\n        min-width: 0;\n    }\n\n    .octopus-select-chevron {\n        padding: 0.25rem 0.5rem;\n        display: flex;\n        align-items: center;\n    }\n\n}\n\n// Dropdown is teleported to body — scoped rules must be top-level so that [data-v-xxxx]\n// is matched directly on the element rather than via a descendant-of-.octopus-select selector.\n.octopus-select-dropdown {\n    z-index: 100;\n    background: white;\n    border: 1px solid var(--octopus-border-default);\n    border-radius: var(--octopus-border-radius);\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n    padding: 0.25rem 0;\n}\n\n.octopus-select-options {\n    max-height: 14rem;\n    overflow-y: auto;\n}\n\n.octopus-select-option {\n    display: block;\n    width: 100%;\n    text-align: left;\n    padding: 0.25rem 0.5rem;\n    border: none;\n    background: transparent;\n    cursor: pointer;\n\n    &:hover {\n        background: var(--octopus-secondary-lighter);\n    }\n\n    &.selected {\n        font-weight: 600;\n        color: var(--octopus-primary);\n    }\n}\n</style>\n","export function slugify(name: string): string {\n    return name\n        .normalize('NFD')\n        .replace(/[\\u0300-\\u036f]/g, '')\n        .toLowerCase()\n        .replace(/[^a-z0-9]+/g, '-')\n        .replace(/^-+|-+$/g, '');\n}\n","import { rubriquesApi } from '@/api';\nimport { slugify } from '@/helper/slugify';\nimport { Annotations } from '@/stores/class/general';\nimport { Rubriquage } from '@/stores/class/rubrique/rubriquage';\nimport ParamSdkStore from '@/stores/ParamSdkStore';\nimport { effectScope, Ref, ref, watch } from 'vue';\n\nconst subOrganisations = ref<Array<SubOrganisation>>([]);\nconst selectedSubOrganisation = ref<SubOrganisation|null>(null);\n\n// Promise for retrieving suborganisations\nlet loadingPromise: Promise<Rubriquage|undefined>|null = null;\n\n// Whether the watch on organisationId has already been registered\nlet watchInitialized = false;\n\nexport interface SubOrganisation {\n    id: number;\n    name: string;\n    annotations: Annotations;\n    podcastCount: number;\n}\n\nfunction slugifySubOrganisation(subOrga: SubOrganisation): string {\n    return slugify(subOrga.name);\n}\n\n/**\n * Composable to manage suborganisation.\n * Allows for selecting (= focusing), unselecting, listing, etc\n * @param organisationId ID of the current organisation\n * @param slugFunc Function to slugify the suborganisation ids\n */\nexport const useSubOrganisations = (organisationId: Ref<string>, slugFunc = slugifySubOrganisation) => {\n\n    // Register the watch on organisationId only once, detached from any\n    // component's lifecycle, so it isn't stopped when the first caller unmounts\n    if (!watchInitialized) {\n        watchInitialized = true;\n\n        // Load suborganisations if necessary\n        if (subOrganisations.value.length === 0 && !loadingPromise) {\n            updateList();\n        }\n\n        effectScope(true).run(() => {\n            watch(organisationId, updateList);\n        });\n    }\n\n    async function updateList() {\n        unselectSubOrganisation();\n        loadingPromise = rubriquesApi.findRestrictiveRubriquage(organisationId.value);\n        const rubriquage = await loadingPromise;\n        loadingPromise = null;\n        if (rubriquage) {\n            subOrganisations.value = rubriquage.rubriques.map(r => ({\n                id: r.rubriqueId,\n                name: r.name,\n                podcastCount: r.podcastCount ?? 0,\n                annotations: r.annotations ?? {}\n            }));\n        } else {\n            subOrganisations.value = [];\n        }\n    }\n\n    async function getSubOrganisation(id: string|number): Promise<SubOrganisation> {\n        if (loadingPromise) {\n            await loadingPromise;\n        }\n\n        let findFunc;\n        if (typeof id === 'string') {\n            findFunc = (c: SubOrganisation) => slugFunc(c) === id;\n        } else {\n            findFunc = (c: SubOrganisation) => c.id === id;\n        }\n\n        const subOrga = subOrganisations.value.find(findFunc);\n        if (subOrga) {\n            return Promise.resolve(subOrga);\n        } else {\n            return Promise.reject(`Sub organisation ${id} not found`);\n        }\n    }\n\n    function selectSubOrganisation(subOrganisation: SubOrganisation): void {\n        if (selectedSubOrganisation.value) {\n            unselectSubOrganisation();\n        }\n\n        selectedSubOrganisation.value = subOrganisation;\n        // Force filtering on rubrique ID of the college\n        ParamSdkStore.state.generalParameters.forceRubriqueId = [\n            ParamSdkStore.state.generalParameters.forceRubriqueId ?? [],\n            subOrganisation.id\n        ].flat();\n    }\n\n    function unselectSubOrganisation(): void {\n        // Nothing to do if no org is selected\n        if (!selectedSubOrganisation.value) {\n            return;\n        }\n\n        // Restore the site's base rubrique filter instead of clearing it outright\n        const data = ParamSdkStore.state.generalParameters.forceRubriqueId;\n        if (Array.isArray(data)) {\n            const idx = data.findIndex(id => id === selectedSubOrganisation.value.id);\n            if (idx >= 0) {\n                data.splice(idx, 1);\n            }\n            ParamSdkStore.state.generalParameters.forceRubriqueId = data;\n        } else {\n            ParamSdkStore.state.generalParameters.forceRubriqueId = undefined;\n        }\n        selectedSubOrganisation.value = null;\n    }\n\n    return {\n        /** Currently selected/focused suborganisation */\n        selectSubOrganisation,\n        /** Change the currently selected/focused suborganisation */\n        selectedSubOrganisation,\n        /** Remove the focus on the suborganisation */\n        unselectSubOrganisation,\n        /** List of available suborganisations */\n        subOrganisations,\n        /**\n         * Get a suborganisation by its ID or sluggified name\n         * @param id Either the numeric ID or the sluggified name of the orga\n         * @returns A promise of the matching sub organisation\n         */\n        getSubOrganisation\n    };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6EA,MAAM,QAAQ;EA+Bd,MAAM,OAAO;EAQb,MAAM,EAAE,MAAM,QAAQ;EAItB,MAAM,cAAc,IAAwB,IAAI;EAEhD,MAAM,EACF,aACA,QACA,cACA,UACA,gBACA,YACA,kBACA,kBACA,UACA,cACA,eACA,gBACA,gBACA,mBAAmB,QAAQ,UAAU,KAAK,UAAU,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC;EAGvF,MAAM,gBAAgB,IAAmB,CAAC,CAAC;EAE3C,SAAS,yBAA+B;GACpC,IAAI,CAAC,aAAa,OAAS;GAC3B,MAAM,OAAO,aAAa,MAAM,sBAAsB;GACtD,cAAc,QAAQ;IAClB,UAAU;IACV,KAAK,GAAG,KAAK,SAAS,EAAE;IACxB,MAAM,GAAG,KAAK,KAAK;IACnB,OAAO,GAAG,KAAK,MAAM;GACzB;EACJ;EAKA,MAAM,cAAc,IAAmB,KAAA,CAAS;EAEhD,MAAM,SAAS,QAAQ;GACnB,IAAI,KAAK;IACL,YAAY,QAAQ,MAAM;IAC1B,SAAS,sBAAsB;GACnC;EACJ,CAAC;EAED,gBAAgB;GAEZ,OAAO,iBAAiB,UAAU,wBAAwB,IAAI;GAC9D,OAAO,iBAAiB,UAAU,sBAAsB;EAC5D,CAAC;EAED,kBAAkB;GACd,OAAO,oBAAoB,UAAU,wBAAwB,IAAI;GACjE,OAAO,oBAAoB,UAAU,sBAAsB;EAC/D,CAAC;EAED,MAAM,gBAAgB,eAClB,MAAM,UAAU,KAAA,IAAY,SAAS,MAAM,KAAK,IAAI,KAAA,CACxD;EAEA,SAAS,WAAW,QAAoB;GACpC,IAAI,MAAM,UAAU,KAAA,GAChB,OAAO;GAEX,IAAI,MAAM,WACN,OAAO,MAAM,MAAM,MAAM,eAAe,OAAO,MAAM;GAEzD,OAAO,MAAM,MAAM,KAAe,MAAM,MAAM,MAAgB;EAClE;EAEA,SAAS,SAAS,QAAoB;GAClC,IAAI,YAAY,UAAU,KAAA,GACtB,OAAO;GAEX,IAAI,MAAM,WACN,OAAO,YAAY,MAAM,MAAM,eAAe,OAAO,MAAM;GAE/D,OAAO,MAAM,YAAY,KAAe,MAAM,MAAM,MAAgB;EACxE;EAEA,MAAM,iBAAiB,eAAoB;GACvC,IAAI,CAAC,MAAM,mBACP,OAAO,iBAAiB;GAE5B,OAAO,CAAC,GAAG,iBAAiB,MAAM,OAAO,QAAQ,GAAG,GAAG,iBAAiB,MAAM,QAAQ,WAAW,CAAC,SAAS,MAAM,CAAC,CAAC;EACvH,CAAC;EAED,SAAS,aAAa,QAAiB;GACnC,IAAI,WAAW,MAAM,KAAK,MAAM,eAC5B,KAAK,gBAAgB,KAAA,CAAS;QAE9B,KAAK,gBAAgB,MAAM;GAE/B,cAAc;EAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBCjKqB,OAAM,yBAAwB;;;;CAUU,OAAM;;;qBA7D/D,mBAmEM,OAAA;EAlEF,KAAI;EACJ,OAAK,eAAA,CAAC,kBAAgB,EAAA,eACG,OAAA,MAAK,CAAA,CAAA;;EAGpB,OAAA,SAAA,UAAA,GADV,mBAMQ,SAAA;;GAJH,KAAK,OAAA;GACN,OAAM;qBAEH,OAAA,KAAK,GAAA,GAAA,UAAA,KAAA,mBAAA,QAAA,IAAA;EAGZ,mBA4BM,OAAA;GA3BF,OAAK,eAAA,CAAC,wBAAsB;IAAA,UAClB,OAAA;IAAQ,MAAQ,OAAA;IAAM,UAAE,OAAA;GAAQ,CAAA,CAAA;GACzC,SAAK,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,gBAAA,OAAA,aAAA,GAAA,IAAA;;kBAER,mBAG2B,QAAA,EADvB,OAAM,uBAAsB,GAAA,gBAC5B,OAAA,aAAa,GAAA,GAAA,GAAA,CAAA,CAAA,OAFL,OAAA,iBAAa,CAAK,OAAA,MAAM,CAAA,CAAA;kBAGpC,mBAWC,SAAA;IATI,IAAI,OAAA;IACL,KAAI;iEACK,OAAA,cAAW;IACpB,MAAK;IACL,OAAM;IACL,aAAa,OAAA;IACb,UAAU,OAAA;IACV,SAAK,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,gBAAA,OAAA,aAAA,GAAA,IAAA;IACP,SAAK,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,eAAA,OAAA,YAAA,GAAA,IAAA;uCATC,OAAA,iBAAiB,OAAA,MAAM,GAAA,CAAA,YAGvB,OAAA,WAAW,CAAA,CAAA;GAQxB,mBAMS,UAAA;IALL,OAAM;IACL,UAAU,OAAA;IACV,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,GAAA,SAAO,OAAA,kBAAA,OAAA,eAAA,GAAA,IAAA,GAAc,CAAA,MAAA,CAAA;OAE3B,YAAmB,OAAA,kBAAA,CAAA,GAAA,GAAA,UAAA;;gBAI3B,YAuBW,UAAA,EAvBA,IAAI,OAAA,eAAc,GAAA,CAEf,OAAA,UAAA,UAAA,GADV,mBAqBM,OAAA;;GAnBF,KAAI;GACJ,OAAK,eAAA,CAAC,2BACE,KAAA,aAAa,CAAA;GACpB,OAAK,eAAE,OAAA,aAAa;MAErB,mBAaM,OAbN,YAaM,EAAA,UAAA,IAAA,GAZF,mBAQS,UAAA,MAAA,WAPqB,OAAA,iBAAlB,QAAQ,UAAK;uBADzB,mBAQS,UAAA;IANJ,KAAK;IACN,OAAK,eAAA,CAAC,yBAAuB,EAAA,UACT,OAAA,WAAW,MAAM,EAAA,CAAA,CAAA;IACpC,UAAK,WAAE,OAAA,aAAa,MAAM;sBAExB,OAAA,SAAS,MAAM,CAAA,GAAA,IAAA,UAAA;aAEV,OAAA,eAAe,WAAM,KAAA,UAAA,GAAjC,mBAEO,QAFP,YAEO,gBADA,OAAA,EAAC,wDAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,QAAA,IAAA,CAAA,CAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,QAAA,IAAA,CAAA,GAAA,GAAA,CAAA,IAAA,CAAA;;;;;;;;;;AC/D5B,SAAgB,QAAQ,MAAsB;CAC1C,OAAO,KACF,UAAU,KAAK,EACf,QAAQ,oBAAoB,EAAE,EAC9B,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AAC/B;;;ACAA,IAAM,mBAAmB,IAA4B,CAAC,CAAC;AACvD,IAAM,0BAA0B,IAA0B,IAAI;AAG9D,IAAI,iBAAqD;AAGzD,IAAI,mBAAmB;AASvB,SAAS,uBAAuB,SAAkC;CAC9D,OAAO,QAAQ,QAAQ,IAAI;AAC/B;;;;;;;AAQA,IAAa,uBAAuB,gBAA6B,WAAW,2BAA2B;CAInG,IAAI,CAAC,kBAAkB;EACnB,mBAAmB;EAGnB,IAAI,iBAAiB,MAAM,WAAW,KAAK,CAAC,gBACxC,WAAW;EAGf,YAAY,IAAI,EAAE,UAAU;GACxB,MAAM,gBAAgB,UAAU;EACpC,CAAC;CACL;CAEA,eAAe,aAAa;EACxB,wBAAwB;EACxB,iBAAiB,aAAa,0BAA0B,eAAe,KAAK;EAC5E,MAAM,aAAa,MAAM;EACzB,iBAAiB;EACjB,IAAI,YACA,iBAAiB,QAAQ,WAAW,UAAU,KAAI,OAAM;GACpD,IAAI,EAAE;GACN,MAAM,EAAE;GACR,cAAc,EAAE,gBAAgB;GAChC,aAAa,EAAE,eAAe,CAAC;EACnC,EAAE;OAEF,iBAAiB,QAAQ,CAAC;CAElC;CAEA,eAAe,mBAAmB,IAA6C;EAC3E,IAAI,gBACA,MAAM;EAGV,IAAI;EACJ,IAAI,OAAO,OAAO,UACd,YAAY,MAAuB,SAAS,CAAC,MAAM;OAEnD,YAAY,MAAuB,EAAE,OAAO;EAGhD,MAAM,UAAU,iBAAiB,MAAM,KAAK,QAAQ;EACpD,IAAI,SACA,OAAO,QAAQ,QAAQ,OAAO;OAE9B,OAAO,QAAQ,OAAO,oBAAoB,GAAG,WAAW;CAEhE;CAEA,SAAS,sBAAsB,iBAAwC;EACnE,IAAI,wBAAwB,OACxB,wBAAwB;EAG5B,wBAAwB,QAAQ;EAEhC,sBAAc,MAAM,kBAAkB,kBAAkB,CACpD,sBAAc,MAAM,kBAAkB,mBAAmB,CAAC,GAC1D,gBAAgB,EACpB,EAAE,KAAK;CACX;CAEA,SAAS,0BAAgC;EAErC,IAAI,CAAC,wBAAwB,OACzB;EAIJ,MAAM,OAAO,sBAAc,MAAM,kBAAkB;EACnD,IAAI,MAAM,QAAQ,IAAI,GAAG;GACrB,MAAM,MAAM,KAAK,WAAU,OAAM,OAAO,wBAAwB,MAAM,EAAE;GACxE,IAAI,OAAO,GACP,KAAK,OAAO,KAAK,CAAC;GAEtB,sBAAc,MAAM,kBAAkB,kBAAkB;EAC5D,OACI,sBAAc,MAAM,kBAAkB,kBAAkB,KAAA;EAE5D,wBAAwB,QAAQ;CACpC;CAEA,OAAO;;EAEH;;EAEA;;EAEA;;EAEA;;;;;;EAMA;CACJ;AACJ"}