1 line
40 KiB
Plaintext
1 line
40 KiB
Plaintext
{"version":3,"file":"index.cjs","names":[],"sources":["../src/lib/overlay-manager.ts","../src/lib/overlay-element.ts","../src/lib/editable-element.ts","../src/lib/editable-store.ts","../src/lib/directus-frame.ts","../src/lib/page-manager.ts","../src/index.ts"],"sourcesContent":["export class OverlayManager {\n\tprivate static readonly CSS_VAR_Z_INDEX = '--directus-visual-editing--overlay--z-index';\n\tprivate static readonly CSS_VAR_BORDER_SPACING = '--directus-visual-editing--rect--border-spacing';\n\tprivate static readonly CSS_VAR_BORDER_WIDTH = '--directus-visual-editing--rect--border-width';\n\tprivate static readonly CSS_VAR_BORDER_COLOR = '--directus-visual-editing--rect--border-color';\n\tprivate static readonly CSS_VAR_BORDER_RADIUS = '--directus-visual-editing--rect--border-radius';\n\tprivate static readonly CSS_VAR_HOVER_OPACITY = '--directus-visual-editing--rect-hover--opacity';\n\tprivate static readonly CSS_VAR_HIGHLIGHT_OPACITY = '--directus-visual-editing--rect-highlight--opacity';\n\tprivate static readonly CSS_VAR_ACTIONS_GAP = '--directus-visual-editing--actions--gap';\n\tprivate static readonly CSS_VAR_BUTTON_WIDTH = '--directus-visual-editing--edit-btn--width';\n\tprivate static readonly CSS_VAR_BUTTON_HEIGHT = '--directus-visual-editing--edit-btn--height';\n\tprivate static readonly CSS_VAR_BUTTON_RADIUS = '--directus-visual-editing--edit-btn--radius';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_BG_COLOR = '--directus-visual-editing--edit-btn--bg-color';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--edit-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--edit-btn--icon-bg-size';\n\tprivate static readonly CSS_VAR_AI_BUTTON_BG_COLOR = '--directus-visual-editing--ai-btn--bg-color';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--ai-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--ai-btn--icon-bg-size';\n\n\t// For icons use https://fonts.google.com/icons?icon.set=Material+Icons&icon.color=%23ffffff\n\tprivate static readonly ICON_EDIT = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"%23ffffff\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><path d=\"M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z\"/></svg>')`;\n\tprivate static readonly ICON_AI = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\"><path fill=\"%23ffffff\" d=\"M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z\"/></svg>')`;\n\n\tprivate static readonly OVERLAY_ID = 'directus-visual-editing';\n\tprivate static readonly STYLE_ID = 'directus-visual-editing-style';\n\n\tstatic readonly CONTAINER_RECT_CLASS_NAME = 'directus-visual-editing-overlay';\n\tstatic readonly RECT_CLASS_NAME = 'directus-visual-editing-rect';\n\tstatic readonly RECT_HIGHLIGHT_CLASS_NAME = 'directus-visual-editing-rect-highlight';\n\tstatic readonly RECT_HIGHLIGHT_ACTIVE_CLASS_NAME = 'directus-visual-editing-rect-highlight-active';\n\tstatic readonly RECT_PARENT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-parent-hover';\n\tstatic readonly RECT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-hover';\n\tstatic readonly RECT_INNER_CLASS_NAME = 'directus-visual-editing-rect-inner';\n\tstatic readonly RECT_BUTTON_CLASS_NAME = 'directus-visual-editing-button';\n\tstatic readonly RECT_EDIT_BUTTON_CLASS_NAME = 'directus-visual-editing-edit-button';\n\tstatic readonly RECT_AI_BUTTON_CLASS_NAME = 'directus-visual-editing-ai-button';\n\n\tstatic getGlobalOverlay(): HTMLElement {\n\t\tconst existingOverlay = document.getElementById(OverlayManager.OVERLAY_ID);\n\t\tif (existingOverlay) return existingOverlay;\n\n\t\tconst globalOverlay = document.createElement('div');\n\t\tglobalOverlay.id = OverlayManager.OVERLAY_ID;\n\t\tdocument.body.insertAdjacentElement('afterend', globalOverlay);\n\n\t\treturn globalOverlay;\n\t}\n\n\tstatic addStyles(): void {\n\t\tconst existingStyle = document.getElementById(OverlayManager.STYLE_ID);\n\t\tif (existingStyle) return;\n\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = OverlayManager.STYLE_ID;\n\n\t\tconst buttonSize = 28;\n\t\tconst buttonWidth = `var(${OverlayManager.CSS_VAR_BUTTON_WIDTH}, ${buttonSize}px)`;\n\t\tconst buttonGap = 4;\n\t\tconst editButtonBgColor = `var(${OverlayManager.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`;\n\t\tconst aiButtonBgColor = `var(${OverlayManager.CSS_VAR_AI_BUTTON_BG_COLOR}, ${editButtonBgColor})`;\n\t\tconst buttonBgColorMix = '#2e3C43 25%';\n\t\tconst borderSpacing = `var(${OverlayManager.CSS_VAR_BORDER_SPACING}, ${Math.round(buttonSize * 0.333)}px)`;\n\t\tconst borderWidth = `var(${OverlayManager.CSS_VAR_BORDER_WIDTH}, 2px)`;\n\n\t\tstyle.appendChild(\n\t\t\tdocument.createTextNode(`\n\t\t\t\t#${OverlayManager.OVERLAY_ID} {\n\t\t\t\t\tdisplay: contents;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.CONTAINER_RECT_CLASS_NAME} {\n\t\t\t\t\tpointer-events: none;\n\t\t\t\t\tposition: fixed;\n\t\t\t\t\ttop: 0;\n\t\t\t\t\tleft: 0;\n\t\t\t\t\tright: 0;\n\t\t\t\t\tbottom: 0;\n\t\t\t\t\tz-index: var(${OverlayManager.CSS_VAR_Z_INDEX}, 999999999);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME} {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\ttop: calc(-1 * ${borderSpacing});\n\t\t\t\t\tleft: calc(-1 * ${borderSpacing});\n\t\t\t\t\tright: calc(-1 * ${borderSpacing});\n\t\t\t\t\tbottom: calc(-1 * ${borderSpacing});\n\t\t\t\t\tborder: ${borderWidth} solid var(${OverlayManager.CSS_VAR_BORDER_COLOR}, #6644ff);\n\t\t\t\t\tborder-radius: var(${OverlayManager.CSS_VAR_BORDER_RADIUS}, 6px);\n\t\t\t\t\topacity: 0;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}.${OverlayManager.RECT_HOVER_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\t--hover-opacity: var(${OverlayManager.CSS_VAR_HOVER_OPACITY}, 0.333);\n\t\t\t\t\topacity: var(--hover-opacity);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}.${OverlayManager.RECT_PARENT_HOVER_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\topacity: calc(var(--hover-opacity) / 3);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME} {\n\t\t\t\t\tpointer-events: all;\n\t\t\t\t\tcursor: pointer;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\topacity: var(${OverlayManager.CSS_VAR_HIGHLIGHT_OPACITY}, 0.333);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:visited,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:active,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:focus,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME} {\n\t\t\t\t\tall: initial;\n\t\t\t\t\tpointer-events: all;\n\t\t\t\t\tcursor: pointer;\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tz-index: 1;\n\t\t\t\t\ttop: calc(-1 * ${borderSpacing} + ${borderWidth} / 2);\n\t\t\t\t\ttransform: translate(-50%, -50%);\n\t\t\t\t\twidth: ${buttonWidth};\n\t\t\t\t\theight: var(${OverlayManager.CSS_VAR_BUTTON_HEIGHT}, ${buttonSize}px);\n\t\t\t\t\tborder-radius: var(${OverlayManager.CSS_VAR_BUTTON_RADIUS}, 50%);\n\t\t\t\t\tbackground-position: center;\n\t\t\t\t\tbackground-repeat: no-repeat;\n\t\t\t\t\topacity: 0;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_EDIT_BUTTON_CLASS_NAME} {\n\t\t\t\t\tleft: calc(-1 * ${borderSpacing} + ${borderWidth} / 2);\n\t\t\t\t\tbackground-color: ${editButtonBgColor};\n\t\t\t\t\tbackground-image: var(${OverlayManager.CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE}, ${OverlayManager.ICON_EDIT});\n\t\t\t\t\tbackground-size: var(${OverlayManager.CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE}, 66.6%);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_AI_BUTTON_CLASS_NAME} {\n\t\t\t\t\tleft: calc(-1 * ${borderSpacing} + ${borderWidth} / 2 + ${buttonWidth} + var(${OverlayManager.CSS_VAR_ACTIONS_GAP}, ${buttonGap}px));\n\t\t\t\t\tbackground-color: ${aiButtonBgColor};\n\t\t\t\t\tbackground-image: var(${OverlayManager.CSS_VAR_AI_BUTTON_ICON_BG_IMAGE}, ${OverlayManager.ICON_AI});\n\t\t\t\t\tbackground-size: var(${OverlayManager.CSS_VAR_AI_BUTTON_ICON_BG_SIZE}, 66.6%);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}.${OverlayManager.RECT_HOVER_CLASS_NAME}:not(.${OverlayManager.RECT_PARENT_HOVER_CLASS_NAME}) .${OverlayManager.RECT_BUTTON_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME}:hover .${OverlayManager.RECT_BUTTON_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover ~ .${OverlayManager.RECT_INNER_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME}:hover .${OverlayManager.RECT_INNER_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}:has(.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover) .${OverlayManager.RECT_BUTTON_CLASS_NAME} {\n\t\t\t\t\topacity: 1;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_EDIT_BUTTON_CLASS_NAME}:hover {\n\t\t\t\t\tbackground-color: color-mix(in srgb, ${editButtonBgColor}, ${buttonBgColorMix});\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_AI_BUTTON_CLASS_NAME}:hover {\n\t\t\t\t\tbackground-color: color-mix(in srgb, ${aiButtonBgColor}, ${buttonBgColorMix});\n\t\t\t\t}\n\t\t\t`),\n\t\t);\n\n\t\tdocument.head.appendChild(style);\n\t}\n}\n","import { EditableStore } from './editable-store.ts';\nimport { OverlayManager } from './overlay-manager.ts';\nimport { DirectusFrame } from './directus-frame.ts';\n\nexport class OverlayElement {\n\tprivate hasNoDimensions: boolean = false;\n\tprivate element: HTMLElement;\n\tprivate container: HTMLElement;\n\n\treadonly editButton: HTMLButtonElement;\n\treadonly aiButton: HTMLButtonElement | null;\n\n\tconstructor() {\n\t\tthis.container = this.createContainer();\n\t\tthis.element = this.createElement();\n\t\tthis.editButton = this.createEditButton();\n\t\tthis.aiButton = new DirectusFrame().isAiEnabled() ? this.createAiButton() : null;\n\t\tthis.createRectElement();\n\n\t\tOverlayManager.getGlobalOverlay().appendChild(this.container);\n\n\t\tif (EditableStore.highlightOverlayElements) this.toggleHighlight(true);\n\n\t\tthis.element.addEventListener('click', () => this.editButton.click());\n\t}\n\n\tprivate createContainer() {\n\t\tconst container = document.createElement('div');\n\t\tcontainer.classList.add(OverlayManager.CONTAINER_RECT_CLASS_NAME);\n\t\treturn container;\n\t}\n\n\tprivate createElement() {\n\t\tconst element = document.createElement('div');\n\t\telement.classList.add(OverlayManager.RECT_CLASS_NAME);\n\t\tthis.container.appendChild(element);\n\t\treturn element;\n\t}\n\n\tprivate createRectElement() {\n\t\tconst rectInnerElement = document.createElement('div');\n\t\trectInnerElement.classList.add(OverlayManager.RECT_INNER_CLASS_NAME);\n\t\tthis.element.appendChild(rectInnerElement);\n\t}\n\n\tprivate createEditButton() {\n\t\tconst editButton = document.createElement('button');\n\t\teditButton.type = 'button';\n\t\teditButton.classList.add(OverlayManager.RECT_BUTTON_CLASS_NAME);\n\t\teditButton.classList.add(OverlayManager.RECT_EDIT_BUTTON_CLASS_NAME);\n\t\tthis.element.appendChild(editButton);\n\t\treturn editButton;\n\t}\n\n\tprivate createAiButton() {\n\t\tconst aiButton = document.createElement('button');\n\t\taiButton.type = 'button';\n\t\taiButton.classList.add(OverlayManager.RECT_BUTTON_CLASS_NAME);\n\t\taiButton.classList.add(OverlayManager.RECT_AI_BUTTON_CLASS_NAME);\n\t\tthis.element.appendChild(aiButton);\n\t\treturn aiButton;\n\t}\n\n\tupdateRect(rect: DOMRect) {\n\t\tconst hasDimensions = rect.width !== 0 && rect.height !== 0;\n\n\t\tif (!this.hasNoDimensions && !hasDimensions) {\n\t\t\tthis.hasNoDimensions = true;\n\t\t\tthis.disable();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.hasNoDimensions && hasDimensions) {\n\t\t\tthis.hasNoDimensions = false;\n\t\t\tthis.enable();\n\t\t}\n\n\t\tthis.element.style.width = `${rect.width}px`;\n\t\tthis.element.style.height = `${rect.height}px`;\n\t\tthis.element.style.transform = `translate(${rect.left}px,${rect.top}px)`;\n\t}\n\n\tsetCustomClass(customClass: string | undefined) {\n\t\tif (customClass === undefined) return;\n\n\t\tconst isValidClassName = /^[a-zA-Z_][\\w-]*$/.test(customClass);\n\t\tif (isValidClassName) this.container.classList.add(customClass);\n\t}\n\n\ttoggleHover(hover: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_HOVER_CLASS_NAME, hover);\n\t}\n\n\ttoggleParentHover(hover: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_PARENT_HOVER_CLASS_NAME, hover);\n\t}\n\n\ttoggleHighlight(show: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_HIGHLIGHT_CLASS_NAME, show);\n\t}\n\n\ttoggleHighlightActive(show: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME, show);\n\t}\n\n\tdisable() {\n\t\tthis.element.style.display = 'none';\n\t}\n\n\tenable() {\n\t\tthis.element.style.removeProperty('display');\n\t}\n\n\tremove() {\n\t\tthis.container.remove();\n\t}\n}\n","import observeRect from '@reach/observe-rect';\nimport { DirectusFrame } from './directus-frame.ts';\nimport { EditableStore } from './editable-store.ts';\nimport { OverlayElement } from './overlay-element.ts';\nimport type { EditConfig, EditConfigStrict, EditableElementOptions } from './types/index.ts';\n\nexport class EditableElement {\n\tprivate static readonly DATASET = 'directus';\n\tprivate static readonly DATA_ATTRIBUTE_VALID_KEYS: Array<keyof EditConfig> = ['collection', 'item', 'fields', 'mode'];\n\n\tprivate optionsWritable = true;\n\n\treadonly element: HTMLElement;\n\treadonly key: string; // A unique key to identify editable elements – not to be confused with the primary key\n\treadonly editConfig: EditConfigStrict;\n\treadonly rectObserver: { observe(): void; unobserve(): void };\n\treadonly overlayElement: OverlayElement;\n\n\trect: DOMRect;\n\thover = false;\n\tdisabled = false;\n\tonSaved: EditableElementOptions['onSaved'] = undefined;\n\n\tprivate boundMouseenter: (e: MouseEvent) => void;\n\tprivate boundMouseleave: (e: MouseEvent) => void;\n\n\tconstructor(element: HTMLElement) {\n\t\tthis.element = element;\n\t\tthis.boundMouseenter = this.onMouseenter.bind(this);\n\t\tthis.boundMouseleave = this.onMouseleave.bind(this);\n\t\tthis.element.addEventListener('mouseenter', this.boundMouseenter);\n\t\tthis.element.addEventListener('mouseleave', this.boundMouseleave);\n\n\t\tthis.key = crypto.randomUUID();\n\t\tthis.editConfig = EditableElement.editAttrToObject(this.element.dataset[EditableElement.DATASET]!);\n\n\t\tthis.rect = this.element.getBoundingClientRect();\n\t\tthis.overlayElement = new OverlayElement();\n\t\tthis.overlayElement.updateRect(this.rect);\n\t\tthis.overlayElement.editButton.addEventListener('click', this.onClickEdit.bind(this));\n\t\tthis.overlayElement.aiButton?.addEventListener('click', this.onClickAddToContext.bind(this));\n\n\t\t// @ts-expect-error\n\t\tthis.rectObserver = observeRect(this.element, this.onObserveRect.bind(this));\n\t\tthis.rectObserver.observe();\n\t}\n\n\tstatic query(elements: HTMLElement | HTMLElement[] | undefined | null) {\n\t\tif (!elements) return Array.from(document.querySelectorAll(`[data-${EditableElement.DATASET}]`)) as HTMLElement[];\n\n\t\tconst elementsArray = Array.isArray(elements) ? elements : [elements];\n\t\treturn elementsArray\n\t\t\t.filter((element) => element instanceof HTMLElement)\n\t\t\t.flatMap((element) => {\n\t\t\t\tif (element.dataset[EditableElement.DATASET] !== undefined) return element;\n\t\t\t\tconst childrenElements = Array.from(element.querySelectorAll(`[data-${EditableElement.DATASET}]`));\n\t\t\t\treturn childrenElements as HTMLElement[];\n\t\t\t})\n\t\t\t.filter((element) => element !== null);\n\t}\n\n\tstatic objectToEditAttr(editConfig: EditConfig): string {\n\t\tconst dataAttr: string[] = [];\n\n\t\tfor (const [key, value] of Object.entries(editConfig)) {\n\t\t\tif (!EditableElement.validEditConfigKey(key as keyof EditConfig)) continue;\n\n\t\t\tif (key === 'fields' && Array.isArray(value)) {\n\t\t\t\tdataAttr.push(`${key}:${value.join(',')}`);\n\t\t\t} else {\n\t\t\t\tdataAttr.push(`${key}:${value}`);\n\t\t\t}\n\t\t}\n\n\t\treturn dataAttr.join(';');\n\t}\n\n\tprivate static editAttrToObject(str: string) {\n\t\tconst pairs = str.split(';');\n\t\tconst result: Record<string, any> = {};\n\n\t\tpairs.forEach((pair) => {\n\t\t\tconst keyValue = pair.split(':');\n\t\t\tif (keyValue[0] === undefined || keyValue?.[1] === undefined) return;\n\n\t\t\tconst key = keyValue[0].trim() as keyof EditConfig;\n\t\t\tif (!EditableElement.validEditConfigKey(key)) return;\n\n\t\t\tconst value = keyValue[1];\n\n\t\t\tif (key === 'fields') {\n\t\t\t\tresult['fields'] = value.split(',').map((field) => field.trim());\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tresult[key] = value.trim();\n\t\t});\n\n\t\treturn result as EditConfigStrict;\n\t}\n\n\tprivate static validEditConfigKey(key: keyof EditConfig) {\n\t\treturn EditableElement.DATA_ATTRIBUTE_VALID_KEYS.includes(key);\n\t}\n\n\tapplyOptions({ customClass, onSaved }: EditableElementOptions, elementsSpecified = false) {\n\t\tif (!this.optionsWritable) return;\n\t\tif (elementsSpecified) this.optionsWritable = false;\n\t\tthis.overlayElement.setCustomClass(customClass);\n\t\tif (onSaved !== undefined) this.onSaved = onSaved;\n\t}\n\n\tremoveHoverListener() {\n\t\tthis.element.removeEventListener('mouseenter', this.boundMouseenter);\n\t\tthis.element.removeEventListener('mouseleave', this.boundMouseleave);\n\t}\n\n\tprivate onClickEdit() {\n\t\tnew DirectusFrame().send('edit', { key: this.key, editConfig: this.editConfig, rect: this.rect });\n\t}\n\n\tprivate onClickAddToContext(event: MouseEvent) {\n\t\tevent.stopPropagation();\n\t\tnew DirectusFrame().send('addToContext', { key: this.key, editConfig: this.editConfig, rect: this.rect });\n\t}\n\n\tprivate onMouseenter(event: MouseEvent) {\n\t\tthis.toggleItemHover(true, event);\n\t}\n\n\tprivate onMouseleave(event: MouseEvent) {\n\t\tthis.toggleItemHover(false, event);\n\t}\n\n\tprivate toggleItemHover(hover: boolean, event: MouseEvent) {\n\t\tif (this.element !== event.currentTarget || this.hover === hover) return;\n\n\t\tthis.hover = hover;\n\t\tthis.setParentsHover();\n\t\tthis.overlayElement.toggleHover(hover);\n\t}\n\n\tprivate setParentsHover() {\n\t\tconst hoveredItems = EditableStore.getHoveredItems();\n\n\t\thoveredItems.forEach((hoveredItem) => {\n\t\t\tconst otherElements = hoveredItems.filter((item) => item.element !== hoveredItem.element);\n\t\t\tconst isParentElement = otherElements.some((el) => hoveredItem.element.contains(el.element));\n\n\t\t\thoveredItem.overlayElement.toggleParentHover(isParentElement);\n\t\t});\n\t}\n\n\tprivate onObserveRect(rect: DOMRect) {\n\t\tif (this.disabled) return;\n\t\tthis.rect = rect;\n\t\tthis.overlayElement.updateRect(rect);\n\t}\n}\n","import { EditableElement } from './editable-element.ts';\n\nexport class EditableStore {\n\tprivate static items: EditableElement[] = [];\n\tstatic highlightOverlayElements = false;\n\tprivate static highlightedKey: string | null = null;\n\n\tstatic getItem(element: Element) {\n\t\treturn EditableStore.items.find((item) => item.element === element);\n\t}\n\n\tstatic getItemByKey(key: EditableElement['key']) {\n\t\treturn EditableStore.items.find((item) => item.key === key);\n\t}\n\n\tstatic getItemByEditConfig(collection: string, item: string | number, fields?: string[]) {\n\t\treturn EditableStore.items.find((i) => {\n\t\t\tif (i.editConfig.collection !== collection) return false;\n\t\t\tif (String(i.editConfig.item) !== String(item)) return false;\n\n\t\t\tconst itemFields = i.editConfig.fields ?? [];\n\t\t\tconst targetFields = fields ?? [];\n\n\t\t\tif (itemFields.length !== targetFields.length) return false;\n\n\t\t\treturn itemFields.every((f) => targetFields.includes(f));\n\t\t});\n\t}\n\n\tstatic getHoveredItems() {\n\t\treturn EditableStore.items.filter((item) => item.hover);\n\t}\n\n\tstatic addItem(item: EditableElement) {\n\t\tEditableStore.items.push(item);\n\t}\n\n\tstatic enableItems(selectedItems?: EditableElement[]) {\n\t\tconst items = selectedItems ?? EditableStore.items;\n\n\t\titems.forEach((item) => {\n\t\t\titem.disabled = false;\n\t\t\titem.rectObserver.observe();\n\t\t\titem.overlayElement.enable();\n\t\t});\n\t}\n\n\tstatic disableItems(selectedItems?: EditableElement[]) {\n\t\tconst items = selectedItems ?? EditableStore.items.filter((item) => !item.disabled);\n\n\t\titems.forEach((item) => {\n\t\t\titem.disabled = true;\n\t\t\titem.hover = false;\n\t\t\titem.rectObserver.unobserve();\n\t\t\titem.overlayElement.disable();\n\t\t});\n\n\t\treturn [...items];\n\t}\n\n\tstatic removeItems(selectedItems?: EditableElement[]) {\n\t\tconst items = selectedItems ?? EditableStore.items;\n\n\t\titems.forEach((item) => {\n\t\t\titem.rectObserver.unobserve();\n\t\t\titem.overlayElement.remove();\n\t\t\titem.removeHoverListener();\n\t\t});\n\n\t\tEditableStore.items = EditableStore.items.filter((item) => !items.includes(item));\n\t}\n\n\tstatic highlightItems(show: boolean) {\n\t\tif (this.highlightOverlayElements === show) return;\n\n\t\tthis.highlightOverlayElements = show;\n\n\t\tEditableStore.items.forEach((item) => {\n\t\t\titem.overlayElement.toggleHighlight(show);\n\t\t});\n\t}\n\n\tstatic highlightElement(\n\t\tidentifier: { key: string } | { collection: string; item: string | number; fields?: string[] } | null,\n\t) {\n\t\tif (this.highlightedKey !== null) {\n\t\t\tEditableStore.getItemByKey(this.highlightedKey)?.overlayElement.toggleHighlightActive(false);\n\t\t}\n\n\t\tif (identifier === null) {\n\t\t\tthis.highlightedKey = null;\n\t\t\treturn;\n\t\t}\n\n\t\tlet element: EditableElement | undefined;\n\n\t\tif ('key' in identifier) {\n\t\t\telement = EditableStore.getItemByKey(identifier.key);\n\t\t} else {\n\t\t\telement = EditableStore.getItemByEditConfig(identifier.collection, identifier.item, identifier.fields);\n\t\t}\n\n\t\tif (element) {\n\t\t\tthis.highlightedKey = element.key;\n\t\t\telement.overlayElement.toggleHighlightActive(true);\n\t\t} else {\n\t\t\tthis.highlightedKey = null;\n\t\t}\n\t}\n}\n","import { EditableStore } from './editable-store.ts';\nimport type { HighlightElementData, ConfirmData, SendAction, ReceiveData, SavedData } from './types/index.ts';\n\n/**\n * *Singleton* class to handle communication with Directus in parent frame.\n */\nexport class DirectusFrame {\n\tprivate static SINGLETON?: DirectusFrame;\n\tprivate static readonly ERROR_PARENT_NOT_FOUND = 'Error sending message to Directus in parent frame:';\n\n\tprivate origin: string | null = null;\n\tprivate confirmed = false;\n\tprivate aiEnabled = false;\n\n\tconstructor() {\n\t\tif (DirectusFrame.SINGLETON) return DirectusFrame.SINGLETON;\n\t\tDirectusFrame.SINGLETON = this;\n\n\t\twindow?.addEventListener('message', this.receive.bind(this));\n\t}\n\n\tconnect(origin: string) {\n\t\tthis.origin = origin;\n\t\treturn this.send('connect');\n\t}\n\n\tsend(action: SendAction, data?: unknown) {\n\t\ttry {\n\t\t\tif (!this.origin) throw new Error();\n\t\t\twindow.parent.postMessage({ action, data }, this.origin);\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\t// eslint-disable-next-line\n\t\t\tconsole.error(DirectusFrame.ERROR_PARENT_NOT_FOUND, error);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate sameOrigin(origin: string, url: string) {\n\t\ttry {\n\t\t\treturn origin === new URL(url).origin;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treceive(event: MessageEvent) {\n\t\tif (!this.origin || !this.sameOrigin(event.origin, this.origin)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { action, data }: ReceiveData = event.data;\n\n\t\tif (action === 'confirm') this.receiveConfirmAction(data);\n\t\tif (action === 'showEditableElements') this.receiveShowEditableElements(data);\n\t\tif (action === 'saved') this.receiveSaved(data);\n\t\tif (action === 'highlightElement') this.receiveHighlightElement(data);\n\t}\n\n\tprivate receiveConfirmAction(data: unknown) {\n\t\tthis.confirmed = true;\n\t\tthis.aiEnabled = !!(data as ConfirmData)?.aiEnabled;\n\t}\n\n\tisAiEnabled() {\n\t\treturn this.aiEnabled;\n\t}\n\n\treceiveConfirm() {\n\t\tlet attempts = 0;\n\t\tconst maxAttempts = 10;\n\t\tconst timeout = 100;\n\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tconst checkConfirmed = () => {\n\t\t\t\tif (attempts >= maxAttempts) return resolve(false);\n\t\t\t\tattempts++;\n\n\t\t\t\tif (this.confirmed) resolve(true);\n\t\t\t\telse setTimeout(checkConfirmed, timeout);\n\t\t\t};\n\n\t\t\tcheckConfirmed();\n\t\t});\n\t}\n\n\tprivate receiveShowEditableElements(data: unknown) {\n\t\tconst show = !!data;\n\t\tEditableStore.highlightItems(show);\n\t}\n\n\tprivate receiveSaved(data: unknown) {\n\t\tconst { key = '', collection = '', item = null, payload = {} } = data as SavedData;\n\n\t\tconst storeItem = EditableStore.getItemByKey(key);\n\n\t\tif (storeItem && collection && typeof storeItem.onSaved === 'function') {\n\t\t\tstoreItem.onSaved({ collection, item, payload });\n\t\t\treturn;\n\t\t}\n\n\t\twindow.location.reload();\n\t}\n\n\tprivate receiveHighlightElement(data: unknown) {\n\t\tif (!data || typeof data !== 'object') {\n\t\t\tEditableStore.highlightElement(null);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { key, collection, item, fields } = data as HighlightElementData;\n\n\t\tif (key === null) {\n\t\t\t// Clear highlight (edit overlay closed or AI store emits null)\n\t\t\tEditableStore.highlightElement(null);\n\t\t} else if (collection && item !== undefined) {\n\t\t\t// Key absent, collection+item present: AI context panel hover\n\t\t\t// Looks up via getItemByEditConfig(). fields included for relational/multi-field items\n\t\t\tEditableStore.highlightElement(fields ? { collection, item, fields } : { collection, item });\n\t\t} else if (typeof key === 'string') {\n\t\t\t// Key of type string = UUID from editable-element.ts, looks up via getItemByKey()\n\t\t\tEditableStore.highlightElement({ key });\n\t\t}\n\t}\n}\n","export class PageManager {\n\tprivate static navigationInitialized = false;\n\n\tstatic onNavigation(callback: (data: { url: string; title: string }) => void) {\n\t\tif (PageManager.navigationInitialized) return;\n\n\t\tlet lastUrl = '';\n\t\tlet lastTitle = '';\n\t\tlet debounceId: number;\n\n\t\tconst debounce = (debounceFunction: () => void) => {\n\t\t\tclearTimeout(debounceId);\n\t\t\tdebounceId = setTimeout(debounceFunction, 100);\n\t\t};\n\n\t\tconst observeNavigation = () => {\n\t\t\tconst url = window.location.href;\n\t\t\tconst title = document.title;\n\t\t\tconst changesDetected = lastUrl !== url || lastTitle !== title;\n\n\t\t\tif (changesDetected) {\n\t\t\t\tdebounce(() => callback({ url, title }));\n\t\t\t\tlastUrl = url;\n\t\t\t\tlastTitle = title;\n\t\t\t}\n\n\t\t\tsetTimeout(observeNavigation, changesDetected ? 50 : 200);\n\t\t};\n\n\t\tobserveNavigation();\n\n\t\tPageManager.navigationInitialized = true;\n\t}\n}\n","import { DirectusFrame } from './lib/directus-frame.ts';\nimport { EditableElement } from './lib/editable-element.ts';\nimport { EditableStore } from './lib/editable-store.ts';\nimport { OverlayManager } from './lib/overlay-manager.ts';\nimport { PageManager } from './lib/page-manager.ts';\nimport type { EditConfig, EditableElementOptions } from './lib/types/index.ts';\n\nexport async function apply({\n\tdirectusUrl,\n\telements = undefined,\n\tcustomClass = undefined,\n\tonSaved = undefined,\n}: {\n\tdirectusUrl: string;\n\telements?: HTMLElement | HTMLElement[] | null;\n} & EditableElementOptions) {\n\tconst directusFrame = new DirectusFrame();\n\tconst connected = directusFrame.connect(directusUrl);\n\tif (!connected) return;\n\n\tconst confirmed = await directusFrame.receiveConfirm();\n\tif (!confirmed) return;\n\n\tPageManager.onNavigation((data) => directusFrame.send('navigation', data));\n\tOverlayManager.addStyles();\n\n\tconst editableElements = EditableElement.query(elements);\n\tconst scopedItems: EditableElement[] = [];\n\n\teditableElements.forEach((element) => {\n\t\tconst existingItem = EditableStore.getItem(element);\n\t\tconst item = existingItem ?? new EditableElement(element);\n\n\t\titem.applyOptions({ customClass, onSaved }, !!elements);\n\n\t\tscopedItems.push(item);\n\t\tif (!existingItem) EditableStore.addItem(item);\n\t});\n\n\treturn {\n\t\tremove() {\n\t\t\tEditableStore.removeItems(scopedItems);\n\t\t},\n\t\tenable() {\n\t\t\tEditableStore.enableItems(scopedItems);\n\t\t},\n\t\tdisable() {\n\t\t\tEditableStore.disableItems(scopedItems);\n\t\t},\n\t};\n}\n\nexport function remove() {\n\tEditableStore.removeItems();\n}\n\nexport function disable() {\n\tconst items = EditableStore.disableItems();\n\treturn {\n\t\tenable() {\n\t\t\tEditableStore.enableItems(items);\n\t\t},\n\t};\n}\n\nexport function setAttr(editConfig: EditConfig) {\n\treturn EditableElement.objectToEditAttr(editConfig);\n}\n"],"mappings":"0gBAAA,IAAa,EAAb,MAAa,CAAe,CAC3B,OAAwB,gBAAkB,8CAC1C,OAAwB,uBAAyB,kDACjD,OAAwB,qBAAuB,gDAC/C,OAAwB,qBAAuB,gDAC/C,OAAwB,sBAAwB,iDAChD,OAAwB,sBAAwB,iDAChD,OAAwB,0BAA4B,qDACpD,OAAwB,oBAAsB,0CAC9C,OAAwB,qBAAuB,6CAC/C,OAAwB,sBAAwB,8CAChD,OAAwB,sBAAwB,8CAChD,OAAwB,6BAA+B,gDACvD,OAAwB,kCAAoC,qDAC5D,OAAwB,iCAAmC,oDAC3D,OAAwB,2BAA6B,8CACrD,OAAwB,gCAAkC,mDAC1D,OAAwB,+BAAiC,kDAGzD,OAAwB,UAAY,8YACpC,OAAwB,QAAU,uWAElC,OAAwB,WAAa,0BACrC,OAAwB,SAAW,gCAEnC,OAAgB,0BAA4B,kCAC5C,OAAgB,gBAAkB,+BAClC,OAAgB,0BAA4B,yCAC5C,OAAgB,iCAAmC,gDACnD,OAAgB,6BAA+B,4CAC/C,OAAgB,sBAAwB,qCACxC,OAAgB,sBAAwB,qCACxC,OAAgB,uBAAyB,iCACzC,OAAgB,4BAA8B,sCAC9C,OAAgB,0BAA4B,oCAE5C,OAAO,kBAAgC,CACtC,IAAM,EAAkB,SAAS,eAAe,EAAe,WAAW,CAC1E,GAAI,EAAiB,OAAO,EAE5B,IAAM,EAAgB,SAAS,cAAc,MAAM,CAInD,MAHA,GAAc,GAAK,EAAe,WAClC,SAAS,KAAK,sBAAsB,WAAY,EAAc,CAEvD,EAGR,OAAO,WAAkB,CAExB,GADsB,SAAS,eAAe,EAAe,SAAS,CACnD,OAEnB,IAAM,EAAQ,SAAS,cAAc,QAAQ,CAC7C,EAAM,GAAK,EAAe,SAE1B,IACM,EAAc,OAAO,EAAe,qBAAqB,SAEzD,EAAoB,OAAO,EAAe,6BAA6B,YACvE,EAAkB,OAAO,EAAe,2BAA2B,IAAI,EAAkB,GACzF,EAAmB,cACnB,EAAgB,OAAO,EAAe,uBAAuB,QAC7D,EAAc,OAAO,EAAe,qBAAqB,QAE/D,EAAM,YACL,SAAS,eAAe;OACpB,EAAe,WAAW;;;OAG1B,EAAe,0BAA0B;;;;;;;oBAO5B,EAAe,gBAAgB;;OAE5C,EAAe,gBAAgB;;;OAG/B,EAAe,sBAAsB;;;sBAGtB,EAAc;uBACb,EAAc;wBACb,EAAc;yBACb,EAAc;eACxB,EAAY,aAAa,EAAe,qBAAqB;0BAClD,EAAe,sBAAsB;;;OAGxD,EAAe,gBAAgB,GAAG,EAAe,sBAAsB,IAAI,EAAe,sBAAsB;4BAC3F,EAAe,sBAAsB;;;OAG1D,EAAe,gBAAgB,GAAG,EAAe,6BAA6B,IAAI,EAAe,sBAAsB;;;OAGvH,EAAe,0BAA0B;;;;OAIzC,EAAe,0BAA0B,IAAI,EAAe,sBAAsB;oBACrE,EAAe,0BAA0B;;OAEtD,EAAe,uBAAuB;OACtC,EAAe,uBAAuB;OACtC,EAAe,uBAAuB;OACtC,EAAe,uBAAuB;OACtC,EAAe,uBAAuB;;;;;;sBAMvB,EAAc,KAAK,EAAY;;cAEvC,EAAY;mBACP,EAAe,sBAAsB;0BAC9B,EAAe,sBAAsB;;;;;OAKxD,EAAe,uBAAuB,GAAG,EAAe,4BAA4B;uBACpE,EAAc,KAAK,EAAY;yBAC7B,EAAkB;6BACd,EAAe,kCAAkC,IAAI,EAAe,UAAU;4BAC/E,EAAe,iCAAiC;;OAErE,EAAe,uBAAuB,GAAG,EAAe,0BAA0B;uBAClE,EAAc,KAAK,EAAY,SAAS,EAAY,SAAS,EAAe,oBAAoB;yBAC9F,EAAgB;6BACZ,EAAe,gCAAgC,IAAI,EAAe,QAAQ;4BAC3E,EAAe,+BAA+B;;OAEnE,EAAe,gBAAgB,GAAG,EAAe,sBAAsB,QAAQ,EAAe,6BAA6B,KAAK,EAAe,uBAAuB;OACtK,EAAe,iCAAiC,IAAI,EAAe,sBAAsB;OACzF,EAAe,0BAA0B,UAAU,EAAe,uBAAuB;OACzF,EAAe,uBAAuB;OACtC,EAAe,uBAAuB,YAAY,EAAe,sBAAsB;OACvF,EAAe,0BAA0B,UAAU,EAAe,sBAAsB;OACxF,EAAe,gBAAgB,QAAQ,EAAe,uBAAuB,WAAW,EAAe,uBAAuB;;;OAG9H,EAAe,uBAAuB,GAAG,EAAe,4BAA4B;4CAC/C,EAAkB,IAAI,EAAiB;;OAE5E,EAAe,uBAAuB,GAAG,EAAe,0BAA0B;4CAC7C,EAAgB,IAAI,EAAiB;;KAE5E,CACF,CAED,SAAS,KAAK,YAAY,EAAM,GCvJrB,EAAb,KAA4B,CAC3B,gBAAmC,GACnC,QACA,UAEA,WACA,SAEA,aAAc,CACb,KAAK,UAAY,KAAK,iBAAiB,CACvC,KAAK,QAAU,KAAK,eAAe,CACnC,KAAK,WAAa,KAAK,kBAAkB,CACzC,KAAK,SAAW,IAAI,GAAe,CAAC,aAAa,CAAG,KAAK,gBAAgB,CAAG,KAC5E,KAAK,mBAAmB,CAExB,EAAe,kBAAkB,CAAC,YAAY,KAAK,UAAU,CAEzD,EAAc,0BAA0B,KAAK,gBAAgB,GAAK,CAEtE,KAAK,QAAQ,iBAAiB,YAAe,KAAK,WAAW,OAAO,CAAC,CAGtE,iBAA0B,CACzB,IAAM,EAAY,SAAS,cAAc,MAAM,CAE/C,OADA,EAAU,UAAU,IAAI,EAAe,0BAA0B,CAC1D,EAGR,eAAwB,CACvB,IAAM,EAAU,SAAS,cAAc,MAAM,CAG7C,OAFA,EAAQ,UAAU,IAAI,EAAe,gBAAgB,CACrD,KAAK,UAAU,YAAY,EAAQ,CAC5B,EAGR,mBAA4B,CAC3B,IAAM,EAAmB,SAAS,cAAc,MAAM,CACtD,EAAiB,UAAU,IAAI,EAAe,sBAAsB,CACpE,KAAK,QAAQ,YAAY,EAAiB,CAG3C,kBAA2B,CAC1B,IAAM,EAAa,SAAS,cAAc,SAAS,CAKnD,MAJA,GAAW,KAAO,SAClB,EAAW,UAAU,IAAI,EAAe,uBAAuB,CAC/D,EAAW,UAAU,IAAI,EAAe,4BAA4B,CACpE,KAAK,QAAQ,YAAY,EAAW,CAC7B,EAGR,gBAAyB,CACxB,IAAM,EAAW,SAAS,cAAc,SAAS,CAKjD,MAJA,GAAS,KAAO,SAChB,EAAS,UAAU,IAAI,EAAe,uBAAuB,CAC7D,EAAS,UAAU,IAAI,EAAe,0BAA0B,CAChE,KAAK,QAAQ,YAAY,EAAS,CAC3B,EAGR,WAAW,EAAe,CACzB,IAAM,EAAgB,EAAK,QAAU,GAAK,EAAK,SAAW,EAE1D,GAAI,CAAC,KAAK,iBAAmB,CAAC,EAAe,CAC5C,KAAK,gBAAkB,GACvB,KAAK,SAAS,CACd,OAGG,KAAK,iBAAmB,IAC3B,KAAK,gBAAkB,GACvB,KAAK,QAAQ,EAGd,KAAK,QAAQ,MAAM,MAAQ,GAAG,EAAK,MAAM,IACzC,KAAK,QAAQ,MAAM,OAAS,GAAG,EAAK,OAAO,IAC3C,KAAK,QAAQ,MAAM,UAAY,aAAa,EAAK,KAAK,KAAK,EAAK,IAAI,KAGrE,eAAe,EAAiC,CAC3C,IAAgB,IAAA,IAEK,oBAAoB,KAAK,EAAY,EACxC,KAAK,UAAU,UAAU,IAAI,EAAY,CAGhE,YAAY,EAAgB,CAC3B,KAAK,QAAQ,UAAU,OAAO,EAAe,sBAAuB,EAAM,CAG3E,kBAAkB,EAAgB,CACjC,KAAK,QAAQ,UAAU,OAAO,EAAe,6BAA8B,EAAM,CAGlF,gBAAgB,EAAe,CAC9B,KAAK,QAAQ,UAAU,OAAO,EAAe,0BAA2B,EAAK,CAG9E,sBAAsB,EAAe,CACpC,KAAK,QAAQ,UAAU,OAAO,EAAe,iCAAkC,EAAK,CAGrF,SAAU,CACT,KAAK,QAAQ,MAAM,QAAU,OAG9B,QAAS,CACR,KAAK,QAAQ,MAAM,eAAe,UAAU,CAG7C,QAAS,CACR,KAAK,UAAU,QAAQ,GC5GZ,EAAb,MAAa,CAAgB,CAC5B,OAAwB,QAAU,WAClC,OAAwB,0BAAqD,CAAC,aAAc,OAAQ,SAAU,OAAO,CAErH,gBAA0B,GAE1B,QACA,IACA,WACA,aACA,eAEA,KACA,MAAQ,GACR,SAAW,GACX,QAA6C,IAAA,GAE7C,gBACA,gBAEA,YAAY,EAAsB,CACjC,KAAK,QAAU,EACf,KAAK,gBAAkB,KAAK,aAAa,KAAK,KAAK,CACnD,KAAK,gBAAkB,KAAK,aAAa,KAAK,KAAK,CACnD,KAAK,QAAQ,iBAAiB,aAAc,KAAK,gBAAgB,CACjE,KAAK,QAAQ,iBAAiB,aAAc,KAAK,gBAAgB,CAEjE,KAAK,IAAM,OAAO,YAAY,CAC9B,KAAK,WAAa,EAAgB,iBAAiB,KAAK,QAAQ,QAAQ,EAAgB,SAAU,CAElG,KAAK,KAAO,KAAK,QAAQ,uBAAuB,CAChD,KAAK,eAAiB,IAAI,EAC1B,KAAK,eAAe,WAAW,KAAK,KAAK,CACzC,KAAK,eAAe,WAAW,iBAAiB,QAAS,KAAK,YAAY,KAAK,KAAK,CAAC,CACrF,KAAK,eAAe,UAAU,iBAAiB,QAAS,KAAK,oBAAoB,KAAK,KAAK,CAAC,CAG5F,KAAK,cAAA,EAAA,EAAA,SAA2B,KAAK,QAAS,KAAK,cAAc,KAAK,KAAK,CAAC,CAC5E,KAAK,aAAa,SAAS,CAG5B,OAAO,MAAM,EAA0D,CAItE,OAHK,GAEiB,MAAM,QAAQ,EAAS,CAAG,EAAW,CAAC,EAAS,EAEnE,OAAQ,GAAY,aAAmB,YAAY,CACnD,QAAS,GACL,EAAQ,QAAQ,EAAgB,WAAa,IAAA,GACxB,MAAM,KAAK,EAAQ,iBAAiB,SAAS,EAAgB,QAAQ,GAAG,CAAC,CAD/B,EAGlE,CACD,OAAQ,GAAY,IAAY,KAAK,CAVjB,MAAM,KAAK,SAAS,iBAAiB,SAAS,EAAgB,QAAQ,GAAG,CAAC,CAajG,OAAO,iBAAiB,EAAgC,CACvD,IAAM,EAAqB,EAAE,CAE7B,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAW,CAC/C,EAAgB,mBAAmB,EAAwB,GAE5D,IAAQ,UAAY,MAAM,QAAQ,EAAM,CAC3C,EAAS,KAAK,GAAG,EAAI,GAAG,EAAM,KAAK,IAAI,GAAG,CAE1C,EAAS,KAAK,GAAG,EAAI,GAAG,IAAQ,EAIlC,OAAO,EAAS,KAAK,IAAI,CAG1B,OAAe,iBAAiB,EAAa,CAC5C,IAAM,EAAQ,EAAI,MAAM,IAAI,CACtB,EAA8B,EAAE,CAmBtC,OAjBA,EAAM,QAAS,GAAS,CACvB,IAAM,EAAW,EAAK,MAAM,IAAI,CAChC,GAAI,EAAS,KAAO,IAAA,IAAa,IAAW,KAAO,IAAA,GAAW,OAE9D,IAAM,EAAM,EAAS,GAAG,MAAM,CAC9B,GAAI,CAAC,EAAgB,mBAAmB,EAAI,CAAE,OAE9C,IAAM,EAAQ,EAAS,GAEvB,GAAI,IAAQ,SAAU,CACrB,EAAO,OAAY,EAAM,MAAM,IAAI,CAAC,IAAK,GAAU,EAAM,MAAM,CAAC,CAChE,OAGD,EAAO,GAAO,EAAM,MAAM,EACzB,CAEK,EAGR,OAAe,mBAAmB,EAAuB,CACxD,OAAO,EAAgB,0BAA0B,SAAS,EAAI,CAG/D,aAAa,CAAE,cAAa,WAAmC,EAAoB,GAAO,CACpF,KAAK,kBACN,IAAmB,KAAK,gBAAkB,IAC9C,KAAK,eAAe,eAAe,EAAY,CAC3C,IAAY,IAAA,KAAW,KAAK,QAAU,IAG3C,qBAAsB,CACrB,KAAK,QAAQ,oBAAoB,aAAc,KAAK,gBAAgB,CACpE,KAAK,QAAQ,oBAAoB,aAAc,KAAK,gBAAgB,CAGrE,aAAsB,CACrB,IAAI,GAAe,CAAC,KAAK,OAAQ,CAAE,IAAK,KAAK,IAAK,WAAY,KAAK,WAAY,KAAM,KAAK,KAAM,CAAC,CAGlG,oBAA4B,EAAmB,CAC9C,EAAM,iBAAiB,CACvB,IAAI,GAAe,CAAC,KAAK,eAAgB,CAAE,IAAK,KAAK,IAAK,WAAY,KAAK,WAAY,KAAM,KAAK,KAAM,CAAC,CAG1G,aAAqB,EAAmB,CACvC,KAAK,gBAAgB,GAAM,EAAM,CAGlC,aAAqB,EAAmB,CACvC,KAAK,gBAAgB,GAAO,EAAM,CAGnC,gBAAwB,EAAgB,EAAmB,CACtD,KAAK,UAAY,EAAM,eAAiB,KAAK,QAAU,IAE3D,KAAK,MAAQ,EACb,KAAK,iBAAiB,CACtB,KAAK,eAAe,YAAY,EAAM,EAGvC,iBAA0B,CACzB,IAAM,EAAe,EAAc,iBAAiB,CAEpD,EAAa,QAAS,GAAgB,CAErC,IAAM,EADgB,EAAa,OAAQ,GAAS,EAAK,UAAY,EAAY,QAAQ,CACnD,KAAM,GAAO,EAAY,QAAQ,SAAS,EAAG,QAAQ,CAAC,CAE5F,EAAY,eAAe,kBAAkB,EAAgB,EAC5D,CAGH,cAAsB,EAAe,CAChC,KAAK,WACT,KAAK,KAAO,EACZ,KAAK,eAAe,WAAW,EAAK,IC1JzB,EAAb,MAAa,CAAc,CAC1B,OAAe,MAA2B,EAAE,CAC5C,OAAO,yBAA2B,GAClC,OAAe,eAAgC,KAE/C,OAAO,QAAQ,EAAkB,CAChC,OAAO,EAAc,MAAM,KAAM,GAAS,EAAK,UAAY,EAAQ,CAGpE,OAAO,aAAa,EAA6B,CAChD,OAAO,EAAc,MAAM,KAAM,GAAS,EAAK,MAAQ,EAAI,CAG5D,OAAO,oBAAoB,EAAoB,EAAuB,EAAmB,CACxF,OAAO,EAAc,MAAM,KAAM,GAAM,CAEtC,GADI,EAAE,WAAW,aAAe,GAC5B,OAAO,EAAE,WAAW,KAAK,GAAK,OAAO,EAAK,CAAE,MAAO,GAEvD,IAAM,EAAa,EAAE,WAAW,QAAU,EAAE,CACtC,EAAe,GAAU,EAAE,CAIjC,OAFI,EAAW,SAAW,EAAa,OAEhC,EAAW,MAAO,GAAM,EAAa,SAAS,EAAE,CAAC,CAFF,IAGrD,CAGH,OAAO,iBAAkB,CACxB,OAAO,EAAc,MAAM,OAAQ,GAAS,EAAK,MAAM,CAGxD,OAAO,QAAQ,EAAuB,CACrC,EAAc,MAAM,KAAK,EAAK,CAG/B,OAAO,YAAY,EAAmC,EACvC,GAAiB,EAAc,OAEvC,QAAS,GAAS,CACvB,EAAK,SAAW,GAChB,EAAK,aAAa,SAAS,CAC3B,EAAK,eAAe,QAAQ,EAC3B,CAGH,OAAO,aAAa,EAAmC,CACtD,IAAM,EAAQ,GAAiB,EAAc,MAAM,OAAQ,GAAS,CAAC,EAAK,SAAS,CASnF,OAPA,EAAM,QAAS,GAAS,CACvB,EAAK,SAAW,GAChB,EAAK,MAAQ,GACb,EAAK,aAAa,WAAW,CAC7B,EAAK,eAAe,SAAS,EAC5B,CAEK,CAAC,GAAG,EAAM,CAGlB,OAAO,YAAY,EAAmC,CACrD,IAAM,EAAQ,GAAiB,EAAc,MAE7C,EAAM,QAAS,GAAS,CACvB,EAAK,aAAa,WAAW,CAC7B,EAAK,eAAe,QAAQ,CAC5B,EAAK,qBAAqB,EACzB,CAEF,EAAc,MAAQ,EAAc,MAAM,OAAQ,GAAS,CAAC,EAAM,SAAS,EAAK,CAAC,CAGlF,OAAO,eAAe,EAAe,CAChC,KAAK,2BAA6B,IAEtC,KAAK,yBAA2B,EAEhC,EAAc,MAAM,QAAS,GAAS,CACrC,EAAK,eAAe,gBAAgB,EAAK,EACxC,EAGH,OAAO,iBACN,EACC,CAKD,GAJI,KAAK,iBAAmB,MAC3B,EAAc,aAAa,KAAK,eAAe,EAAE,eAAe,sBAAsB,GAAM,CAGzF,IAAe,KAAM,CACxB,KAAK,eAAiB,KACtB,OAGD,IAAI,EAEJ,AAGC,EAHG,QAAS,EACF,EAAc,aAAa,EAAW,IAAI,CAE1C,EAAc,oBAAoB,EAAW,WAAY,EAAW,KAAM,EAAW,OAAO,CAGnG,GACH,KAAK,eAAiB,EAAQ,IAC9B,EAAQ,eAAe,sBAAsB,GAAK,EAElD,KAAK,eAAiB,OCpGZ,EAAb,MAAa,CAAc,CAC1B,OAAe,UACf,OAAwB,uBAAyB,qDAEjD,OAAgC,KAChC,UAAoB,GACpB,UAAoB,GAEpB,aAAc,CACb,GAAI,EAAc,UAAW,OAAO,EAAc,UAClD,EAAc,UAAY,KAE1B,QAAQ,iBAAiB,UAAW,KAAK,QAAQ,KAAK,KAAK,CAAC,CAG7D,QAAQ,EAAgB,CAEvB,MADA,MAAK,OAAS,EACP,KAAK,KAAK,UAAU,CAG5B,KAAK,EAAoB,EAAgB,CACxC,GAAI,CACH,GAAI,CAAC,KAAK,OAAQ,MAAU,OAAO,CAEnC,OADA,OAAO,OAAO,YAAY,CAAE,SAAQ,OAAM,CAAE,KAAK,OAAO,CACjD,SACC,EAAO,CAGf,OADA,QAAQ,MAAM,EAAc,uBAAwB,EAAM,CACnD,IAIT,WAAmB,EAAgB,EAAa,CAC/C,GAAI,CACH,OAAO,IAAW,IAAI,IAAI,EAAI,CAAC,YACxB,CACP,MAAO,IAIT,QAAQ,EAAqB,CAC5B,GAAI,CAAC,KAAK,QAAU,CAAC,KAAK,WAAW,EAAM,OAAQ,KAAK,OAAO,CAC9D,OAGD,GAAM,CAAE,SAAQ,QAAsB,EAAM,KAExC,IAAW,WAAW,KAAK,qBAAqB,EAAK,CACrD,IAAW,wBAAwB,KAAK,4BAA4B,EAAK,CACzE,IAAW,SAAS,KAAK,aAAa,EAAK,CAC3C,IAAW,oBAAoB,KAAK,wBAAwB,EAAK,CAGtE,qBAA6B,EAAe,CAC3C,KAAK,UAAY,GACjB,KAAK,UAAY,CAAC,CAAE,GAAsB,UAG3C,aAAc,CACb,OAAO,KAAK,UAGb,gBAAiB,CAChB,IAAI,EAAW,EAIf,OAAO,IAAI,QAAkB,GAAY,CACxC,IAAM,MAAuB,CAC5B,GAAI,GAAY,GAAa,OAAO,EAAQ,GAAM,CAClD,IAEI,KAAK,UAAW,EAAQ,GAAK,CAC5B,WAAW,EAAgB,IAAQ,EAGzC,GAAgB,EACf,CAGH,4BAAoC,EAAe,CAClD,IAAM,EAAO,CAAC,CAAC,EACf,EAAc,eAAe,EAAK,CAGnC,aAAqB,EAAe,CACnC,GAAM,CAAE,MAAM,GAAI,aAAa,GAAI,OAAO,KAAM,UAAU,EAAE,EAAK,EAE3D,EAAY,EAAc,aAAa,EAAI,CAEjD,GAAI,GAAa,GAAc,OAAO,EAAU,SAAY,WAAY,CACvE,EAAU,QAAQ,CAAE,aAAY,OAAM,UAAS,CAAC,CAChD,OAGD,OAAO,SAAS,QAAQ,CAGzB,wBAAgC,EAAe,CAC9C,GAAI,CAAC,GAAQ,OAAO,GAAS,SAAU,CACtC,EAAc,iBAAiB,KAAK,CACpC,OAGD,GAAM,CAAE,MAAK,aAAY,OAAM,UAAW,EAEtC,IAAQ,KAEX,EAAc,iBAAiB,KAAK,CAC1B,GAAc,IAAS,IAAA,GAGjC,EAAc,iBAAiB,EAAS,CAAE,aAAY,OAAM,SAAQ,CAAG,CAAE,aAAY,OAAM,CAAC,CAClF,OAAO,GAAQ,UAEzB,EAAc,iBAAiB,CAAE,MAAK,CAAC,GCzH7B,EAAb,MAAa,CAAY,CACxB,OAAe,sBAAwB,GAEvC,OAAO,aAAa,EAA0D,CAC7E,GAAI,EAAY,sBAAuB,OAEvC,IAAI,EAAU,GACV,EAAY,GACZ,EAEE,EAAY,GAAiC,CAClD,aAAa,EAAW,CACxB,EAAa,WAAW,EAAkB,IAAI,EAGzC,MAA0B,CAC/B,IAAM,EAAM,OAAO,SAAS,KACtB,EAAQ,SAAS,MACjB,EAAkB,IAAY,GAAO,IAAc,EAErD,IACH,MAAe,EAAS,CAAE,MAAK,QAAO,CAAC,CAAC,CACxC,EAAU,EACV,EAAY,GAGb,WAAW,EAAmB,EAAkB,GAAK,IAAI,EAG1D,GAAmB,CAEnB,EAAY,sBAAwB,KCxBtC,eAAsB,EAAM,CAC3B,cACA,WAAW,IAAA,GACX,cAAc,IAAA,GACd,UAAU,IAAA,IAIiB,CAC3B,IAAM,EAAgB,IAAI,EAK1B,GAHI,CADc,EAAc,QAAQ,EAAY,EAIhD,CADc,MAAM,EAAc,gBAAgB,CACtC,OAEhB,EAAY,aAAc,GAAS,EAAc,KAAK,aAAc,EAAK,CAAC,CAC1E,EAAe,WAAW,CAE1B,IAAM,EAAmB,EAAgB,MAAM,EAAS,CAClD,EAAiC,EAAE,CAYzC,OAVA,EAAiB,QAAS,GAAY,CACrC,IAAM,EAAe,EAAc,QAAQ,EAAQ,CAC7C,EAAO,GAAgB,IAAI,EAAgB,EAAQ,CAEzD,EAAK,aAAa,CAAE,cAAa,UAAS,CAAE,CAAC,CAAC,EAAS,CAEvD,EAAY,KAAK,EAAK,CACjB,GAAc,EAAc,QAAQ,EAAK,EAC7C,CAEK,CACN,QAAS,CACR,EAAc,YAAY,EAAY,EAEvC,QAAS,CACR,EAAc,YAAY,EAAY,EAEvC,SAAU,CACT,EAAc,aAAa,EAAY,EAExC,CAGF,SAAgB,GAAS,CACxB,EAAc,aAAa,CAG5B,SAAgB,GAAU,CACzB,IAAM,EAAQ,EAAc,cAAc,CAC1C,MAAO,CACN,QAAS,CACR,EAAc,YAAY,EAAM,EAEjC,CAGF,SAAgB,EAAQ,EAAwB,CAC/C,OAAO,EAAgB,iBAAiB,EAAW"} |