@citolab/qti-components 7.20.2 → 7.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../qti-interactions/src/mixins/drag-drop/flippables-mixin.ts","../../qti-interactions/src/mixins/drag-drop/drag-drop-interaction-mixin.ts","../../qti-interactions/src/components/qti-associate-interaction/qti-associate-interaction.styles.ts","../../qti-interactions/src/components/qti-associate-interaction/qti-associate-interaction.ts","../../qti-interactions/src/mixins/vocabulary/vocabulary-mixin.ts","../../qti-interactions/src/components/qti-choice-interaction/qti-choice-interaction.styles.ts","../../qti-interactions/src/mixins/choices/choices.mixin.ts","../../qti-interactions/src/components/qti-choice-interaction/qti-choice-interaction.ts","../../qti-interactions/src/components/qti-custom-interaction/qti-custom-interaction.ts","../../qti-interactions/src/components/qti-end-attempt-interaction/qti-end-attempt-interaction.ts","../../qti-interactions/src/components/qti-extended-text-interaction/qti-extended-text-interaction.styles.ts","../../qti-interactions/src/components/qti-extended-text-interaction/qti-extended-text-interaction.ts","../../qti-interactions/src/components/qti-gap-match-interaction/qti-gap-match-interaction.styles.ts","../../qti-interactions/src/components/qti-gap-match-interaction/qti-gap-match-interaction.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/repeat.ts","../../qti-interactions/src/internal/hotspots/hotspot.ts","../../qti-interactions/src/components/qti-graphic-associate-interaction/qti-graphic-associate-interaction.styles.ts","../../qti-interactions/src/components/qti-graphic-associate-interaction/qti-graphic-associate-interaction.ts","../../qti-interactions/src/components/qti-graphic-gap-match-interaction/qti-graphic-gap-match-interaction.styles.ts","../../qti-interactions/src/components/qti-graphic-gap-match-interaction/qti-graphic-gap-match-interaction.ts","../../qti-interactions/src/components/qti-graphic-order-interaction/qti-graphic-order-interaction.styles.ts","../../qti-interactions/src/components/qti-graphic-order-interaction/qti-graphic-order-interaction.ts","../../qti-interactions/src/components/qti-hotspot-interaction/qti-hotspot-interaction.styles.ts","../../qti-interactions/src/components/qti-hotspot-interaction/qti-hotspot-interaction.ts","../../qti-interactions/src/components/qti-hottext-interaction/qti-hottext-interaction.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/unsafe-html.ts","../../qti-interactions/src/components/qti-inline-choice-interaction/qti-inline-choice-interaction.ts","../../qti-interactions/src/components/qti-match-interaction/qti-match-interaction.styles.ts","../../qti-interactions/src/components/qti-match-interaction/qti-match-interaction.ts","../../qti-interactions/src/components/qti-media-interaction/qti-media-interaction.ts","../../qti-interactions/src/components/qti-order-interaction/qti-order-interaction.styles.ts","../../qti-interactions/src/components/qti-order-interaction/qti-order-interaction.ts","../../qti-interactions/src/components/qti-portable-custom-interaction/qti-portable-custom-interaction.styles.ts","../../qti-interactions/src/components/qti-portable-custom-interaction/qti-portable-custom-interaction.ts","../../qti-interactions/src/components/qti-position-object-interaction/qti-position-object-interaction.ts","../../qti-interactions/src/components/qti-position-object-interaction/qti-position-object-stage.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/style-map.ts","../../qti-interactions/src/components/qti-select-point-interaction/qti-select-point-interaction.ts","../../qti-interactions/src/components/qti-slider-interaction/qti-slider-interaction.styles.ts","../../qti-interactions/src/components/qti-slider-interaction/qti-slider-interaction.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/ref.ts","../../qti-interactions/src/components/qti-text-entry-interaction/qti-text-entry-interaction.styles.ts","../../qti-interactions/src/components/qti-text-entry-interaction/qti-text-entry-interaction.ts","../../qti-interactions/src/components/qti-upload-interaction/qti-upload-interaction.ts","../../qti-interactions/src/elements/qti-associable-hotspot/qti-associable-hotspot.ts","../../qti-interactions/src/elements/qti-gap/qti-gap.ts","../../qti-interactions/src/elements/qti-gap-img/qti-gap-img.ts","../../qti-interactions/src/mixins/active-element/active-element.mixin.ts","../../qti-interactions/src/elements/qti-gap-text/qti-gap-text.ts","../../qti-interactions/src/elements/qti-hotspot-choice/qti-hotspot-choice.ts","../../qti-interactions/src/elements/qti-hottext/qti-hottext.ts","../../qti-interactions/src/elements/qti-inline-choice/qti-inline-choice.ts","../../qti-interactions/src/elements/qti-prompt/qti-prompt.ts","../../qti-interactions/src/elements/qti-simple-associable-choice/qti-simple-associable-choice.ts","../../qti-interactions/src/elements/qti-simple-choice/qti-simple-choice.styles.ts","../../qti-interactions/src/elements/qti-simple-choice/qti-simple-choice.ts","../../qti-interactions/src/components/qti-associate-interaction/register.ts","../../qti-interactions/src/components/qti-choice-interaction/register.ts","../../qti-interactions/src/components/qti-custom-interaction/register.ts","../../qti-interactions/src/components/qti-end-attempt-interaction/register.ts","../../qti-interactions/src/components/qti-extended-text-interaction/register.ts","../../qti-interactions/src/components/qti-gap-match-interaction/register.ts","../../qti-interactions/src/components/qti-graphic-associate-interaction/register.ts","../../qti-interactions/src/components/qti-graphic-gap-match-interaction/register.ts","../../qti-interactions/src/components/qti-graphic-order-interaction/register.ts","../../qti-interactions/src/components/qti-hotspot-interaction/register.ts","../../qti-interactions/src/components/qti-hottext-interaction/register.ts","../../qti-interactions/src/components/qti-inline-choice-interaction/register.ts","../../qti-interactions/src/components/qti-match-interaction/register.ts","../../qti-interactions/src/components/qti-media-interaction/register.ts","../../qti-interactions/src/components/qti-order-interaction/register.ts","../../qti-interactions/src/components/qti-portable-custom-interaction/qti-portable-custom-test-interaction.ts","../../qti-interactions/src/components/qti-portable-custom-interaction/register.ts","../../qti-interactions/src/components/qti-position-object-interaction/register.ts","../../qti-interactions/src/components/qti-select-point-interaction/register.ts","../../qti-interactions/src/components/qti-slider-interaction/register.ts","../../qti-interactions/src/components/qti-text-entry-interaction/register.ts","../../qti-interactions/src/components/qti-upload-interaction/register.ts","../../qti-interactions/src/elements/qti-associable-hotspot/register.ts","../../qti-interactions/src/elements/qti-gap/register.ts","../../qti-interactions/src/elements/qti-gap-img/register.ts","../../qti-interactions/src/elements/qti-gap-text/register.ts","../../qti-interactions/src/elements/qti-hotspot-choice/register.ts","../../qti-interactions/src/elements/qti-hottext/register.ts","../../qti-interactions/src/elements/qti-inline-choice/register.ts","../../qti-interactions/src/elements/qti-prompt/register.ts","../../qti-interactions/src/elements/qti-simple-associable-choice/register.ts","../../qti-interactions/src/elements/qti-simple-choice/register.ts"],"sourcesContent":["// THIS IS A MIXIN, THIS IS A MIXIN\n// USE LIKE THIS\n// ```class DropList extends Flippables(LitElement) {```\n// mixin which animates children with FLIP\n// a combination between this directive:\n// https://ng-run.com/edit/9MGr5dYWA20AiJtpy5az?open=app%2Fapp.component.html\n// and a tutorial how to make a mixin\n// https://lit.dev/docs/composition/mixins/\n\nimport type { Interaction } from '@qti-components/base';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\nexport declare class FlippablesInterface {\n connectedCallback(): void;\n disconnectedCallback(): void;\n}\n\n// just a conversion of a angular FLIP directive, made as a Mixin\n// https://ng-run.com/edit/9MGr5dYWA20AiJtpy5az?open=app%2Fapp.component.html\nexport const FlippablesMixin = <T extends Constructor<Interaction>>(\n superClass: T,\n _droppablesSel: string,\n _draggablesSel: string\n) => {\n abstract class FlippablesElement extends superClass {\n // private state = new Map<Element, any>();\n // private observer: MutationObserver;\n // flippablesSelector: string;\n // override async firstUpdated(changedProps) {\n // await this.updateComplete; // pk: this is the key to calculate correct proportions\n // const draggables = Array.from(this.querySelectorAll(draggablesSel));\n // draggables.forEach((elem) => {\n // const { left, top, width, height } = elem.getBoundingClientRect();\n // this.state.set(elem, { left, top, width, height });\n // });\n // this.observer = new MutationObserver(this.animateMe);\n // const droppables = Array.from(this.querySelectorAll(droppablesSel));\n // droppables.forEach((draggable) => {\n // this.observer.observe(draggable, { childList: true });\n // });\n // this.observer.observe(this, { childList: true });\n // super.firstUpdated(changedProps);\n // }\n // private animateMe = () => {\n // this.state.forEach((value, elem) => {\n // const { left, top, width, height } = elem.getBoundingClientRect();\n // if (this.state.get(elem) == null) {\n // this.state.set(elem, { left, top, width, height });\n // }\n // const cache = this.state.get(elem);\n // const deltaX = cache.left - left;\n // const deltaY = cache.top - top;\n // const deltaW = cache.width / width;\n // const deltaH = cache.height / height;\n // this.state.set(elem, { left, top, width, height });\n // const { duration, easing } = { duration: 350, easing: 'cubic-bezier(0.26, 0.86, 0.44, 0.985)' };\n // elem.animate(\n // [\n // {\n // transformOrigin: 'top left',\n // transform: `\n // translate(${deltaX}px, ${deltaY}px)\n // scale(${deltaW}, ${deltaH})\n // `,\n // // width: cache.width,\n // // height: cache.height+ 'px',\n // // opacity: cache.opacity,\n // },\n // {\n // transformOrigin: 'top left',\n // transform: 'none',\n // },\n // ],\n // {\n // duration,\n // easing,\n // }\n // );\n // });\n // };\n // override disconnectedCallback(): void {\n // super.disconnectedCallback();\n // this.observer.disconnect();\n // }\n }\n return FlippablesElement as Constructor<FlippablesInterface> & T;\n};\n","import { property } from 'lit/decorators.js';\n\nimport { liveQuery, watch } from '@qti-components/utilities';\n\nimport { FlippablesMixin } from './flippables-mixin';\n\nimport type { Interaction, IInteraction } from '@qti-components/base';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\ninterface InteractionConfiguration {\n copyStylesDragClone: boolean;\n dragCanBePlacedBack: boolean;\n dragOnClick: boolean;\n}\n\ntype RectLike = {\n left: number;\n right: number;\n top: number;\n bottom: number;\n width: number;\n height: number;\n};\n\nexport const DragDropInteractionMixin = <T extends Constructor<Interaction>>(\n superClass: T,\n draggablesSelector: string,\n droppablesSelector: string,\n dragContainersSelector: string\n) => {\n abstract class DragDropInteractionElement extends FlippablesMixin(\n superClass,\n droppablesSelector,\n draggablesSelector\n ) {\n // protected draggables = new Map<HTMLElement, { parent: HTMLElement; index: number }>();\n private observer: MutationObserver | null = null;\n private droppableObsever: MutationObserver | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private draggables: HTMLElement[] = [];\n private droppables: HTMLElement[] = [];\n private dragContainers: HTMLElement[] = [];\n private dragClone: HTMLElement = null; // Clone of drag source for visual feedback\n private dragSource: HTMLElement = null; // The source element being dragged\n\n private touchStartPoint = null; // Point of the first touch\n private isDraggable = false; // Whether a draggable element is active\n private cloneOffset = { x: 0, y: 0 }; // Offset for positioning the drag clone\n private isDragging = false; // Whether a drag operation is ongoing\n private allDropzones: HTMLElement[] = []; // All dropzones for keyboard navigation\n private lastTarget = null; // Last touch target\n private currentDropTarget = null; // Current droppable element\n private dragMoveRaf = 0;\n private pendingMove: { clientX: number; clientY: number } | null = null;\n private dragBounds: {\n minLeft: number;\n maxLeft: number;\n minTop: number;\n maxTop: number;\n width: number;\n height: number;\n } | null = null;\n private dragCloneRect: RectLike | null = null;\n private dropzoneRects = new Map<HTMLElement, DOMRect>();\n private dropzoneRectsDirty = false;\n private dragBoundsDirty = false;\n private dragCloneStyleCache = new WeakMap<HTMLElement, string>();\n private readonly onScrollOrResize = () => {\n this.dropzoneRectsDirty = true;\n this.dragBoundsDirty = true;\n this.dragBoundsDirty = true;\n };\n\n private onMove = this.handleTouchMove.bind(this);\n private onEnd = this.handleTouchEnd.bind(this);\n private onCancel = this.handleTouchCancel.bind(this);\n\n private readonly MIN_DRAG_DISTANCE = 5; // Minimum pixel movement to start dragging\n private readonly DRAG_CLONE_OPACITY = 1; // Opacity of the drag clone element\n private readonly MAX_DRAGGABLE_WIDTH = 600; // Maximum width of a draggable element\n\n private dataTransfer = {\n data: {},\n setData(type, val) {\n this.data[type] = val;\n },\n getData(type) {\n return this.data[type];\n },\n effectAllowed: 'move'\n };\n\n @property({ attribute: false, type: Object }) protected configuration: InteractionConfiguration = {\n copyStylesDragClone: true,\n dragCanBePlacedBack: true,\n dragOnClick: false\n };\n @property({ type: Number, reflect: true, attribute: 'min-associations' }) minAssociations = 1;\n @property({ type: Number, reflect: true, attribute: 'max-associations' }) maxAssociations = 0;\n\n @liveQuery(dragContainersSelector)\n handleDraggableContainerChange(dragContainersAdded: HTMLElement[], dragContainersRemoved: HTMLElement[]) {\n if (this.isMatchTabular()) return;\n\n if (dragContainersAdded.length > 0 || dragContainersRemoved.length > 0) {\n this.dragContainersModified(dragContainersAdded || [], dragContainersRemoved || []);\n }\n }\n\n dragContainersModified(addedDragContainers: HTMLElement[], removedDragContainers: HTMLElement[]) {\n for (const removedContainer of removedDragContainers) {\n if (this.dragContainers.includes(removedContainer)) {\n this.dragContainers = this.dragContainers.filter(container => container !== removedContainer);\n this.allDropzones = this.allDropzones.filter(dropzone => dropzone !== removedContainer);\n }\n }\n for (const dragContainer of addedDragContainers) {\n if (!this.dragContainers.includes(dragContainer)) {\n this.dragContainers.push(dragContainer);\n this.allDropzones.push(dragContainer);\n }\n }\n this.dropzoneRectsDirty = true;\n this.dragBoundsDirty = true;\n }\n\n @liveQuery(draggablesSelector)\n handleDraggablesChange(dragsAdded: HTMLElement[], dragsRemoved: HTMLElement[]) {\n if (this.isMatchTabular()) return;\n if (dragsAdded.length > 0 || dragsRemoved.length > 0) {\n this.draggablesModified(dragsAdded || [], dragsRemoved || []);\n }\n }\n\n @liveQuery(droppablesSelector)\n handleDroppablesChange(dropsAdded: HTMLElement[], dropsRemoved: HTMLElement[]) {\n if (this.isMatchTabular()) return;\n if (dropsAdded.length > 0 || dropsRemoved.length > 0) {\n this.droppablesModified(dropsAdded || [], dropsRemoved || []);\n }\n }\n\n override firstUpdated(): void {\n super.firstUpdated();\n if (this.isMatchTabular()) return;\n const disabled = this.hasAttribute('disabled');\n if (!disabled) {\n document.addEventListener('mousemove', this.onMove, { passive: false });\n document.addEventListener('mouseup', this.onEnd, { passive: false });\n document.addEventListener('touchmove', this.onMove, { passive: false });\n document.addEventListener('touchend', this.onEnd, { passive: false });\n document.addEventListener('touchcancel', this.onCancel, { passive: false });\n }\n const draggables = Array.from(this.querySelectorAll(draggablesSelector) || []).concat(\n Array.from(this.shadowRoot?.querySelectorAll(draggablesSelector) || [])\n ) as HTMLElement[];\n const droppables = Array.from(this.querySelectorAll(droppablesSelector) || []).concat(\n Array.from(this.shadowRoot?.querySelectorAll(droppablesSelector) || [])\n ) as HTMLElement[];\n const dragContainers = Array.from(this.querySelectorAll(dragContainersSelector) || []).concat(\n Array.from(this.shadowRoot?.querySelectorAll(dragContainersSelector) || [])\n ) as HTMLElement[];\n this.dragContainersModified(dragContainers, []);\n this.droppablesModified(droppables, []);\n this.draggablesModified(draggables, []);\n\n this.updateMinDimensionsForDropZones();\n\n // MutationObserver to observe changes in child elements\n this.observer = new MutationObserver(() => this.updateMinDimensionsForDropZones());\n this.observer.observe(this, { childList: true, subtree: true });\n\n // ResizeObserver to monitor size changes of `gapTexts`\n this.resizeObserver = new ResizeObserver(() => this.updateMinDimensionsForDropZones());\n const gapTexts = this.querySelectorAll('qti-gap-text');\n gapTexts.forEach(gapText => this.resizeObserver?.observe(gapText));\n }\n\n private draggablesModified = (addedDraggables: HTMLElement[], removedDraggables: HTMLElement[]) => {\n if (this.isMatchTabular()) return;\n for (const removedDraggable of removedDraggables) {\n if (this.draggables.includes(removedDraggable)) {\n this.draggables = this.draggables.filter(draggable => draggable !== removedDraggable);\n removedDraggable.removeAttribute('tabindex');\n removedDraggable.removeEventListener('touchstart', this.handleTouchStart.bind(this));\n removedDraggable.removeEventListener('mousedown', this.handleTouchStart.bind(this));\n }\n }\n for (const draggable of addedDraggables) {\n if (!this.draggables.includes(draggable)) {\n this.draggables.push(draggable);\n // draggables.forEach(el => {\n draggable.setAttribute('tabindex', '0'); // Make draggable elements focusable\n if (!(draggable as any).hasTouchStartListener) {\n // Prevent adding multiple listeners\n draggable.addEventListener('touchstart', this.handleTouchStart.bind(this), { passive: false });\n draggable.addEventListener('mousedown', this.handleTouchStart.bind(this), { passive: false });\n (draggable as any).hasTouchStartListener = true;\n }\n // });\n }\n }\n let index = 0;\n this.draggables.forEach(draggable => {\n draggable.style.viewTransitionName = `drag-${index}-${this.getAttribute('identifier') || crypto.randomUUID()}`;\n draggable.setAttribute('qti-draggable', 'true');\n index++;\n });\n };\n\n private droppablesModified = (addedDroppables: HTMLElement[], removedDroppables: HTMLElement[]) => {\n if (this.isMatchTabular()) return;\n for (const removedDroppable of removedDroppables) {\n if (this.droppables.includes(removedDroppable)) {\n this.droppables = this.droppables.filter(droppable => droppable !== removedDroppable);\n this.allDropzones = this.allDropzones.filter(dropzone => dropzone !== removedDroppable);\n }\n }\n for (const droppable of addedDroppables) {\n if (!this.droppables.includes(droppable)) {\n this.droppables.push(droppable);\n this.allDropzones.push(droppable);\n }\n }\n for (const droppable of this.droppables) {\n if (this.dataset.choicesContainerWidth) {\n droppable.style.width = `${this.dataset.choicesContainerWidth}px`;\n droppable.style.boxSizing = `border-box`;\n }\n }\n this.dropzoneRectsDirty = true;\n this.dragBoundsDirty = true;\n };\n\n private async moveDraggableToDroppable(draggable: HTMLElement, droppable: HTMLElement): Promise<void> {\n if (this.isMatchTabular()) return;\n // console.log(`moveDraggableToDroppable, draggable: ${draggable.tagName}, droppable: ${droppable.tagName}`);\n const moveElement = (): void => {\n draggable.style.transform = 'translate(0, 0)';\n if (droppable.tagName === 'SLOT') {\n draggable.setAttribute('slot', droppable.getAttribute('name'));\n } else {\n droppable.appendChild(draggable);\n }\n this.checkAllMaxAssociations();\n this.saveResponse(); //\n };\n // if (!document.startViewTransition) {\n moveElement();\n return;\n // }\n\n // const transition = document.startViewTransition(moveElement);\n // await transition.finished;\n }\n\n private activateDroppable(droppable: HTMLElement): void {\n if (this.dragContainers.includes(droppable)) {\n this._internals.states.add('--dragzone-active');\n droppable.setAttribute('active', '');\n } else {\n this._internals.states.delete('--dragzone-active');\n droppable.setAttribute('active', '');\n }\n }\n\n private deactivateDroppable(droppable: HTMLElement, makeDragzoneActive = true): void {\n if (makeDragzoneActive) {\n this._internals.states.add('--dragzone-active');\n }\n droppable.removeAttribute('active');\n }\n\n override connectedCallback() {\n super.connectedCallback();\n }\n\n private isMatchTabular(): boolean {\n return this.classList.contains('qti-match-tabular');\n }\n\n private async updateMinDimensionsForDropZones() {\n await this.updateComplete;\n if (this.isMatchTabular()) return;\n this.dropzoneRectsDirty = true;\n\n const draggables: NodeListOf<HTMLElement> = this.querySelectorAll(draggablesSelector);\n const dragContainer: HTMLElement =\n this.querySelector(dragContainersSelector) || this.shadowRoot?.querySelector(dragContainersSelector);\n\n const droppables: NodeListOf<HTMLElement> = this.querySelectorAll(droppablesSelector);\n const dropContainer: HTMLElement = droppables[0]?.parentElement;\n\n const maxWidth = this.determineMaxWidth(dragContainer, dropContainer);\n\n let maxDraggableHeight = 0;\n let maxDraggableWidth = 0;\n for (const draggable of draggables) {\n draggable.style.maxWidth = maxWidth + 'px';\n const { width, height } = await this.measureIntrinsicSize(draggable);\n maxDraggableHeight = Math.max(maxDraggableHeight, height);\n maxDraggableWidth = Math.max(maxDraggableWidth, width);\n }\n\n if (dropContainer) {\n // Calculate the correct width of grid columns by adding the defined padding to the maximum width\n dropContainer.style.gridTemplateColumns = `repeat(auto-fit, minmax(calc(min(${maxWidth}px,${maxDraggableWidth}px + 2 * var(--qti-dropzone-padding))), 1fr))`;\n }\n\n if (dragContainer) {\n dragContainer.style.minHeight = `${maxDraggableHeight}px`;\n }\n for (const droppable of droppables) {\n droppable.style.minHeight = `${maxDraggableHeight}px`;\n droppable.style.minWidth = `${maxDraggableWidth}px`;\n\n const dropSlot: HTMLElement = droppable.shadowRoot?.querySelector('slot[part=\"dropslot\"]');\n if (dropSlot) {\n dropSlot.style.minHeight = `${maxDraggableHeight}px`;\n }\n }\n }\n\n private determineMaxWidth(dragContainer: HTMLElement, dropContainer: HTMLElement) {\n const referenceContainer = dropContainer ?? dragContainer;\n\n if (!referenceContainer || referenceContainer.clientWidth == 0) {\n return this.MAX_DRAGGABLE_WIDTH;\n }\n\n const styles = window.getComputedStyle(referenceContainer);\n const paddingLeft = parseFloat(styles.paddingLeft);\n const paddingRight = parseFloat(styles.paddingRight);\n\n return Math.min(this.MAX_DRAGGABLE_WIDTH, referenceContainer.clientWidth - paddingLeft - paddingRight);\n }\n\n private async measureIntrinsicSize(el: HTMLElement): Promise<{ width: number; height: number }> {\n const origPosition = el.style.position;\n el.style.position = 'fixed';\n const rect = el.getBoundingClientRect();\n el.style.position = origPosition;\n\n return { width: rect.width, height: rect.height };\n }\n\n private activateDroppables(target: HTMLElement): void {\n if (this.isMatchTabular()) return;\n const dragContainers = this.dragContainers;\n dragContainers.forEach(d => {\n d.setAttribute('enabled', '');\n if (d.hasAttribute('disabled')) {\n if (d.contains(target) || (d.shadowRoot && d.shadowRoot.contains(target))) {\n d.removeAttribute('disabled');\n }\n }\n });\n this.droppables.forEach(d => {\n d.setAttribute('enabled', '');\n if (d.hasAttribute('disabled')) {\n if (d.contains(target) || (d.shadowRoot && d.shadowRoot.contains(target))) {\n d.removeAttribute('disabled');\n }\n }\n });\n }\n\n private activateDragLocation(): void {\n this._internals.states.add('--dragzone-enabled');\n }\n\n private deactivateDragLocation(): void {\n this._internals.states.delete('--dragzone-enabled');\n }\n\n private deactivateDroppables(): void {\n const dragContainers = this.dragContainers;\n dragContainers.forEach(d => {\n d.removeAttribute('enabled');\n d.removeAttribute('active');\n });\n this.droppables.forEach(d => {\n d.removeAttribute('enabled');\n d.removeAttribute('active');\n });\n }\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n // Cleanup MutationObserver\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n }\n\n if (this.droppableObsever) {\n this.droppableObsever.disconnect();\n this.droppableObsever = null;\n }\n\n // Cleanup ResizeObserver\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n // Remove global event listeners\n document.removeEventListener('mousemove', this.onMove);\n document.removeEventListener('mouseup', this.onEnd);\n document.removeEventListener('touchmove', this.onMove);\n document.removeEventListener('touchend', this.onEnd);\n document.removeEventListener('touchcancel', this.onCancel);\n window.removeEventListener('scroll', this.onScrollOrResize, true);\n window.removeEventListener('resize', this.onScrollOrResize);\n }\n\n private handleTouchMove(e) {\n if (this.isMatchTabular()) return;\n if (this.isDraggable && this.dragClone) {\n const { x, y } = this.getEventCoordinates(e);\n this.pendingMove = { clientX: x, clientY: y };\n this.scheduleDragMove();\n e.preventDefault();\n }\n }\n\n private scheduleDragMove() {\n if (this.dragMoveRaf) return;\n this.dragMoveRaf = requestAnimationFrame(() => {\n this.dragMoveRaf = 0;\n if (!this.pendingMove) return;\n const currentTouch = this.pendingMove;\n this.pendingMove = null;\n this.processDragMove(currentTouch);\n if (this.pendingMove) {\n this.scheduleDragMove();\n }\n });\n }\n\n private processDragMove(currentTouch: { clientX: number; clientY: number }) {\n if (!this.isDraggable || !this.dragClone || !this.touchStartPoint) return;\n\n // Check if the minimum drag distance has been reached\n if (this.calculateDragDistance(currentTouch) >= this.MIN_DRAG_DISTANCE) {\n this.isDragging = true;\n }\n\n if (!this.isDragging) return;\n\n this.updateDragClonePosition(currentTouch);\n\n if (this.dropzoneRectsDirty) {\n this.refreshDropzoneRects();\n }\n\n // Find the closest dropzone to the current drag clone position\n const closestDropzone = this.findClosestDropzone();\n this.currentDropTarget = closestDropzone;\n\n // Handle dragenter and dragleave\n if (closestDropzone !== this.lastTarget) {\n if (this.lastTarget) {\n // Simulate dragleave for the previous target\n this.deactivateDroppable(this.lastTarget);\n this.dispatchCustomEvent(this.lastTarget, 'dragleave');\n }\n if (closestDropzone) {\n // Simulate dragenter for the new target\n this.activateDroppable(closestDropzone);\n this.dispatchCustomEvent(closestDropzone, 'dragenter');\n }\n this.lastTarget = closestDropzone;\n }\n\n // Simulate dragover for the current dropzone\n if (this.currentDropTarget) {\n this.dispatchCustomEvent(this.currentDropTarget, 'dragover');\n }\n }\n\n private handleTouchEnd(e) {\n if (this.isMatchTabular()) return;\n if (this.isDragging || this.isDraggable || this.dragClone) {\n this.resetDragState();\n }\n this._internals.states.delete('--dragzone-active');\n this.checkAllMaxAssociations();\n\n this._internals.states.delete('--dragzone-enabled');\n this._internals.states.delete('--dragzone-active');\n this.deactivateDragLocation();\n this.deactivateDroppables();\n this.draggables.forEach(d => {\n d.removeAttribute('dragging');\n });\n e.preventDefault();\n }\n\n private handleTouchCancel(_e) {\n this.resetDragState();\n }\n\n validate(): boolean | null {\n if (this.isMatchTabular()) return null;\n if (!this.shadowRoot) return false;\n const validAssociations = this.getValidAssociations();\n let isValid = true;\n let validityMessage = '';\n\n if (this.maxAssociations > 0 && validAssociations > this.maxAssociations) {\n isValid = false;\n validityMessage =\n this.dataset.maxSelectionsMessage ||\n `You've selected too many associations. Maximum allowed is ${this.maxAssociations}.`;\n } else if (this.minAssociations > 0 && validAssociations < this.minAssociations) {\n isValid = false;\n validityMessage =\n this.dataset.minSelectionsMessage ||\n `You haven't selected enough associations. Minimum required is ${this.minAssociations}.`;\n }\n const lastElementChild = this.lastElementChild as HTMLElement;\n // Use null for the third argument if no specific anchor is needed\n this._internals.setValidity(isValid ? {} : { customError: true }, validityMessage, lastElementChild);\n return isValid;\n }\n\n override reportValidity(): boolean {\n const validationMessageElement = this.shadowRoot.querySelector('#validation-message') as HTMLElement;\n if (validationMessageElement) {\n if (!this._internals.validity.valid) {\n validationMessageElement.textContent = this._internals.validationMessage;\n validationMessageElement.style.setProperty('display', 'block', 'important');\n } else {\n validationMessageElement.textContent = '';\n validationMessageElement.style.display = 'none';\n }\n }\n return this._internals.validity.valid;\n }\n\n private checkMaxAssociations(droppable: HTMLElement): boolean {\n const maxMatch = this.getMatchMaxValue(droppable);\n const currentAssociations = droppable.querySelectorAll('[qti-draggable=\"true\"]').length;\n const unlimitedAssociations = maxMatch === 0;\n return !unlimitedAssociations && currentAssociations >= maxMatch;\n }\n\n private dropDraggableInDroppable(draggable: HTMLElement, droppable: HTMLElement): void {\n // Create a clean clone of the original draggable without computed styles\n const cleanClone = draggable.cloneNode(true) as HTMLElement;\n cleanClone.removeAttribute('style'); // Remove inline styles from the clone\n // Place the clean clone into the drop target\n this.moveDraggableToDroppable(cleanClone, droppable);\n // this.currentDropTarget.appendChild(cleanClone);\n this.draggablesModified([cleanClone], []);\n\n // check if max associations are reached\n const matchMax = this.getMatchMaxValue(draggable);\n const currentDraggables = this.draggables.filter(\n d => d.getAttribute('identifier') === draggable.getAttribute('identifier')\n );\n if (matchMax !== 0 && currentDraggables.length >= matchMax) {\n draggable.style.opacity = '0.0';\n draggable.style.pointerEvents = 'none';\n } else {\n draggable.style.opacity = '1.0';\n }\n }\n\n private resetDragState() {\n if (this.dragMoveRaf) {\n cancelAnimationFrame(this.dragMoveRaf);\n this.dragMoveRaf = 0;\n }\n this.pendingMove = null;\n\n if (this.dragClone) {\n const isDropped = this.currentDropTarget !== null;\n const droppedInDragContainer = !isDropped || this.dragContainers.includes(this.currentDropTarget);\n if (isDropped && this.currentDropTarget && !droppedInDragContainer) {\n this.dropDraggableInDroppable(this.dragSource, this.currentDropTarget);\n }\n if (droppedInDragContainer) {\n this.dragSource.style.opacity = '1.0';\n this.dragSource.style.display = 'block';\n this.dragSource.style.position = 'static';\n this.dragSource.style.pointerEvents = 'auto';\n this.saveResponse();\n }\n this.dragClone.remove();\n this.draggablesModified([], [this.dragClone]);\n }\n\n this.isDragging = false;\n this.isDraggable = false;\n this.dragSource = null;\n this.dragClone = null;\n this.touchStartPoint = null;\n this.currentDropTarget = null;\n this.lastTarget = null;\n this.dragBounds = null;\n this.dragCloneRect = null;\n this.dropzoneRects.clear();\n this.dropzoneRectsDirty = false;\n this.dragBoundsDirty = false;\n window.removeEventListener('scroll', this.onScrollOrResize, true);\n window.removeEventListener('resize', this.onScrollOrResize);\n\n this.deactivateDroppables();\n }\n\n protected checkAllMaxAssociations(): void {\n const currentAssociations = this.getValidAssociations();\n const maxAssociationsInterationReached =\n this.maxAssociations !== 0 && currentAssociations >= this.maxAssociations;\n this.droppables.forEach(d => {\n if (maxAssociationsInterationReached) {\n this.disableDroppable(d);\n } else {\n const maxAssociationsReached = this.checkMaxAssociations(d);\n if (maxAssociationsReached) {\n this.disableDroppable(d);\n } else {\n this.enableDroppable(d);\n }\n }\n });\n }\n\n private getMatchMaxValue(el: HTMLElement): number {\n const matchMaxRawValue = el.getAttribute('match-max');\n return matchMaxRawValue ? parseInt(matchMaxRawValue, 10) : 1;\n }\n\n private disableDroppable(droppable: Element): void {\n droppable.setAttribute('disabled', '');\n }\n\n private enableDroppable(droppable: Element): void {\n droppable.removeAttribute('disabled');\n }\n\n get response(): string {\n let response: string[];\n if (typeof (this as any).getResponse === 'function') {\n // only for the qti-order-interaction, abstracted this away in a method\n response = (this as any).getResponse(); // Call the method from the implementing class\n } else {\n response = this.collectResponseData();\n }\n return response.join(',');\n }\n\n set response(value: string | null) {\n if (this.isMatchTabular()) return;\n // Assuming this.value is an array of strings\n\n if (typeof (this as any).getValue === 'function') {\n // only for the qti-order-interaction, abstracted this away in a method\n value = (this as any).getValue(value); // Call the method from the implementing class\n }\n\n if (Array.isArray(value)) {\n this.reset(false);\n\n value?.forEach(entry => this.placeResponse(entry));\n const formData = new FormData();\n value.forEach(response => {\n formData.append(this.responseIdentifier, response);\n });\n this._internals.setFormValue(formData);\n } else {\n // Handle the case where this.value is not an array\n this._internals.setFormValue(value || '');\n }\n }\n\n private placeResponse(response: string): void {\n const [dropId, ...dragIds] = response.split(' ').reverse();\n\n const draggableArray = Array.from(this.draggables);\n const droppableArray = Array.from(this.droppables);\n\n dragIds.forEach(dragId => {\n if (dragId === '') return; // in the case of a qti-order-interaction this is necessary, ['drag0','drag1','','drag2'] there can be empty placeholders\n const draggable = draggableArray.find(d => d.getAttribute('identifier') === dragId);\n const droppable = droppableArray.find(d => d.getAttribute('identifier') === dropId);\n this.dropDraggableInDroppable(draggable, droppable);\n });\n }\n\n private getValidAssociations(): number {\n let count = 0;\n for (const droppable of this.droppables) {\n count = count + this.getDraggablesFromDroppable(droppable).length;\n }\n return count;\n }\n\n public override saveResponse(): void {\n let response: string | string[];\n if (typeof (this as any).getResponse === 'function') {\n // only for the qti-order-interaction, abstracted this away in a method\n response = (this as any).getResponse(); // Call the method from the implementing class\n } else {\n response = this.collectResponseData();\n }\n this.dispatchEvent(\n new CustomEvent('qti-interaction-response', {\n bubbles: true,\n composed: true,\n detail: {\n responseIdentifier: this.responseIdentifier,\n response\n }\n })\n );\n }\n\n private collectResponseData(): string[] {\n const response = this.droppables\n .map(droppable => {\n const draggablesInDroppable = this.getDraggablesFromDroppable(droppable);\n const identifiers = draggablesInDroppable.map(d => d.getAttribute('identifier'));\n const droppableIdentifier = droppable.getAttribute('identifier');\n return identifiers.map(id => `${id} ${droppableIdentifier}`);\n })\n .flat();\n return response;\n }\n\n private getDraggablesFromDroppable(droppable: HTMLElement): HTMLElement[] {\n const uniqueDraggableIds = this.draggables\n .map(d => d.getAttribute('identifier'))\n .filter((v, i, a) => a.indexOf(v) === i);\n\n const draggables = uniqueDraggableIds\n .flatMap(d => Array.from(droppable.querySelectorAll(`[identifier='${d}']`)))\n .filter(d => !!d)\n .map(d => d as HTMLElement);\n return draggables;\n }\n\n override reset(save = true): void {\n // Remove all draggables from droppables\n this.droppables.forEach(droppable => {\n const draggables = this.getDraggablesFromDroppable(droppable);\n draggables.forEach((draggable: HTMLElement) => {\n draggable.remove();\n this.draggablesModified([], [draggable]);\n });\n });\n this.dragContainers.forEach(dragContainer => {\n const draggables = Array.from(dragContainer.querySelectorAll('[qti-draggable=\"true\"]')) as HTMLElement[];\n draggables.forEach(draggable => {\n draggable.style.opacity = '1.0';\n });\n });\n\n // Reset dragClone, dragSource, and related states\n this.dragClone = null;\n this.dragSource = null;\n this.isDragging = false;\n this.isDraggable = false;\n this.currentDropTarget = null;\n this.lastTarget = null;\n\n // Optionally save the reset state\n if (save) {\n this.saveResponse();\n }\n }\n\n private updateDragClonePosition(touch) {\n if (!this.isDragging || !this.dragClone) return;\n if (this.dragBoundsDirty || !this.dragBounds) {\n this.refreshDragBounds();\n }\n\n const newLeft = touch.clientX - this.cloneOffset.x;\n const newTop = touch.clientY - this.cloneOffset.y;\n\n // Apply boundaries specific to the interaction element\n const { newLeft: boundedLeft, newTop: boundedTop } = this.applyInteractionBoundaries(newLeft, newTop);\n\n this.dragClone.style.left = `${boundedLeft}px`;\n this.dragClone.style.top = `${boundedTop}px`;\n\n let width = this.dragBounds?.width ?? this.dragCloneRect?.width;\n let height = this.dragBounds?.height ?? this.dragCloneRect?.height;\n if (!width || !height) {\n const rect = this.dragClone.getBoundingClientRect();\n width = rect.width;\n height = rect.height;\n }\n this.dragCloneRect = {\n left: boundedLeft,\n top: boundedTop,\n right: boundedLeft + width,\n bottom: boundedTop + height,\n width,\n height\n };\n }\n\n private applyInteractionBoundaries(newLeft: number, newTop: number) {\n if (!this.dragBounds) {\n return { newLeft, newTop };\n }\n\n // Constrain the position to the interaction's boundaries\n const boundedLeft = Math.max(this.dragBounds.minLeft, Math.min(newLeft, this.dragBounds.maxLeft));\n const boundedTop = Math.max(this.dragBounds.minTop, Math.min(newTop, this.dragBounds.maxTop));\n\n return { newLeft: boundedLeft, newTop: boundedTop };\n }\n\n private refreshDragBounds() {\n if (!this.dragClone) return;\n const interactionRect = this.getBoundingClientRect();\n const cloneRect = this.dragClone.getBoundingClientRect();\n this.dragBounds = {\n minLeft: interactionRect.left,\n maxLeft: interactionRect.right - cloneRect.width,\n minTop: interactionRect.top,\n maxTop: interactionRect.bottom - cloneRect.height,\n width: cloneRect.width,\n height: cloneRect.height\n };\n this.dragCloneRect = {\n left: cloneRect.left,\n top: cloneRect.top,\n right: cloneRect.left + cloneRect.width,\n bottom: cloneRect.top + cloneRect.height,\n width: cloneRect.width,\n height: cloneRect.height\n };\n this.dragBoundsDirty = false;\n }\n\n private getEventCoordinates(event, page = false) {\n const touch = event.touches ? event.touches[0] : event;\n return {\n x: page ? touch.pageX : touch.clientX,\n y: page ? touch.pageY : touch.clientY\n };\n }\n\n private calculateDragDistance(touch): number {\n const xDist = Math.abs(touch.clientX - this.touchStartPoint.x);\n const yDist = Math.abs(touch.clientY - this.touchStartPoint.y);\n return xDist + yDist;\n }\n\n private refreshDropzoneRects() {\n this.dropzoneRects.clear();\n const activeDrops = this.allDropzones.filter(d => !d.hasAttribute('disabled'));\n for (const dz of activeDrops) {\n this.dropzoneRects.set(dz, this.getDropzoneRect(dz));\n }\n this.dropzoneRectsDirty = false;\n }\n\n private getCachedDropzoneRect(el: HTMLElement): DOMRect {\n const cached = this.dropzoneRects.get(el);\n if (cached) return cached;\n const rect = this.getDropzoneRect(el);\n this.dropzoneRects.set(el, rect);\n return rect;\n }\n\n private getDropzoneRect(el: HTMLElement): DOMRect {\n const slot = el.shadowRoot?.querySelector<HTMLElement>('slot[part=\"dropslot\"]');\n return (slot ?? el).getBoundingClientRect();\n }\n\n private findClosestDropzone(): HTMLElement | null {\n const activeDrops = this.allDropzones.filter(d => !d.hasAttribute('disabled'));\n if (!this.dragClone || activeDrops.length === 0) return null;\n\n const dragRect = this.dragCloneRect ?? this.dragClone.getBoundingClientRect();\n let closestDropzone: HTMLElement | null = null;\n let maxArea = 0;\n\n // prefer real droppables first\n const prefer = (elements: HTMLElement[]) => {\n for (const dz of elements) {\n const dzRect = this.getCachedDropzoneRect(dz);\n const area = this.calculateOverlapArea(dragRect, dzRect);\n if (area > maxArea) {\n maxArea = area;\n closestDropzone = dz;\n }\n }\n };\n\n prefer(this.droppables.filter(droppable => !droppable.hasAttribute('disabled')));\n if (!closestDropzone) {\n // fallback to drag containers only if no droppable overlaps\n prefer(this.dragContainers.filter(drags => !drags.hasAttribute('disabled')));\n }\n\n // fallback by distance\n if (!closestDropzone) {\n let minDist = Number.POSITIVE_INFINITY;\n for (const dz of activeDrops) {\n const dzRect = this.getCachedDropzoneRect(dz);\n const dist = Math.hypot(dragRect.left - dzRect.left, dragRect.top - dzRect.top);\n if (dist < minDist) {\n minDist = dist;\n closestDropzone = dz;\n }\n }\n }\n return closestDropzone;\n }\n\n private calculateOverlapArea(rect1: RectLike, rect2: RectLike): number {\n const xOverlap = Math.max(0, Math.min(rect1.right, rect2.right) - Math.max(rect1.left, rect2.left));\n const yOverlap = Math.max(0, Math.min(rect1.bottom, rect2.bottom) - Math.max(rect1.top, rect2.top));\n return xOverlap * yOverlap;\n }\n\n private getComputedStyleText(source: HTMLElement): string {\n const cached = this.dragCloneStyleCache.get(source);\n if (cached) return cached;\n\n const computedStyles = window.getComputedStyle(source);\n let cssText = '';\n for (let i = 0; i < computedStyles.length; i++) {\n const key = computedStyles[i];\n cssText += `${key}:${computedStyles.getPropertyValue(key)};`;\n }\n this.dragCloneStyleCache.set(source, cssText);\n return cssText;\n }\n\n private dispatchCustomEvent(element, eventType, bubble = true) {\n if (!element) return;\n const event = new CustomEvent(eventType, { bubbles: bubble, cancelable: true });\n event['dataTransfer'] = this.dataTransfer;\n element.dispatchEvent(event);\n }\n\n private appendClone() {\n document.body.appendChild(this.dragClone);\n }\n\n private handleTouchStart(e) {\n if (this.isMatchTabular()) return;\n if (e instanceof MouseEvent) {\n // Only allow the left button\n if (e.button !== 0) return;\n }\n if (this.isDragging) {\n return;\n }\n const { x, y } = this.getEventCoordinates(e);\n this.touchStartPoint = { x, y };\n this.dragSource = e.currentTarget;\n this.isDraggable = true;\n\n this._internals.states.add('--dragzone-enabled');\n this._internals.states.add('--dragzone-active');\n\n this.activateDragLocation();\n this.activateDroppables(this.dragSource);\n\n // Create and position the drag clone\n const draggableInDragContainer = this.findDraggableInDraggableContainer(\n this.dragSource.getAttribute('identifier')\n );\n\n // clone the element if it is not in a dropzone\n const draggedFromDropzone = this.droppables.some(d =>\n Array.from(d.children).some(child => child === this.dragSource)\n );\n const rect = this.dragSource.getBoundingClientRect();\n if (draggedFromDropzone) {\n this.dragSource.remove();\n this.draggablesModified([], [this.dragSource]);\n this.dragSource = draggableInDragContainer;\n }\n\n this.cloneOffset.x = x - rect.left;\n this.cloneOffset.y = y - rect.top;\n this.dragClone = draggableInDragContainer.cloneNode(true) as HTMLElement;\n\n // Copy computed styles to the clone\n if (this.configuration.copyStylesDragClone) {\n this.dragClone.style.cssText = this.getComputedStyleText(draggableInDragContainer);\n }\n const rectOrg = draggableInDragContainer.getBoundingClientRect();\n this.dragClone.style.width = `${rectOrg.width}px`;\n this.dragClone.style.height = `${rectOrg.height}px`;\n if (rect) {\n this.setDragCloneStyles(rect);\n }\n this.dragClone.style.display = 'block';\n this.dragClone.style.opacity = '1';\n this.appendClone();\n this.refreshDragBounds();\n this.refreshDropzoneRects();\n window.addEventListener('scroll', this.onScrollOrResize, true);\n window.addEventListener('resize', this.onScrollOrResize);\n\n // check if max associations are reached\n const matchMax = this.getMatchMaxValue(this.dragSource);\n const currentDraggables = this.draggables.filter(\n d => d.getAttribute('identifier') === this.dragSource.getAttribute('identifier')\n );\n if (matchMax !== 0 && currentDraggables.length >= matchMax) {\n draggableInDragContainer.style.opacity = '0.0';\n draggableInDragContainer.style.pointerEvents = 'none';\n } else {\n draggableInDragContainer.style.opacity = '1.0';\n }\n e.preventDefault();\n this.dragClone.setAttribute('dragging', '');\n }\n\n private findDraggableInDraggableContainer(identifier: string): HTMLElement | undefined {\n // Flatten all drag containers\n const allDragContainers = this.dragContainers.flat();\n // Iterate through each drag container\n for (const container of allDragContainers) {\n // Check if the container itself has the identifier\n if (container.getAttribute('identifier') === identifier) {\n // Return the container itself if it matches\n return container;\n }\n // If the container is a slot element, get assigned elements\n let elements: HTMLElement[];\n // Check if the container is a slot element\n if (container instanceof HTMLSlotElement) {\n // If it's a slot, get the assigned elements\n elements = Array.from(container?.assignedElements() || []) as HTMLElement[];\n } else {\n // Otherwise, query the container using draggablesSelector\n elements = Array.from(container.querySelectorAll(draggablesSelector)) as HTMLElement[];\n }\n // Search for a matching child element inside the container\n const foundElement = elements.find(e => e.getAttribute('identifier') === identifier);\n\n // If a matching element is found, return it\n if (foundElement) {\n return foundElement;\n }\n }\n // Return undefined if no matching element is found\n return undefined;\n }\n\n private setDragCloneStyles(rect: DOMRect) {\n this.dragClone.style.position = 'fixed';\n this.dragClone.style.top = `${rect.top}px`;\n this.dragClone.style.left = `${rect.left}px`;\n this.dragClone.style.setProperty('box-sizing', 'border-box', 'important');\n this.dragClone.style.zIndex = '9999';\n this.dragClone.style.pointerEvents = 'none';\n this.dragClone.style.opacity = this.DRAG_CLONE_OPACITY.toString();\n this.dragClone.style.display = 'block';\n }\n }\n\n return DragDropInteractionElement as Constructor<IInteraction> & T;\n};\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: block; /* necessary to calculate scaling position */\n }\n slot[name='qti-simple-associable-choice'] {\n display: flex;\n align-items: flex-start;\n flex: 1;\n border: 2px solid transparent;\n padding: 0.3rem;\n border-radius: 0.3rem;\n gap: 0.5rem;\n }\n\n [part='drop-list'][active] {\n border-color: var(--qti-border-active) !important;\n background-color: var(--qti-bg-active) !important;\n }\n\n [part='drop-list'][enabled] {\n background-color: var(--qti-bg-active) !important;\n }\n\n :host::part(associables-container) {\n display: flex;\n padding: 0.5rem;\n justify-content: space-between;\n background: linear-gradient(\n 180deg,\n rgb(0 0 0 / 0%) calc(50% - 1px),\n var(--qti-border-color-gray) calc(50%),\n rgb(0 0 0 / 0%) calc(50% + 1px)\n );\n }\n`;\n","import { html } from 'lit';\nimport { state } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { DragDropInteractionMixin } from '../../mixins/drag-drop';\nimport styles from './qti-associate-interaction.styles';\n\nimport type { QtiSimpleAssociableChoice } from '../../elements/qti-simple-associable-choice';\nimport type { CSSResultGroup } from 'lit';\nexport class QtiAssociateInteraction extends DragDropInteractionMixin(\n Interaction,\n 'qti-simple-associable-choice',\n '.dl',\n `slot[name='qti-simple-associable-choice']`\n) {\n static override styles: CSSResultGroup = styles;\n @state() protected _childrenMap: Element[] = [];\n\n protected _registerChoiceHandler: (event: CustomEvent) => void;\n\n constructor() {\n super();\n this._registerChoiceHandler = this._registerChoice.bind(this);\n this.addEventListener('register-qti-simple-associable-choice', this._registerChoiceHandler);\n }\n\n protected _registerChoice(event: CustomEvent) {\n const choice = event.target as QtiSimpleAssociableChoice;\n this._childrenMap.push(choice);\n }\n\n override render() {\n return html` <slot name=\"prompt\"></slot>\n <slot name=\"qti-simple-associable-choice\"></slot>\n <div part=\"drop-container\">\n ${this._childrenMap.length > 0 &&\n Array.from(Array(Math.ceil(this._childrenMap.length / 2)).keys()).map(\n (_, index) =>\n html`<div part=\"associables-container\">\n <div name=\"left${index}\" part=\"drop-list\" class=\"dl\" identifier=\"droplist${index}_left\"></div>\n <div name=\"right${index}\" part=\"drop-list\" class=\"dl\" identifier=\"droplist${index}_right\"></div>\n </div>`\n )}\n\n <div role=\"alert\" part=\"message\" id=\"validation-message\"></div>\n </div>`;\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('register-qti-simple-associable-choice', this._registerChoiceHandler);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-associate-interaction': QtiAssociateInteraction;\n }\n}\n","import { property } from 'lit/decorators.js';\n\nimport type { QtiSimpleChoice } from '../../elements/qti-simple-choice';\nimport type { Interaction } from '@qti-components/base';\nimport type { LitElement, PropertyValues } from 'lit';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\ntype LabelType = 'qti-labels-decimal' | 'qti-labels-lower-alpha' | 'qti-labels-upper-alpha';\ntype LabelSuffixType = 'qti-labels-suffix-period' | 'qti-labels-suffix-parenthesis';\n\ndeclare class VocabularyInterface {}\n\nexport const VocabularyMixin = <T extends Constructor<LitElement>>(superClass: T, _selector: string) => {\n abstract class VocabularyElement extends superClass {\n private _classes: string[] = [];\n private _allLabels = ['qti-labels-decimal', 'qti-labels-lower-alpha', 'qti-labels-upper-alpha'];\n private _allLabelSuffixes = ['qti-labels-suffix-period', 'qti-labels-suffix-parenthesis'] as LabelSuffixType[];\n // Define the property with the custom converter\n @property({\n type: String\n })\n set class(value: string) {\n if (!value) {\n return;\n }\n // const oldValue = this._classes.join(' ');\n this._classes = value.split(' ');\n\n this._addLabels();\n // this.requestUpdate('class', oldValue);\n }\n get class(): string {\n return this._classes?.join(' ') || '';\n }\n\n protected override updated(_changedProperties: PropertyValues): void {\n super.updated(_changedProperties);\n // if (_changedProperties.has('shuffle')) {\n this._addLabels();\n // }\n }\n\n private _addLabels() {\n const classContainsLabel = this._classes.some(\n cls => this._allLabels.includes(cls) || this._allLabelSuffixes.includes(cls as LabelSuffixType)\n );\n const isNumber = value => {\n return !isNaN(+value);\n };\n if (classContainsLabel) {\n const choiceElements = Array.from(this.querySelectorAll('qti-simple-choice')).map(c => c as QtiSimpleChoice);\n const choices = choiceElements\n .map((choice: HTMLElement, index) => {\n return { el: choice, order: isNumber(choice.style.order) ? +choice.style.order : index + 1 };\n })\n .sort((a, b) => a.order - b.order)\n .map(choice => choice.el);\n for (let i = 0; i < choices.length; i++) {\n (choices[i] as QtiSimpleChoice).marker = this._getLabel(i + 1);\n }\n }\n }\n private _getLabel(index: number) {\n let lastLabel = this._classes.filter(c => this._allLabels.includes(c)).pop() as LabelType;\n const lastLabelSuffix = this._classes.filter(c => this._allLabelSuffixes.includes(c as LabelSuffixType)).pop();\n\n if (!lastLabel && lastLabelSuffix) {\n // a suffix without a label is strange so add qti-labels-upper-alpha\n lastLabel = 'qti-labels-upper-alpha';\n }\n let label = '';\n switch (lastLabel) {\n case 'qti-labels-decimal':\n label = `${index}`;\n break;\n case 'qti-labels-lower-alpha':\n label = `${String.fromCharCode(97 + index - 1)}`;\n break;\n case 'qti-labels-upper-alpha':\n label = `${String.fromCharCode(65 + index - 1)}`;\n break;\n }\n if (lastLabelSuffix === 'qti-labels-suffix-period') {\n label += '.';\n } else if (lastLabelSuffix === 'qti-labels-suffix-parenthesis') {\n label += `)`;\n }\n return label;\n }\n }\n return VocabularyElement as Constructor<VocabularyInterface> & T;\n};\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: block;\n }\n\n [part='slot'] {\n display: grid;\n gap: 10px;\n }\n\n /* Define the number of columns dynamically */\n :host([class*='qti-choices-stacking-']) [part='slot'] {\n grid-template-columns: repeat(var(--stacking-count, 1), 1fr);\n }\n\n /* Apply dynamic stacking count based on class */\n :host(.qti-choices-stacking-1) {\n --stacking-count: 1;\n }\n :host(.qti-choices-stacking-2) {\n --stacking-count: 2;\n }\n :host(.qti-choices-stacking-3) {\n --stacking-count: 3;\n }\n :host(.qti-choices-stacking-4) {\n --stacking-count: 4;\n }\n :host(.qti-choices-stacking-5) {\n --stacking-count: 5;\n }\n :host(.qti-choices-stacking-6) {\n --stacking-count: 6;\n }\n\n /* Default slot item layout */\n ::slotted(qti-simple-choice) {\n display: flex;\n align-items: center;\n white-space: normal;\n }\n\n /* Orientation styles */\n :host(.qti-orientation-horizontal) [part='slot'] {\n grid-auto-flow: dense column;\n grid-auto-columns: 1fr;\n }\n\n :host(.qti-orientation-vertical) [part='slot'] {\n grid-auto-flow: row;\n }\n\n /* Vertical and horizontal stacking logic */\n :host(.qti-orientation-vertical[class*='qti-choices-stacking-']) [part='slot'] {\n grid-auto-flow: dense column;\n grid-auto-columns: 1fr;\n grid-template-columns: repeat(var(--stacking-count), 1fr);\n grid-template-rows: repeat(calc(var(--item-count) / var(--stacking-count)), 1fr);\n }\n\n :host(.qti-orientation-horizontal[class*='qti-choices-stacking-']) [part='slot'] {\n grid-auto-flow: row;\n grid-template-columns: repeat(var(--stacking-count), 1fr);\n grid-template-rows: unset;\n }\n\n /* Ensure even distribution in vertical mode */\n :host(.qti-orientation-vertical) ::slotted(qti-simple-choice:nth-child(even)) {\n grid-row: auto;\n }\n`;\n\n// export default css`\n// [part='slot'] {\n// display: flex;\n// flex-direction: column;\n// gap: var(--qti-gap-size);\n// flex-wrap: wrap;\n// }\n\n// ::slotted(qti-simple-choice) {\n// flex: 0 0\n// calc((100% - (var(--qti-gap-size) * var(--choice-interactions-stacking))) / var(--choice-interactions-stacking)) !important;\n// box-sizing: border-box !important;\n// }\n\n// :host(.qti-choices-stacking-1) [part='slot'] {\n// flex-direction: row;\n// --choice-interactions-stacking: 1;\n// }\n\n// :host(.qti-choices-stacking-2) [part='slot'] {\n// flex-direction: row;\n// --choice-interactions-stacking: 2;\n// }\n// :host(.qti-choices-stacking-3) [part='slot'] {\n// flex-direction: row;\n// --choice-interactions-stacking: 3;\n// }\n// :host(.qti-choices-stacking-4) [part='slot'] {\n// flex-direction: row;\n// --choice-interactions-stacking: 4;\n// }\n// :host(.qti-choices-stacking-5) [part='slot'] {\n// flex-direction: row;\n// --choice-interactions-stacking: 5;\n// }\n// :host([orientation='horizontal']) [part='slot'] {\n// flex-direction: row;\n// }\n\n// :host(.qti-orientation-horizontal) [part='slot'] {\n// flex-direction: row;\n// flex-wrap: nowrap;\n// }\n\n// :host(.qti-orientation-horizontal) ::slotted(qti-simple-choice) {\n// flex: 1 1 auto !important;\n// }\n// `;\n","import { property, query, state } from 'lit/decorators.js';\nimport { consume } from '@lit/context';\n\nimport { watch } from '@qti-components/utilities';\nimport { configContext, type ConfigContext } from '@qti-components/base';\n\nimport type { Interaction, IInteraction } from '@qti-components/base';\nimport type { ChoiceInterface } from '../active-element/active-element.mixin';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\nexport type Choice = HTMLElement & ChoiceInterface & { internals: ElementInternals };\n\nexport interface ChoicesInterface extends IInteraction {\n minChoices: number;\n maxChoices: number;\n value: string | null;\n response: string | string[] | null;\n validate(): boolean;\n reportValidity(): boolean;\n}\n\nexport const ChoicesMixin = <T extends Constructor<Interaction>>(superClass: T, selector: string) => {\n abstract class ChoicesMixinElement extends superClass implements ChoicesInterface {\n protected _choiceElements: Choice[] = [];\n\n private _mutationObserver: MutationObserver | null = null;\n\n @query('#validation-message')\n protected _validationMessageElement!: HTMLElement;\n\n private _validationMessageShown = false;\n\n @property({ type: Number, attribute: 'min-choices' })\n public minChoices = 0;\n\n @property({ type: Number, attribute: 'max-choices' })\n public maxChoices = 1;\n\n @watch('maxChoices', { waitUntilFirstUpdate: true })\n protected _handleMaxChoicesChange(_oldValue: number, _newValue: number) {\n this._determineInputType();\n }\n\n @watch('disabled', { waitUntilFirstUpdate: true })\n protected _handleDisabledChange = (_: boolean, disabled: boolean) => {\n this._choiceElements.forEach(ch => (ch.disabled = disabled));\n };\n\n @watch('readonly', { waitUntilFirstUpdate: true })\n protected _handleReadonlyChange = (_: boolean, readonly: boolean) => {\n this._choiceElements.forEach(choice => (choice.readonly = readonly));\n };\n\n @state() response: string | string[] | null = '';\n\n @watch('response', { waitUntilFirstUpdate: true })\n protected _handleValueChange = () => {\n this._internals.setFormValue(this.value);\n this._updateChoiceSelection();\n };\n\n @state()\n @consume({ context: configContext, subscribe: true })\n protected _configContext: ConfigContext; //configContext\n override get value(): string | null {\n if (Array.isArray(this.response) && this.response.length === 0) {\n return null;\n } else if (this.response === '') {\n return null;\n }\n return Array.isArray(this.response) ? this.response.join(',') : this.response;\n }\n\n override set value(val: string | null) {\n if (this.maxChoices > 1 && (typeof val === 'string' || val === null)) {\n this.response = !val ? [] : val.toString().split(',');\n } else {\n this.response = val || '';\n }\n }\n\n protected override toggleInternalCorrectResponse(show: boolean) {\n // Get correct response from either responseVariable (item context) or local property (standalone)\n const correctResponse = this.correctResponse;\n\n if (correctResponse) {\n const responseArray = Array.isArray(correctResponse) ? correctResponse : [correctResponse];\n this._choiceElements.forEach(choice => {\n choice.internals.states.delete('correct-response');\n choice.internals.states.delete('incorrect-response');\n if (show && responseArray.length > 0) {\n if (responseArray.includes(choice.identifier)) {\n choice.internals.states.add('correct-response');\n } else {\n choice.internals.states.add('incorrect-response');\n }\n }\n });\n }\n }\n\n public override toggleCandidateCorrection(show: boolean) {\n // Get correct response from either responseVariable (item context) or local property (standalone)\n const correctResponse = this.correctResponse;\n\n if (!correctResponse) {\n return;\n }\n\n const correctResponseArray = Array.isArray(correctResponse) ? correctResponse : [correctResponse];\n\n // Get current response (works in both standalone and item context modes)\n const currentResponse = this.response;\n const candidateResponseArray = Array.isArray(currentResponse)\n ? currentResponse\n : currentResponse\n ? [currentResponse]\n : [];\n\n this._choiceElements.forEach(choice => {\n choice.internals.states.delete('candidate-correct');\n choice.internals.states.delete('candidate-incorrect');\n if (!show) {\n return;\n }\n if (!candidateResponseArray.includes(choice.identifier)) {\n return; // Not checked, so no feedback\n }\n if (correctResponseArray.includes(choice.identifier)) {\n choice.internals.states.add('candidate-correct');\n } else {\n choice.internals.states.add('candidate-incorrect');\n }\n });\n\n // Also update interaction-level states\n super.toggleCandidateCorrection(show);\n }\n\n override connectedCallback() {\n super.connectedCallback();\n this.addEventListener(`activate-${selector}`, this._choiceElementSelectedHandler);\n\n // Use MutationObserver to track choice elements (handles both direct children and nested descendants)\n this._mutationObserver = new MutationObserver(() => this._syncChoicesFromDOM());\n this._mutationObserver.observe(this, { childList: true, subtree: true });\n\n // Initial sync after DOM is ready\n this._syncChoicesFromDOM();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(`activate-${selector}`, this._choiceElementSelectedHandler);\n\n // Disconnect the observer\n if (this._mutationObserver) {\n this._mutationObserver.disconnect();\n this._mutationObserver = null;\n }\n }\n\n /**\n * Synchronizes the internal choice elements list with the current DOM state.\n * Also filters the response to only include valid identifiers.\n */\n protected _syncChoicesFromDOM() {\n const previousChoices = new Set(this._choiceElements);\n this._choiceElements = Array.from(this.querySelectorAll(selector)) as Choice[];\n\n // Initialize new choice elements\n this._choiceElements.forEach(choiceElement => {\n if (!previousChoices.has(choiceElement)) {\n // New choice element - initialize it\n if (this.disabled) {\n choiceElement.disabled = true;\n }\n choiceElement.readonly = this.readonly;\n\n if (choiceElement.internals && !choiceElement.internals.ariaChecked) {\n choiceElement.internals.ariaChecked = 'false';\n }\n\n this._setInputType(choiceElement);\n }\n });\n\n // Filter response to only include valid identifiers (handles removal)\n const validIdentifiers = new Set(this._choiceElements.map(c => c.identifier));\n if (Array.isArray(this.response)) {\n const filteredResponse = this.response.filter(id => validIdentifiers.has(id));\n if (filteredResponse.length !== this.response.length) {\n this.response = filteredResponse;\n }\n } else if (this.response && !validIdentifiers.has(this.response)) {\n this.response = '';\n }\n\n // Update selection state to match response\n this._updateChoiceSelection();\n }\n\n public validate(): boolean {\n const selectedChoices = this._choiceElements.filter(choice => this._getChoiceChecked(choice));\n const selectedCount = selectedChoices.length;\n let isValid = true;\n let validityMessage = '';\n if (this.maxChoices !== 0 && selectedCount > this.maxChoices) {\n isValid = false;\n validityMessage =\n this.dataset.maxSelectionsMessage ||\n `Please select no more than ${this.maxChoices} ${this.maxChoices === 1 ? 'option' : 'options'}.`;\n } else if (selectedCount < this.minChoices) {\n isValid = false;\n validityMessage =\n this.dataset.minSelectionsMessage ||\n `Please select at least ${this.minChoices} ${this.minChoices === 1 ? 'option' : 'options'}.`;\n }\n\n // Always set validity state, regardless of whether there are selections\n // Anchor must be a shadow-including descendant of this element, or use this as fallback\n const anchor = this._choiceElements.find(c => this.contains(c)) || this;\n this._internals.setValidity(isValid ? {} : { customError: true }, validityMessage, anchor);\n\n return isValid;\n }\n\n override reportValidity() {\n if (this._validationMessageElement) {\n if (!this._internals.validity.valid) {\n this._validationMessageElement.textContent = this._internals.validationMessage;\n // Set the display to block to show the message, add important to override any styles\n this._validationMessageElement.style.setProperty('display', 'block', 'important');\n this._validationMessageShown = true; // Track that validation message was shown\n } else {\n this._validationMessageElement.textContent = '';\n this._validationMessageElement.style.display = 'none';\n // Don't reset _validationMessageShown here - let it be cleared by user input\n }\n }\n return this._internals.validity.valid;\n }\n\n protected _determineInputType() {\n this._choiceElements.forEach(choice => {\n this._setInputType(choice);\n });\n }\n\n protected _setInputType(choiceElement: Choice) {\n this._internals.role = this.maxChoices === 1 ? 'radiogroup' : null;\n\n if (choiceElement.internals) {\n const role = this.maxChoices === 1 ? 'radio' : 'checkbox';\n choiceElement.internals.role = role;\n choiceElement.internals.states.delete(role === 'radio' ? 'checkbox' : 'radio');\n choiceElement.internals.states.add(role);\n }\n }\n\n protected _choiceElementSelectedHandler(event: CustomEvent<{ identifier: string }>) {\n this._toggleChoiceChecked(event.target as Choice);\n if (this.maxChoices === 1) {\n this._choiceElements.forEach(choice => {\n if (choice.identifier !== event.detail.identifier) {\n this._setChoiceChecked(choice, false);\n }\n });\n } else if (this.maxChoices !== 0 && this._configContext?.disableAfterIfMaxChoicesReached) {\n const selectedChoices = this._choiceElements.filter(choice => this._getChoiceChecked(choice));\n if (selectedChoices.length >= this.maxChoices) {\n this._choiceElements.forEach(choice => {\n if (!this._getChoiceChecked(choice)) {\n choice.disabled = true;\n }\n });\n } else {\n this._choiceElements.forEach(choice => (choice.disabled = false));\n }\n }\n\n this._handleChoiceSelection();\n }\n\n protected _setChoiceChecked(choice: Choice, checked: boolean) {\n if (choice.internals?.states) {\n if (checked) {\n choice.internals.states.add('--checked');\n choice.internals.ariaChecked = 'true';\n } else {\n choice.internals.states.delete('--checked');\n choice.internals.ariaChecked = 'false';\n }\n }\n }\n\n protected _getChoiceChecked(choice: Choice): boolean {\n return choice.internals.states.has('--checked');\n }\n\n protected _toggleChoiceChecked(choice: Choice) {\n const checked = this._getChoiceChecked(choice);\n this._setChoiceChecked(choice, !checked);\n }\n\n protected _handleChoiceSelection() {\n const selectedChoices = this._choiceElements.filter(choice => this._getChoiceChecked(choice));\n const selectedIdentifiers = selectedChoices.map(choice => choice.identifier);\n\n this.response = this.maxChoices === 1 ? selectedIdentifiers[0] || '' : selectedIdentifiers;\n\n this.validate();\n\n // Auto-update validation message if it was previously shown (FACE behavior)\n if (this._validationMessageShown) {\n this.reportValidity();\n // Reset flag if now valid to prevent unnecessary future auto-updates\n if (this._internals.validity.valid) {\n this._validationMessageShown = false;\n }\n }\n\n this.saveResponse(this.response);\n }\n\n /**\n * Updates the selection state of each choice element based on the current response.\n */\n protected _updateChoiceSelection() {\n const responseArray = Array.isArray(this.response) ? this.response : [this.response];\n this._choiceElements.forEach(choice => {\n const isSelected = responseArray.includes(choice.identifier);\n this._setChoiceChecked(choice, isSelected);\n });\n }\n }\n return ChoicesMixinElement as Constructor<ChoicesInterface> & T;\n};\n","import { html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { ChoicesMixin } from '../../mixins/choices/choices.mixin';\nimport { VocabularyMixin } from '../../mixins/vocabulary/vocabulary-mixin';\nimport styles from './qti-choice-interaction.styles';\n\nimport type { ChoicesInterface } from '../../mixins/choices/choices.mixin';\nimport type { CSSResultGroup } from 'lit';\n\nexport type Orientation = 'horizontal' | 'vertical' | undefined;\nexport class QtiChoiceInteraction\n extends VocabularyMixin(ChoicesMixin(Interaction, 'qti-simple-choice'), 'qti-simple-choice')\n implements ChoicesInterface\n{\n static override styles: CSSResultGroup = styles;\n\n /** @deprecated, use 'qti-orientation-horizontal' or 'qti-orientation-vertical' instead */\n @property({ type: String })\n public orientation: Orientation = 'vertical';\n\n private _handleSlotChange() {\n // count the number of choices, set a css variable for the number of choices\n const choices = this.querySelectorAll('qti-simple-choice');\n this.style.setProperty('--item-count', choices.length.toString());\n }\n\n override render() {\n return html`\n <slot part=\"prompt\" name=\"prompt\"></slot>\n <slot part=\"slot\" @slotchange=${this._handleSlotChange}></slot>\n <div part=\"message\" role=\"alert\" id=\"validation-message\"></div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-choice-interaction': QtiChoiceInteraction;\n }\n}\n","import { html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { Interaction, removeDoubleSlashes } from '@qti-components/base';\n\n/**\n * CES (Custom Element Standard) Custom Interaction Support\n *\n * This component provides runtime support for legacy custom interactions that were built\n * for the CES player - the predecessor to what is now known as FACET and the Trifork QTI Player.\n *\n * These custom interactions use a specific API pattern:\n * - A manifest.json file that references script, style, and media files\n * - A bootstrap.js script that creates an iframe and loads the interaction's index.html\n * - A global CES object that provides: getMedia(), getResponse(), setResponse(), setStageHeight()\n *\n * The challenge is that when these interactions are embedded in iframes (especially those\n * created via document.write() which have about:blank origin), they cannot:\n * - Access the parent's global CES object (cross-origin restriction)\n * - Load external scripts via service workers (about:blank is not controlled)\n *\n * This implementation solves these problems by:\n * 1. Fetching the interaction's index.html from the main window (where service workers work)\n * 2. Injecting a CES proxy (registerCES) that uses postMessage to communicate with the parent\n * 3. Creating a blob URL for the modified HTML\n * 4. Using a simplified bootstrap (ciBootstrap) that loads the pre-created blob URL\n *\n * This approach is transparent - the original package files remain unchanged and the\n * transformation happens entirely at runtime within this web component.\n */\n\n// CES API proxy that gets injected into the index.html\n// This provides the CES object that the custom interaction expects,\n// but uses postMessage to communicate with the parent qti-custom-interaction component\nconst registerCES = `\nconst postToParentWindows = (type, data) => {\n window.top.postMessage(data ? { type, data } : { type }, '*');\n let w = window.parent;\n while (w) {\n if (w !== window.top) {\n w.postMessage({ type, data }, '*');\n }\n if (w !== w.parent) {\n w = w.parent;\n } else {\n w = null;\n }\n }\n};\n\nwindow.CES = {\n media: null,\n response: null,\n load: () => {\n let resolveCount = 0;\n\n const handleMessage = (event) => {\n if (event.data.type === \"mediaData\") {\n const media = event.data.data;\n CES.media = media;\n resolveCount++;\n } else if (event.data.type === \"responseData\") {\n const response = event.data.data;\n if (response && Array.isArray(response) && response.length > 0) {\n // state is stored in the first element of the array\n CES.response = response[0];\n // Wait a short moment to ensure CES.response is set\n setTimeout(() => {\n // Re-create the Controller instance if it exists\n if (typeof Controller === 'function') {\n console.log(\"Re-creating Controller instance\");\n ctrl = new Controller();\n }\n }, 50);\n } else { \n CES.response = response;\n }\n resolveCount++;\n }\n if (resolveCount === 2) {\n //window.removeEventListener(\"message\", handleMessage);\n }\n };\n window.addEventListener(\"message\", handleMessage);\n postToParentWindows(\"getMedia\");\n postToParentWindows(\"getResponse\");\n },\n setResponse: (data) => {\n postToParentWindows(\"setResponse\", data);\n },\n getResponse: () => {\n return CES.response;\n },\n getMedia: () => {\n return CES.media;\n },\n setStageHeight: () => {\n postToParentWindows(\"setStageHeight\");\n },\n};\nCES.load();\n`;\n\n// Simple bootstrap that just waits for the blob URL and creates the iframe\nconst ciBootstrap = `\n window.onload = function () {\n const handleMessage = (event) => {\n if (event.data.type === 'blobUrl') {\n const blobUrl = event.data.data;\n var n = document.createElement('iframe');\n n.frameBorder = '0';\n n.scrolling = 'no';\n n.src = blobUrl;\n n.style.width = '100%';\n n.style.height = '100%';\n document.body.appendChild(n);\n window.removeEventListener('message', handleMessage);\n }\n };\n window.addEventListener('message', handleMessage);\n // Request the blob URL from parent\n let w = window.parent;\n while (w) {\n w.postMessage({ type: 'getBlobUrl' }, '*');\n if (w !== w.parent) {\n w = w.parent;\n } else {\n w = null;\n }\n }\n };\n`;\n\n/**\n * QTI Custom Interaction component for legacy CES-based interactions.\n *\n * This component implements support for custom interactions originally built for the CES\n * (Custom Element Standard) player - the predecessor to FACET and the Trifork QTI Player.\n *\n * @remarks\n * The interaction workflow:\n * 1. Fetch the CI manifest (JSON file with script, style, media references)\n * 2. Check if bootstrap.js uses the CES API\n * 3. If CES is used:\n * - Fetch index.html from main window (where service worker/fetch works)\n * - Inject registerCES proxy script for postMessage-based communication\n * - Create blob URL and pass it to ciBootstrap\n * 4. Create pciContainer iframe with style and bootstrap script\n * 5. Handle postMessage events for getMedia, getResponse, setResponse, getBlobUrl\n *\n * The postMessage bridge is necessary because:\n * - Iframes created via document.write() have about:blank origin\n * - They cannot access the parent's global CES object (cross-origin)\n * - Service workers don't control about:blank documents\n *\n * Messages are sent to all parent windows to support embedding scenarios like Storybook\n * where window.top might not be the actual host application.\n */\n\nexport class QtiCustomInteraction extends Interaction {\n private rawResponse: string | string[] = '';\n private _manifestUrl: string = null;\n private _resourceBaseUrl: string = null;\n\n constructor() {\n super();\n this.handlePostMessage = this.handlePostMessage.bind(this);\n }\n\n @property({ type: String, attribute: 'data' })\n data: string;\n\n @property({ type: String, attribute: 'data-base-item' })\n baseItemUrl: string;\n\n @property({ type: String, attribute: 'data-base-ref' })\n baseRefUrl: string;\n\n @property({ type: String, attribute: 'id' })\n override id: string;\n\n @state()\n private _errorMessage: string = null;\n manifest: {\n script: string[];\n style: string[];\n media: string[];\n };\n // Pre-created blob URL for the index.html with injected CES proxy\n private _contentBlobUrl: string = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n // Support two QTI formats:\n // 1. data attribute directly on qti-custom-interaction: <qti-custom-interaction data=\"manifest.json\">\n // 2. object child element: <qti-custom-interaction><object data=\"manifest.json\"></qti-custom-interaction>\n let manifestPath = this.data;\n\n if (!manifestPath) {\n // Try to get from child <object> element\n const objectEl = this.querySelector('object[data]');\n if (objectEl) {\n manifestPath = objectEl.getAttribute('data');\n // Also get width/height from the object element if available\n const width = objectEl.getAttribute('width');\n const height = objectEl.getAttribute('height');\n if (width) this.setAttribute('width', width);\n if (height) this.setAttribute('height', height);\n }\n }\n\n if (!manifestPath) {\n this._errorMessage = 'No manifest path found (neither data attribute nor object child)';\n return;\n }\n\n const uriToManifest =\n manifestPath.startsWith('http') || manifestPath.startsWith('blob')\n ? manifestPath\n : removeDoubleSlashes((this.baseItemUrl || '') + '/' + manifestPath);\n this._manifestUrl = new URL(uriToManifest, window.location.href).toString();\n // fetch the json file located at the data attribute\n fetch(uriToManifest)\n .then(response => {\n return response.json();\n })\n .then(data => {\n this.manifest = data;\n this.setupCES();\n })\n .catch(err => {\n this._errorMessage = err;\n });\n }\n\n /**\n * Sets up the CES custom interaction by creating the iframe structure and\n * handling the CES API communication via postMessage.\n *\n * For interactions that use CES, this method:\n * 1. Fetches the original bootstrap.js and checks if it uses CES\n * 2. If CES is used, fetches index.html and injects the registerCES proxy\n * 3. Creates a blob URL for the modified HTML (stored in _contentBlobUrl)\n * 4. Replaces bootstrap.js with ciBootstrap that loads the blob URL\n * 5. Sets up postMessage listeners for CES API calls\n */\n async setupCES() {\n // Ensure the iframe exists and has a document before writing into it.\n // In some environments (e.g. Storybook/Vitest browser mode) the iframe can exist but its\n // `contentDocument` is still null momentarily, which would otherwise cause an unhandled rejection.\n await this.updateComplete;\n const iframe = this.shadowRoot?.querySelector('#pciContainer') as HTMLIFrameElement | null;\n if (!iframe) {\n this._errorMessage = 'pciContainer iframe not found';\n return;\n }\n\n if (!iframe.getAttribute('src')) {\n // Make sure the iframe navigates so we get a document we can write to.\n iframe.setAttribute('src', 'about:blank');\n }\n\n let iframeDoc = iframe.contentDocument ?? iframe.contentWindow?.document ?? null;\n if (!iframeDoc) {\n await new Promise<void>(resolve => iframe.addEventListener('load', () => resolve(), { once: true }));\n iframeDoc = iframe.contentDocument ?? iframe.contentWindow?.document ?? null;\n }\n if (!iframeDoc) {\n this._errorMessage = 'pciContainer iframe document not available';\n return;\n }\n\n if (!this.manifest.script || this.manifest.script.length === 0) {\n this._errorMessage = 'No script found in manifest';\n return;\n }\n if (!this.manifest.style || this.manifest.style.length === 0) {\n this._errorMessage = 'No style found in manifest';\n return;\n }\n const cssRef = this.manifest.style[0];\n\n const baseCandidates = this.getBaseCandidates();\n console.debug('[qti-custom-interaction] manifest url', this._manifestUrl);\n console.debug('[qti-custom-interaction] base candidates', baseCandidates);\n console.debug('[qti-custom-interaction] refs', { cssRef, media: this.manifest.media });\n\n const cssResolved = await this.resolveResourceWithFallback(cssRef, baseCandidates);\n const cssUrl = cssResolved.url;\n if (cssResolved.baseUrl && !this._resourceBaseUrl) {\n this._resourceBaseUrl = cssResolved.baseUrl;\n }\n console.debug('[qti-custom-interaction] css resolved', cssResolved);\n\n // Always use the built-in ciBootstrap instead of the package's bootstrap.js.\n // The package's bootstrap.js is the original CES version which doesn't work\n // in the iframe/postMessage setup. Our ciBootstrap handles this correctly.\n const usesCES = true;\n console.debug('[qti-custom-interaction] using built-in ciBootstrap (skipping server bootstrap.js)');\n\n // If the original bootstrap.js uses CES, we need to:\n // 1. Fetch the index.html from here (main window, where service worker works)\n // 2. Inject the registerCES proxy script\n // 3. Create a blob URL and store it\n // 4. Use ciBootstrap to request and load the blob URL\n if (usesCES) {\n // Try to get index.html path from manifest.media, or construct it from the manifest path\n let indexUrl = '';\n if (this.manifest.media && this.manifest.media.length > 0) {\n const mediaRef = this.manifest.media[0];\n const indexResolved = await this.resolveResourceWithFallback(mediaRef, baseCandidates, {\n returnText: true\n });\n indexUrl = indexResolved.url;\n if (indexResolved.baseUrl && !this._resourceBaseUrl) {\n this._resourceBaseUrl = indexResolved.baseUrl;\n }\n console.debug('[qti-custom-interaction] index resolved (media)', {\n url: indexResolved.url,\n baseUrl: indexResolved.baseUrl,\n hasText: Boolean(indexResolved.text)\n });\n if (indexResolved.text) {\n let html = indexResolved.text;\n\n // Inject the CES proxy script after <head>\n const cesScript = '<script>' + registerCES + '</' + 'script>';\n const headIndex = html.indexOf('<head>');\n if (headIndex !== -1) {\n html = html.slice(0, headIndex + 6) + cesScript + html.slice(headIndex + 6);\n } else {\n // If no <head>, prepend to document\n html = cesScript + html;\n }\n\n // Create a blob URL for the modified HTML\n const blob = new Blob([html], { type: 'text/html' });\n this._contentBlobUrl = URL.createObjectURL(blob);\n }\n } else {\n // If no media array, try to construct index.html path from the manifest location\n // Assume index.html is in the same directory as the manifest\n const manifestPath = this.data || 'manifest.json';\n const basePath = manifestPath.includes('/') ? manifestPath.substring(0, manifestPath.lastIndexOf('/')) : '';\n const indexPath = basePath ? `${basePath}/index.html` : 'index.html';\n const indexResolved = await this.resolveResourceWithFallback(indexPath, baseCandidates, {\n returnText: true\n });\n indexUrl = indexResolved.url;\n if (indexResolved.baseUrl && !this._resourceBaseUrl) {\n this._resourceBaseUrl = indexResolved.baseUrl;\n }\n console.debug('[qti-custom-interaction] index resolved (fallback)', {\n url: indexResolved.url,\n baseUrl: indexResolved.baseUrl,\n hasText: Boolean(indexResolved.text)\n });\n if (indexResolved.text) {\n let html = indexResolved.text;\n\n // Inject the CES proxy script after <head>\n const cesScript = '<script>' + registerCES + '</' + 'script>';\n const headIndex = html.indexOf('<head>');\n if (headIndex !== -1) {\n html = html.slice(0, headIndex + 6) + cesScript + html.slice(headIndex + 6);\n } else {\n // If no <head>, prepend to document\n html = cesScript + html;\n }\n\n // Create a blob URL for the modified HTML\n const blob = new Blob([html], { type: 'text/html' });\n this._contentBlobUrl = URL.createObjectURL(blob);\n }\n }\n\n if (indexUrl && !this._contentBlobUrl) {\n try {\n const indexResponse = await fetch(indexUrl);\n if (indexResponse.ok) {\n let html = await indexResponse.text();\n\n // Inject the CES proxy script after <head>\n const cesScript = '<script>' + registerCES + '</' + 'script>';\n const headIndex = html.indexOf('<head>');\n if (headIndex !== -1) {\n html = html.slice(0, headIndex + 6) + cesScript + html.slice(headIndex + 6);\n } else {\n // If no <head>, prepend to document\n html = cesScript + html;\n }\n\n // Create a blob URL for the modified HTML\n const blob = new Blob([html], { type: 'text/html' });\n this._contentBlobUrl = URL.createObjectURL(blob);\n } else {\n console.error(`Failed to fetch index.html: ${indexResponse.status}`);\n }\n } catch (e) {\n console.error(`Error fetching index.html: ${e}`);\n }\n }\n }\n\n const inlineScript = `<script>${ciBootstrap}</script>`;\n console.debug('[qti-custom-interaction] using ciBootstrap inline script');\n\n window.addEventListener('message', this.handlePostMessage);\n iframeDoc.open();\n iframeDoc.write(`\n <html>\n <head>\n ${cssUrl ? `<link href='${cssUrl}' rel=\"stylesheet\" />` : ''}\n ${inlineScript}\n </head>\n <body></body>\n </html>\n `);\n\n iframeDoc.close();\n }\n\n private getIFrames() {\n const iframesInShadowRoot = this.shadowRoot.querySelectorAll('iframe');\n const iframe = this.querySelectorAll('iframe');\n\n const outerIFrames = [...iframesInShadowRoot, ...iframe];\n for (const iframe of outerIFrames) {\n const iframeSrc = iframe.src;\n const isSameOrigin = new URL(iframeSrc, window.location.href).origin === window.location.origin;\n if (isSameOrigin) {\n try {\n const outerDoc = iframe.contentDocument || iframe.contentWindow.document;\n if (outerDoc) {\n this.getInnerIFrames(outerDoc, outerIFrames);\n }\n } catch (e) {\n console.error('Error accessing nested iframe:', e);\n }\n }\n }\n // get only unique iframes\n outerIFrames.forEach((iframe, index) => {\n if (outerIFrames.indexOf(iframe) !== index) {\n outerIFrames.splice(index, 1);\n }\n });\n return outerIFrames;\n }\n\n private getInnerIFrames(iframeDocument: Document, iframes: HTMLIFrameElement[] = []) {\n // Get all iframes in the current document\n const currentIframes = iframeDocument.querySelectorAll('iframe');\n\n currentIframes.forEach(iframe => {\n // Add the current iframe to the list\n iframes.push(iframe);\n\n // Recursively get iframes within the current iframe\n // Check if the iframe src is from the same origin\n const iframeSrc = iframe.src;\n const isSameOrigin = new URL(iframeSrc, window.location.href).origin === window.location.origin;\n\n if (isSameOrigin) {\n try {\n const nestedDoc = iframe.contentDocument || iframe.contentWindow.document;\n this.getInnerIFrames(nestedDoc, iframes);\n } catch (e) {\n console.error('Error accessing nested iframe:', e);\n }\n } else {\n console.warn('Skipped cross-origin iframe:', iframeSrc);\n }\n });\n\n return iframes;\n }\n\n private postToWindowAndIframes(type: string, data: any) {\n window.postMessage({ type, data }, '*');\n const iframes = this.getIFrames();\n for (const iframe of iframes) {\n if (iframe.contentWindow) {\n iframe.contentWindow.postMessage({ type, data }, '*');\n }\n }\n }\n\n handlePostMessage(event: MessageEvent) {\n const { type, data } = event.data;\n if (type && type !== 'setResponse') {\n console.debug('[qti-custom-interaction] postMessage', { type, data });\n }\n switch (type) {\n case 'setResponse':\n if (data === null || !(Array.isArray(data) && data.length === 1 && data[0] === '')) {\n this.rawResponse = data;\n this.saveResponse(data);\n }\n break;\n case 'getResponse': {\n this.postToWindowAndIframes('responseData', this.rawResponse);\n break;\n }\n case 'getBlobUrl': {\n // Send the pre-created blob URL to the requesting iframe\n if (this._contentBlobUrl) {\n this.postToWindowAndIframes('blobUrl', this._contentBlobUrl);\n }\n break;\n }\n case 'getMedia': {\n const baseCandidates = this.getBaseCandidates();\n const mediaData = this.manifest.media.map(media => {\n if (media.startsWith('http') || media.startsWith('blob')) {\n return media;\n }\n const baseUrl = this._resourceBaseUrl || baseCandidates[0];\n if (!baseUrl) {\n return media;\n }\n return new URL(media, baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`).toString();\n });\n console.debug('[qti-custom-interaction] mediaData', mediaData);\n this.postToWindowAndIframes('mediaData', mediaData);\n break;\n }\n case 'setStageHeight':\n console.log('setStageHeight not implemented');\n break;\n }\n }\n\n validate(): boolean {\n if (!this.rawResponse) {\n return false;\n }\n if (Array.isArray(this.rawResponse)) {\n if (this.rawResponse.length === 0) {\n return false;\n }\n // check if one of the values has a value\n for (const value of this.rawResponse) {\n if (value !== '' && value !== null) {\n return true;\n }\n }\n }\n return true;\n }\n\n get response(): string | string[] | null {\n return (this.rawResponse as string | string[]) || null;\n }\n\n set response(val: string | string[] | null) {\n if (typeof val === 'string') {\n this.rawResponse = val;\n this.saveResponse(val);\n } else if (Array.isArray(val)) {\n this.rawResponse = val;\n } else if (!val) {\n // do nothing\n } else {\n throw new Error('Value must be a string or an array of strings');\n }\n }\n\n override disconnectedCallback(): void {\n window.removeEventListener('message', this.handlePostMessage);\n super.disconnectedCallback();\n }\n\n override render() {\n return html`<iframe\n width=${this.getAttribute('width')}\n height=${this.getAttribute('height')}\n frameborder=\"0\"\n title=\"pciContainer\"\n id=\"pciContainer\"\n >\n </iframe>\n ${this._errorMessage &&\n html`<div style=\"color:red\">\n <h1>Error</h1>\n ${this._errorMessage}\n </div>`}`;\n }\n\n private getBaseCandidates(): string[] {\n const candidates = [this._resourceBaseUrl, this.baseRefUrl, this.baseItemUrl, this.getManifestBaseUrl()];\n const resolved = candidates.filter(Boolean).map(base => new URL(base, window.location.href).toString());\n\n // Also add the manifest's parent directory (e.g. go up from .../json/ to .../)\n const manifestParent = this.getManifestParentBaseUrl();\n if (manifestParent) {\n resolved.push(manifestParent);\n }\n\n // Deduplicate\n return [...new Set(resolved)];\n }\n\n private getManifestBaseUrl(): string | null {\n if (!this._manifestUrl) {\n return null;\n }\n return new URL('.', this._manifestUrl).toString();\n }\n\n private getManifestParentBaseUrl(): string | null {\n if (!this._manifestUrl) {\n return null;\n }\n // Go up one more level from the manifest directory (e.g. from .../json/ to .../)\n // This helps when manifest.json is in a subdirectory but resources are at the parent level\n return new URL('..', this._manifestUrl).toString();\n }\n\n private async resolveResourceWithFallback(\n ref: string,\n baseCandidates: string[],\n options: { returnText?: boolean } = {}\n ): Promise<{ url: string; baseUrl: string | null; text?: string }> {\n if (!ref) {\n return { url: '', baseUrl: null };\n }\n if (ref.startsWith('http') || ref.startsWith('blob')) {\n return { url: ref, baseUrl: null };\n }\n\n for (const base of baseCandidates) {\n const baseUrl = new URL(base, window.location.href).toString();\n const url = new URL(ref, baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`).toString();\n try {\n const response = await fetch(url);\n if (response.ok) {\n if (options.returnText) {\n const text = await response.text();\n return { url, baseUrl, text };\n }\n return { url, baseUrl };\n }\n } catch (e) {\n // try next base\n }\n }\n\n return { url: '', baseUrl: null };\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-custom-interaction': QtiCustomInteraction;\n }\n}\n","import { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nexport class QtiEndAttemptInteraction extends LitElement {\n @property({ type: String, attribute: 'response-identifier' }) responseIdentifier: string;\n\n @property({ reflect: true, type: Boolean }) disabled = false;\n\n /** Defines the number of attempts that a user can make using the 'endAttemptInteraction' mechanism (this can be used to limit the number of hints, etc.). [More information](https://www.imsglobal.org/sites/default/files/spec/qti/v3/info/index.html#DataCharacteristic_EndAttemptInteraction.Attr_count-attempt) */\n @property({ type: String, attribute: 'count-attempt' })\n public countAttempt: 'true' | 'false' | null = null;\n\n @property({ type: String })\n public override title: string = 'end attempt';\n\n override render() {\n return html`<button ?disabled=${this.disabled} part=\"button\" @click=${this.endAttempt}>${this.title}</button>`;\n }\n public endAttempt(_: Event) {\n this.dispatchEvent(\n new CustomEvent('end-attempt', {\n bubbles: true,\n composed: true,\n detail: { responseIdentifier: this.responseIdentifier, countAttempt: this.countAttempt === 'true' }\n })\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-end-attempt-interaction': QtiEndAttemptInteraction;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n /* PK: display host as block, else design will be collapsed */\n :host {\n display: block;\n }\n textarea {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border: 0;\n }\n`;\n","import { html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { property, state } from 'lit/decorators.js';\n\nimport { watch } from '@qti-components/utilities';\nimport { Interaction } from '@qti-components/base';\n\nimport styles from './qti-extended-text-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nexport class QtiExtendedTextInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\n\n @state()\n protected _rows = 5;\n\n /** expected length is mapped to the property maxlength on the textarea */\n @property({ type: Number, attribute: 'expected-length' }) expectedLength: number;\n\n @property({ type: String, attribute: 'pattern-mask' }) patternMask: string;\n\n /** text appearing in the extended-text-interaction if it is empty */\n @property({ type: String, attribute: 'placeholder-text' }) placeholderText: string;\n\n @property({ type: String, attribute: 'data-patternmask-message' }) dataPatternmaskMessage: string;\n\n @property({ type: String, attribute: 'class' }) classNames: string;\n @watch('classNames')\n handleclassNamesChange(_: any, classes: string) {\n const classNames = classes.split(' ');\n let rowsSet = false;\n classNames.forEach((className: string) => {\n if (className.startsWith('qti-height-lines-')) {\n const nrRows = className.replace('qti-height-lines-', '');\n this._rows = parseInt(nrRows);\n rowsSet = true;\n }\n });\n // If no qti-height-lines class is set, calculate rows based on expectedLength\n if (!rowsSet && this.expectedLength) {\n const estimatedRows = Math.ceil(this.expectedLength / 50); // '50' based on an estimate for characters per row\n this._rows = estimatedRows;\n }\n }\n\n @state()\n response: string | null = null;\n\n @watch('response', { waitUntilFirstUpdate: true })\n protected _handleResponseChange = () => {\n this._internals.setFormValue(this.value);\n this.validate();\n };\n\n override get value(): string | null {\n return this.response || null;\n }\n override set value(val: string | null) {\n this.response = val || null;\n }\n\n public override validate() {\n const textarea = this.shadowRoot.querySelector('textarea');\n if (!textarea) return false;\n\n if (this.patternMask && this.dataPatternmaskMessage) {\n // Clear any custom error initially\n this._internals.setValidity({});\n textarea.setCustomValidity('');\n const patternSource =\n this.patternMask.startsWith('^') && this.patternMask.endsWith('$') ? this.patternMask : `^${this.patternMask}$`;\n\n const pattern = new RegExp(patternSource);\n const isValid = textarea.checkValidity() && pattern.test(textarea.value);\n\n if (!isValid) {\n // Set custom error if invalid\n this._internals.setValidity({ customError: true }, this.dataPatternmaskMessage);\n textarea.setCustomValidity(this.dataPatternmaskMessage);\n }\n } else {\n const isValid = textarea.checkValidity();\n this._internals.setValidity(isValid ? {} : { customError: false });\n }\n\n return !!this.response && textarea.checkValidity();\n }\n\n public override toggleCorrectResponse() {\n // No correct response possible for extended text interactions\n }\n\n override reportValidity() {\n const textarea = this.shadowRoot.querySelector('textarea');\n if (!textarea) return false;\n\n // Run the validate function to ensure the custom validity state is up to date\n const isValid = this.validate();\n if (!isValid) {\n textarea.reportValidity();\n }\n return isValid;\n }\n\n override render() {\n return html`<slot name=\"prompt\"></slot\n ><textarea\n part=\"textarea\"\n name=\"${this.responseIdentifier}\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n maxlength=\"${5000}\"\n @keydown=\"${(event: KeyboardEvent) => event.stopImmediatePropagation()}\"\n @keyup=\"${this.textChanged}\"\n @change=\"${this.textChanged}\"\n @blur=\"${(_: FocusEvent) => {\n this.reportValidity();\n }}\"\n placeholder=\"${ifDefined(this.placeholderText ? this.placeholderText : undefined)}\"\n rows=\"${this._rows}\"\n ?disabled=\"${this.disabled}\"\n ?readonly=\"${this.readonly}\"\n .value=${this.response}\n ></textarea>`;\n }\n\n protected textChanged(event: Event) {\n if (this.disabled || this.readonly) return;\n const input = event.target as HTMLInputElement;\n this.setEmptyAttribute(input.value);\n if (this.response !== input.value) {\n this.value = input.value;\n this.saveResponse(input.value);\n }\n }\n\n protected setEmptyAttribute(text: string) {\n this.setAttribute('empty', text === '' ? 'true' : 'false');\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-extended-text-interaction': QtiExtendedTextInteraction;\n }\n}\n","import { css } from 'lit';\n// import componentStyles from '../../utilities/styles/component.styles';\n// :host {\n// display: inline-block;\n// position: relative;\n// }\n/* ${componentStyles} */\nexport default css`\n :host {\n display: flex;\n align-items: flex-start;\n flex-direction: column;\n flex-wrap: wrap;\n gap: 0.5rem;\n }\n\n :host(.qti-choices-top) {\n flex-direction: column;\n }\n :host(.qti-choices-bottom) {\n flex-direction: column-reverse;\n }\n :host(.qti-choices-left) {\n flex-direction: row;\n }\n :host(.qti-choices-right) {\n flex-direction: row-reverse;\n }\n /* [part='drops'] , */\n [name='prompt'] {\n width: 100%;\n }\n [name='drags'] {\n display: flex;\n align-items: flex-start;\n flex: 1;\n border: 2px solid transparent;\n padding: 0.3rem;\n border-radius: 0.3rem;\n gap: 0.5rem;\n }\n`;\n","import { html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { DragDropInteractionMixin } from '../../mixins/drag-drop/drag-drop-interaction-mixin.js';\nimport styles from './qti-gap-match-interaction.styles.js';\n\nimport type { ResponseVariable } from '@qti-components/base';\nimport type { QtiGap } from '../../elements/qti-gap';\nimport type { CSSResultGroup } from 'lit';\nexport class QtiGapMatchInteraction extends DragDropInteractionMixin(\n Interaction,\n 'qti-gap-text',\n 'qti-gap',\n `slot[part='drags']`\n) {\n static override styles: CSSResultGroup = styles;\n\n override render() {\n return html`<slot name=\"prompt\"> </slot>\n <slot part=\"drags\" name=\"drags\"></slot>\n <slot part=\"drops\"></slot>\n <div role=\"alert\" part=\"message\" id=\"validation-message\"></div>`;\n }\n\n public override toggleCorrectResponse(show: boolean): void {\n const responseVariable = this.responseVariable;\n\n if (show && responseVariable?.correctResponse) {\n let matches: { text: string; gap: string }[] = [];\n const response = Array.isArray(responseVariable.correctResponse)\n ? responseVariable.correctResponse\n : [responseVariable.correctResponse];\n\n if (response) {\n matches = response.map(x => {\n const split = x.split(' ');\n return { text: split[0], gap: split[1] };\n });\n }\n\n const gaps = this.querySelectorAll('qti-gap');\n gaps.forEach(gap => {\n const identifier = gap.getAttribute('identifier');\n const textIdentifier = matches.find(x => x.gap === identifier)?.text;\n const text = this.querySelector(`qti-gap-text[identifier=\"${textIdentifier}\"]`)?.textContent.trim();\n if (textIdentifier && text) {\n if (!gap.nextElementSibling?.classList.contains('correct-option')) {\n const textSpan = document.createElement('span');\n textSpan.classList.add('correct-option');\n textSpan.textContent = text;\n\n // Apply styles\n textSpan.style.border = '1px solid var(--qti-correct)';\n textSpan.style.borderRadius = '4px';\n textSpan.style.padding = '2px 4px';\n textSpan.style.display = 'inline-block';\n\n gap.insertAdjacentElement('afterend', textSpan);\n }\n } else if (gap.nextElementSibling?.classList.contains('correct-option')) {\n gap.nextElementSibling.remove();\n }\n });\n } else {\n const correctOptions = this.querySelectorAll('.correct-option');\n correctOptions.forEach(option => {\n option.remove();\n });\n }\n }\n\n private getMatches(responseVariable: ResponseVariable): { source: string; target: string }[] {\n if (!responseVariable.correctResponse) {\n return [];\n }\n const correctResponse = Array.isArray(responseVariable.correctResponse)\n ? responseVariable.correctResponse\n : [responseVariable.correctResponse];\n\n const matches: { source: string; target: string }[] = [];\n if (correctResponse) {\n correctResponse.forEach(x => {\n const split = x.split(' ');\n matches.push({ source: split[0], target: split[1] });\n });\n }\n return matches;\n }\n\n public override toggleCandidateCorrection(show: boolean) {\n const responseVariable = this.responseVariable;\n\n if (!responseVariable?.correctResponse) {\n return;\n }\n const matches = this.getMatches(responseVariable);\n\n const targetChoices = Array.from<QtiGap>(this.querySelectorAll('qti-gap'));\n targetChoices.forEach(targetChoice => {\n const targetId = targetChoice.getAttribute('identifier');\n const targetMatches = matches.filter(m => m.target === targetId);\n\n const selectedChoices = targetChoice.querySelectorAll(`qti-gap-text`);\n\n selectedChoices.forEach(selectedChoice => {\n selectedChoice.internals.states.delete('candidate-correct');\n selectedChoice.internals.states.delete('candidate-incorrect');\n\n if (!show) {\n return;\n }\n\n const isCorrect = targetMatches.find(m => m.source === selectedChoice.identifier)?.source !== undefined;\n if (isCorrect) {\n selectedChoice.internals.states.add('candidate-correct');\n } else {\n selectedChoice.internals.states.add('candidate-incorrect');\n }\n });\n });\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-gap-match-interaction': QtiGapMatchInteraction;\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {ChildPart, noChange} from '../lit-html.js';\nimport {directive, Directive, PartInfo, PartType} from '../directive.js';\nimport {\n insertPart,\n getCommittedValue,\n removePart,\n setCommittedValue,\n setChildPartValue,\n} from '../directive-helpers.js';\n\nexport type KeyFn<T> = (item: T, index: number) => unknown;\nexport type ItemTemplate<T> = (item: T, index: number) => unknown;\n\n// Helper for generating a map of array item to its index over a subset\n// of an array (used to lazily generate `newKeyToIndexMap` and\n// `oldKeyToIndexMap`)\nconst generateMap = (list: unknown[], start: number, end: number) => {\n const map = new Map<unknown, number>();\n for (let i = start; i <= end; i++) {\n map.set(list[i], i);\n }\n return map;\n};\n\nclass RepeatDirective extends Directive {\n private _itemKeys?: unknown[];\n\n constructor(partInfo: PartInfo) {\n super(partInfo);\n if (partInfo.type !== PartType.CHILD) {\n throw new Error('repeat() can only be used in text expressions');\n }\n }\n\n private _getValuesAndKeys<T>(\n items: Iterable<T>,\n keyFnOrTemplate: KeyFn<T> | ItemTemplate<T>,\n template?: ItemTemplate<T>\n ) {\n let keyFn: KeyFn<T> | undefined;\n if (template === undefined) {\n template = keyFnOrTemplate;\n } else if (keyFnOrTemplate !== undefined) {\n keyFn = keyFnOrTemplate as KeyFn<T>;\n }\n const keys = [];\n const values = [];\n let index = 0;\n for (const item of items) {\n keys[index] = keyFn ? keyFn(item, index) : index;\n values[index] = template!(item, index);\n index++;\n }\n return {\n values,\n keys,\n };\n }\n\n render<T>(items: Iterable<T>, template: ItemTemplate<T>): Array<unknown>;\n render<T>(\n items: Iterable<T>,\n keyFn: KeyFn<T> | ItemTemplate<T>,\n template: ItemTemplate<T>\n ): Array<unknown>;\n render<T>(\n items: Iterable<T>,\n keyFnOrTemplate: KeyFn<T> | ItemTemplate<T>,\n template?: ItemTemplate<T>\n ) {\n return this._getValuesAndKeys(items, keyFnOrTemplate, template).values;\n }\n\n override update<T>(\n containerPart: ChildPart,\n [items, keyFnOrTemplate, template]: [\n Iterable<T>,\n KeyFn<T> | ItemTemplate<T>,\n ItemTemplate<T>,\n ]\n ) {\n // Old part & key lists are retrieved from the last update (which may\n // be primed by hydration)\n const oldParts = getCommittedValue(\n containerPart\n ) as Array<ChildPart | null>;\n const {values: newValues, keys: newKeys} = this._getValuesAndKeys(\n items,\n keyFnOrTemplate,\n template\n );\n\n // We check that oldParts, the committed value, is an Array as an\n // indicator that the previous value came from a repeat() call. If\n // oldParts is not an Array then this is the first render and we return\n // an array for lit-html's array handling to render, and remember the\n // keys.\n if (!Array.isArray(oldParts)) {\n this._itemKeys = newKeys;\n return newValues;\n }\n\n // In SSR hydration it's possible for oldParts to be an array but for us\n // to not have item keys because the update() hasn't run yet. We set the\n // keys to an empty array. This will cause all oldKey/newKey comparisons\n // to fail and execution to fall to the last nested brach below which\n // reuses the oldPart.\n const oldKeys = (this._itemKeys ??= []);\n\n // New part list will be built up as we go (either reused from\n // old parts or created for new keys in this update). This is\n // saved in the above cache at the end of the update.\n const newParts: ChildPart[] = [];\n\n // Maps from key to index for current and previous update; these\n // are generated lazily only when needed as a performance\n // optimization, since they are only required for multiple\n // non-contiguous changes in the list, which are less common.\n let newKeyToIndexMap!: Map<unknown, number>;\n let oldKeyToIndexMap!: Map<unknown, number>;\n\n // Head and tail pointers to old parts and new values\n let oldHead = 0;\n let oldTail = oldParts.length - 1;\n let newHead = 0;\n let newTail = newValues.length - 1;\n\n // Overview of O(n) reconciliation algorithm (general approach\n // based on ideas found in ivi, vue, snabbdom, etc.):\n //\n // * We start with the list of old parts and new values (and\n // arrays of their respective keys), head/tail pointers into\n // each, and we build up the new list of parts by updating\n // (and when needed, moving) old parts or creating new ones.\n // The initial scenario might look like this (for brevity of\n // the diagrams, the numbers in the array reflect keys\n // associated with the old parts or new values, although keys\n // and parts/values are actually stored in parallel arrays\n // indexed using the same head/tail pointers):\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, 2, 3, 4, 5, 6]\n // newParts: [ , , , , , , ]\n // newKeys: [0, 2, 1, 4, 3, 7, 6] <- reflects the user's new\n // item order\n // newHead ^ ^ newTail\n //\n // * Iterate old & new lists from both sides, updating,\n // swapping, or removing parts at the head/tail locations\n // until neither head nor tail can move.\n //\n // * Example below: keys at head pointers match, so update old\n // part 0 in-place (no need to move it) and record part 0 in\n // the `newParts` list. The last thing we do is advance the\n // `oldHead` and `newHead` pointers (will be reflected in the\n // next diagram).\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, 2, 3, 4, 5, 6]\n // newParts: [0, , , , , , ] <- heads matched: update 0\n // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance both oldHead\n // & newHead\n // newHead ^ ^ newTail\n //\n // * Example below: head pointers don't match, but tail\n // pointers do, so update part 6 in place (no need to move\n // it), and record part 6 in the `newParts` list. Last,\n // advance the `oldTail` and `oldHead` pointers.\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, 2, 3, 4, 5, 6]\n // newParts: [0, , , , , , 6] <- tails matched: update 6\n // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance both oldTail\n // & newTail\n // newHead ^ ^ newTail\n //\n // * If neither head nor tail match; next check if one of the\n // old head/tail items was removed. We first need to generate\n // the reverse map of new keys to index (`newKeyToIndexMap`),\n // which is done once lazily as a performance optimization,\n // since we only hit this case if multiple non-contiguous\n // changes were made. Note that for contiguous removal\n // anywhere in the list, the head and tails would advance\n // from either end and pass each other before we get to this\n // case and removals would be handled in the final while loop\n // without needing to generate the map.\n //\n // * Example below: The key at `oldTail` was removed (no longer\n // in the `newKeyToIndexMap`), so remove that part from the\n // DOM and advance just the `oldTail` pointer.\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, 2, 3, 4, 5, 6]\n // newParts: [0, , , , , , 6] <- 5 not in new map: remove\n // newKeys: [0, 2, 1, 4, 3, 7, 6] 5 and advance oldTail\n // newHead ^ ^ newTail\n //\n // * Once head and tail cannot move, any mismatches are due to\n // either new or moved items; if a new key is in the previous\n // \"old key to old index\" map, move the old part to the new\n // location, otherwise create and insert a new part. Note\n // that when moving an old part we null its position in the\n // oldParts array if it lies between the head and tail so we\n // know to skip it when the pointers get there.\n //\n // * Example below: neither head nor tail match, and neither\n // were removed; so find the `newHead` key in the\n // `oldKeyToIndexMap`, and move that old part's DOM into the\n // next head position (before `oldParts[oldHead]`). Last,\n // null the part in the `oldPart` array since it was\n // somewhere in the remaining oldParts still to be scanned\n // (between the head and tail pointers) so that we know to\n // skip that old part on future iterations.\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, -, 3, 4, 5, 6]\n // newParts: [0, 2, , , , , 6] <- stuck: update & move 2\n // newKeys: [0, 2, 1, 4, 3, 7, 6] into place and advance\n // newHead\n // newHead ^ ^ newTail\n //\n // * Note that for moves/insertions like the one above, a part\n // inserted at the head pointer is inserted before the\n // current `oldParts[oldHead]`, and a part inserted at the\n // tail pointer is inserted before `newParts[newTail+1]`. The\n // seeming asymmetry lies in the fact that new parts are\n // moved into place outside in, so to the right of the head\n // pointer are old parts, and to the right of the tail\n // pointer are new parts.\n //\n // * We always restart back from the top of the algorithm,\n // allowing matching and simple updates in place to\n // continue...\n //\n // * Example below: the head pointers once again match, so\n // simply update part 1 and record it in the `newParts`\n // array. Last, advance both head pointers.\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, -, 3, 4, 5, 6]\n // newParts: [0, 2, 1, , , , 6] <- heads matched: update 1\n // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance both oldHead\n // & newHead\n // newHead ^ ^ newTail\n //\n // * As mentioned above, items that were moved as a result of\n // being stuck (the final else clause in the code below) are\n // marked with null, so we always advance old pointers over\n // these so we're comparing the next actual old value on\n // either end.\n //\n // * Example below: `oldHead` is null (already placed in\n // newParts), so advance `oldHead`.\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, -, 3, 4, 5, 6] <- old head already used:\n // newParts: [0, 2, 1, , , , 6] advance oldHead\n // newKeys: [0, 2, 1, 4, 3, 7, 6]\n // newHead ^ ^ newTail\n //\n // * Note it's not critical to mark old parts as null when they\n // are moved from head to tail or tail to head, since they\n // will be outside the pointer range and never visited again.\n //\n // * Example below: Here the old tail key matches the new head\n // key, so the part at the `oldTail` position and move its\n // DOM to the new head position (before `oldParts[oldHead]`).\n // Last, advance `oldTail` and `newHead` pointers.\n //\n // oldHead v v oldTail\n // oldKeys: [0, 1, -, 3, 4, 5, 6]\n // newParts: [0, 2, 1, 4, , , 6] <- old tail matches new\n // newKeys: [0, 2, 1, 4, 3, 7, 6] head: update & move 4,\n // advance oldTail & newHead\n // newHead ^ ^ newTail\n //\n // * Example below: Old and new head keys match, so update the\n // old head part in place, and advance the `oldHead` and\n // `newHead` pointers.\n //\n // oldHead v oldTail\n // oldKeys: [0, 1, -, 3, 4, 5, 6]\n // newParts: [0, 2, 1, 4, 3, ,6] <- heads match: update 3\n // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance oldHead &\n // newHead\n // newHead ^ ^ newTail\n //\n // * Once the new or old pointers move past each other then all\n // we have left is additions (if old list exhausted) or\n // removals (if new list exhausted). Those are handled in the\n // final while loops at the end.\n //\n // * Example below: `oldHead` exceeded `oldTail`, so we're done\n // with the main loop. Create the remaining part and insert\n // it at the new head position, and the update is complete.\n //\n // (oldHead > oldTail)\n // oldKeys: [0, 1, -, 3, 4, 5, 6]\n // newParts: [0, 2, 1, 4, 3, 7 ,6] <- create and insert 7\n // newKeys: [0, 2, 1, 4, 3, 7, 6]\n // newHead ^ newTail\n //\n // * Note that the order of the if/else clauses is not\n // important to the algorithm, as long as the null checks\n // come first (to ensure we're always working on valid old\n // parts) and that the final else clause comes last (since\n // that's where the expensive moves occur). The order of\n // remaining clauses is just a simple guess at which cases\n // will be most common.\n //\n // * Note, we could calculate the longest\n // increasing subsequence (LIS) of old items in new position,\n // and only move those not in the LIS set. However that costs\n // O(nlogn) time and adds a bit more code, and only helps\n // make rare types of mutations require fewer moves. The\n // above handles removes, adds, reversal, swaps, and single\n // moves of contiguous items in linear time, in the minimum\n // number of moves. As the number of multiple moves where LIS\n // might help approaches a random shuffle, the LIS\n // optimization becomes less helpful, so it seems not worth\n // the code at this point. Could reconsider if a compelling\n // case arises.\n\n while (oldHead <= oldTail && newHead <= newTail) {\n if (oldParts[oldHead] === null) {\n // `null` means old part at head has already been used\n // below; skip\n oldHead++;\n } else if (oldParts[oldTail] === null) {\n // `null` means old part at tail has already been used\n // below; skip\n oldTail--;\n } else if (oldKeys[oldHead] === newKeys[newHead]) {\n // Old head matches new head; update in place\n newParts[newHead] = setChildPartValue(\n oldParts[oldHead]!,\n newValues[newHead]\n );\n oldHead++;\n newHead++;\n } else if (oldKeys[oldTail] === newKeys[newTail]) {\n // Old tail matches new tail; update in place\n newParts[newTail] = setChildPartValue(\n oldParts[oldTail]!,\n newValues[newTail]\n );\n oldTail--;\n newTail--;\n } else if (oldKeys[oldHead] === newKeys[newTail]) {\n // Old head matches new tail; update and move to new tail\n newParts[newTail] = setChildPartValue(\n oldParts[oldHead]!,\n newValues[newTail]\n );\n insertPart(containerPart, newParts[newTail + 1], oldParts[oldHead]!);\n oldHead++;\n newTail--;\n } else if (oldKeys[oldTail] === newKeys[newHead]) {\n // Old tail matches new head; update and move to new head\n newParts[newHead] = setChildPartValue(\n oldParts[oldTail]!,\n newValues[newHead]\n );\n insertPart(containerPart, oldParts[oldHead]!, oldParts[oldTail]!);\n oldTail--;\n newHead++;\n } else {\n if (newKeyToIndexMap === undefined) {\n // Lazily generate key-to-index maps, used for removals &\n // moves below\n newKeyToIndexMap = generateMap(newKeys, newHead, newTail);\n oldKeyToIndexMap = generateMap(oldKeys, oldHead, oldTail);\n }\n if (!newKeyToIndexMap.has(oldKeys[oldHead])) {\n // Old head is no longer in new list; remove\n removePart(oldParts[oldHead]!);\n oldHead++;\n } else if (!newKeyToIndexMap.has(oldKeys[oldTail])) {\n // Old tail is no longer in new list; remove\n removePart(oldParts[oldTail]!);\n oldTail--;\n } else {\n // Any mismatches at this point are due to additions or\n // moves; see if we have an old part we can reuse and move\n // into place\n const oldIndex = oldKeyToIndexMap.get(newKeys[newHead]);\n const oldPart = oldIndex !== undefined ? oldParts[oldIndex] : null;\n if (oldPart === null) {\n // No old part for this value; create a new one and\n // insert it\n const newPart = insertPart(containerPart, oldParts[oldHead]!);\n setChildPartValue(newPart, newValues[newHead]);\n newParts[newHead] = newPart;\n } else {\n // Reuse old part\n newParts[newHead] = setChildPartValue(oldPart, newValues[newHead]);\n insertPart(containerPart, oldParts[oldHead]!, oldPart);\n // This marks the old part as having been used, so that\n // it will be skipped in the first two checks above\n oldParts[oldIndex as number] = null;\n }\n newHead++;\n }\n }\n }\n // Add parts for any remaining new values\n while (newHead <= newTail) {\n // For all remaining additions, we insert before last new\n // tail, since old pointers are no longer valid\n const newPart = insertPart(containerPart, newParts[newTail + 1]);\n setChildPartValue(newPart, newValues[newHead]);\n newParts[newHead++] = newPart;\n }\n // Remove any remaining unused old parts\n while (oldHead <= oldTail) {\n const oldPart = oldParts[oldHead++];\n if (oldPart !== null) {\n removePart(oldPart);\n }\n }\n\n // Save order of new parts for next round\n this._itemKeys = newKeys;\n // Directly set part value, bypassing it's dirty-checking\n setCommittedValue(containerPart, newParts);\n return noChange;\n }\n}\n\nexport interface RepeatDirectiveFn {\n <T>(\n items: Iterable<T>,\n keyFnOrTemplate: KeyFn<T> | ItemTemplate<T>,\n template?: ItemTemplate<T>\n ): unknown;\n <T>(items: Iterable<T>, template: ItemTemplate<T>): unknown;\n <T>(\n items: Iterable<T>,\n keyFn: KeyFn<T> | ItemTemplate<T>,\n template: ItemTemplate<T>\n ): unknown;\n}\n\n/**\n * A directive that repeats a series of values (usually `TemplateResults`)\n * generated from an iterable, and updates those items efficiently when the\n * iterable changes based on user-provided `keys` associated with each item.\n *\n * Note that if a `keyFn` is provided, strict key-to-DOM mapping is maintained,\n * meaning previous DOM for a given key is moved into the new position if\n * needed, and DOM will never be reused with values for different keys (new DOM\n * will always be created for new keys). This is generally the most efficient\n * way to use `repeat` since it performs minimum unnecessary work for insertions\n * and removals.\n *\n * The `keyFn` takes two parameters, the item and its index, and returns a unique key value.\n *\n * ```js\n * html`\n * <ol>\n * ${repeat(this.items, (item) => item.id, (item, index) => {\n * return html`<li>${index}: ${item.name}</li>`;\n * })}\n * </ol>\n * `\n * ```\n *\n * **Important**: If providing a `keyFn`, keys *must* be unique for all items in a\n * given call to `repeat`. The behavior when two or more items have the same key\n * is undefined.\n *\n * If no `keyFn` is provided, this directive will perform similar to mapping\n * items to values, and DOM will be reused against potentially different items.\n */\nexport const repeat = directive(RepeatDirective) as RepeatDirectiveFn;\n\n/**\n * The type of the class that powers this directive. Necessary for naming the\n * directive's return type.\n */\nexport type {RepeatDirective};\n","export function positionShapes(shape: string, coordsNumber: number[], img: HTMLImageElement, hotspot: HTMLElement) {\n // Determine the reference width and height based on the attributes or natural dimensions\n const imgWidth = img.getAttribute('width') ? parseFloat(img.getAttribute('width')!) : img.naturalWidth;\n const imgHeight = img.getAttribute('height') ? parseFloat(img.getAttribute('height')!) : img.naturalHeight;\n\n switch (shape) {\n case 'circle':\n {\n if (coordsNumber.length !== 3) {\n console.error('Invalid circle coordinates:', coordsNumber);\n return;\n }\n const [centerX, centerY, radius] = coordsNumber;\n\n // Calculate percentages for center and radius\n const centerXPer = (centerX / imgWidth) * 100;\n const centerYPer = (centerY / imgHeight) * 100;\n const radiusXPer = (radius / imgWidth) * 100; // Relative to width\n const radiusYPer = (radius / imgHeight) * 100; // Relative to height\n\n // Position the hotspot so its center aligns with the circle center\n hotspot.style.left = centerXPer - radiusXPer + '%';\n hotspot.style.top = centerYPer - radiusYPer + '%';\n hotspot.style.width = 2 * radiusXPer + '%';\n hotspot.style.height = 2 * radiusYPer + '%';\n hotspot.style.borderRadius = `50%`; // Create a circular shape\n }\n break;\n\n case 'rect':\n {\n if (coordsNumber.length !== 4) {\n console.error('Invalid rectangle coordinates:', coordsNumber);\n return;\n }\n const [leftX, topY, rightX, bottomY] = coordsNumber;\n const leftXPer = (leftX / imgWidth) * 100;\n const topYPer = (topY / imgHeight) * 100;\n const rightXPer = (rightX / imgWidth) * 100;\n const bottomYPer = (bottomY / imgHeight) * 100;\n hotspot.style.left = leftXPer + '%';\n hotspot.style.top = topYPer + '%';\n hotspot.style.width = rightXPer - leftXPer + '%';\n hotspot.style.height = bottomYPer - topYPer + '%';\n }\n break;\n case 'ellipse':\n {\n if (coordsNumber.length !== 4) {\n console.error('Invalid ellipse coordinates:', coordsNumber);\n return;\n }\n const [centerX, centerY, radiusX, radiusY] = coordsNumber;\n\n // Calculate center position as percentages\n const centerXPer = (centerX / imgWidth) * 100;\n const centerYPer = (centerY / imgHeight) * 100;\n\n // Calculate radii as percentages (relative to their respective dimensions)\n const radiusXPer = (radiusX / imgWidth) * 100;\n const radiusYPer = (radiusY / imgHeight) * 100;\n\n // Position the hotspot so its center aligns with the ellipse center\n hotspot.style.left = centerXPer - radiusXPer + '%';\n hotspot.style.top = centerYPer - radiusYPer + '%';\n hotspot.style.width = 2 * radiusXPer + '%';\n hotspot.style.height = 2 * radiusYPer + '%';\n hotspot.style.borderRadius = `50%`; // Create an elliptical shape\n }\n break;\n case 'poly':\n {\n if (coordsNumber.length < 6 || coordsNumber.length % 2 !== 0) {\n console.error('Invalid polygon coordinates:', coordsNumber);\n return;\n }\n // Convert coordsNumber to an array of {x, y}\n const polycoords = [];\n for (let i = 0; i < coordsNumber.length; i += 2) {\n polycoords.push({ x: coordsNumber[i], y: coordsNumber[i + 1] });\n }\n\n // Calculate the bounding box\n const leftX = Math.min(...polycoords.map(point => point.x));\n const rightX = Math.max(...polycoords.map(point => point.x));\n const topY = Math.min(...polycoords.map(point => point.y));\n const bottomY = Math.max(...polycoords.map(point => point.y));\n\n // Set the hotspot position and size in percentages\n const leftXPer = (leftX / imgWidth) * 100;\n const topYPer = (topY / imgHeight) * 100;\n const rightXPer = (rightX / imgWidth) * 100;\n const bottomYPer = (bottomY / imgHeight) * 100;\n\n hotspot.style.left = leftXPer + '%';\n hotspot.style.top = topYPer + '%';\n hotspot.style.width = rightXPer - leftXPer + '%';\n hotspot.style.height = bottomYPer - topYPer + '%';\n\n // Calculate the clip path based on the bounding box\n const polygonData = polycoords.map(point => ({\n x: ((point.x - leftX) / (rightX - leftX)) * 100,\n y: ((point.y - topY) / (bottomY - topY)) * 100\n }));\n\n const polyD = polygonData.map(p => `${p.x}% ${p.y}%`).join(',');\n hotspot.style.clipPath = `polygon(${polyD})`;\n }\n break;\n\n default:\n console.error(`Unsupported shape: ${shape}`);\n break;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n slot:not([name='prompt']) {\n // position: relative; /* qti-hotspot-choice relative to the slot */\n display: block;\n width: fit-content; /* hotspots not stretching further if image is at max size */\n }\n ::slotted(img) {\n /* image not selectable anymore */\n pointer-events: none;\n user-select: none;\n }\n ::slotted(qti-associable-hotspot) {\n transform: translate(-50%, -50%);\n }\n line-container {\n display: block;\n position: relative;\n width: fit-content;\n }\n svg {\n position: absolute;\n top: 0px;\n left: 0px;\n }\n`;\n","import { html, svg } from 'lit';\nimport { queryAssignedElements, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { repeat } from 'lit/directives/repeat.js';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { positionShapes } from '../../internal/hotspots/hotspot';\nimport styles from './qti-graphic-associate-interaction.styles';\n\nimport type { QtiAssociableHotspot } from '../../elements/qti-associable-hotspot';\nimport type { QtiHotspotChoice } from '../../elements/qti-hotspot-choice';\nimport type { CSSResultGroup } from 'lit';\nexport class QtiGraphicAssociateInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\n\n private hotspots: any[] | NodeListOf<QtiAssociableHotspot>;\n private startPoint: HTMLElement | null = null;\n private endPoint: HTMLElement | null = null;\n\n @state() private _correctLines: string[] = [];\n @state() private startCoord: { x: number; y: number };\n @state() private mouseCoord: { x: number; y: number };\n @queryAssignedElements({ selector: 'img' }) private grImage: any[];\n\n @state()\n private _response: string[] | null = [];\n\n constructor() {\n super();\n this.addEventListener('qti-register-hotspot', this.positionHotspotOnRegister);\n }\n\n override reset(): void {\n this._response = [];\n this._correctLines = [];\n }\n\n validate(): boolean {\n return this.getResponseArray().length > 0;\n }\n\n set response(val) {\n this._response = this.normalizeResponse(val);\n }\n\n get response() {\n return this._response;\n }\n\n private normalizeResponse(value: string | string[] | null | undefined): string[] {\n if (value === null || value === undefined || value === '') return [];\n return Array.isArray(value) ? value : [value];\n }\n\n private getResponseArray(): string[] {\n return this.normalizeResponse(this._response);\n }\n\n public override toggleInternalCorrectResponse(show: boolean) {\n const responseVariable = this.responseVariable;\n if (!show || !responseVariable) {\n this._correctLines = [];\n return;\n }\n if (!responseVariable.correctResponse) {\n console.error('No correct response found for this interaction.');\n return;\n }\n const correctResponses = Array.isArray(responseVariable.correctResponse)\n ? responseVariable.correctResponse\n : [responseVariable.correctResponse];\n this._correctLines = correctResponses;\n }\n\n override render() {\n return html`<slot name=\"prompt\"></slot>\n <line-container>\n <svg\n width=${ifDefined(this.grImage[0]?.width)}\n height=${ifDefined(this.grImage[0]?.height)}\n viewbox=\"0 0 ${this.grImage[0]?.width} ${this.grImage[0]?.height}\"\n >\n ${repeat(\n this.getResponseArray(),\n line => line,\n (line, index) => svg`\n <line\n part=\"line\"\n x1=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[0]}]`).style.left)}\n y1=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[0]}]`).style.top)}\n x2=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[1]}]`).style.left)}\n y2=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[1]}]`).style.top)}\n stroke=\"red\"\n stroke-width=\"3\"\n @click=${(e: Event) => {\n e.stopPropagation();\n this._response = this._response.filter((_, i) => i !== index);\n this.saveResponse(this.response);\n }}\n />\n `\n )}\n ${repeat(\n this._correctLines || [],\n line => line,\n (line, _index) => svg`\n <line\n part=\"correct-line\"\n x1=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[0]}]`).style.left)}\n y1=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[0]}]`).style.top)}\n x2=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[1]}]`).style.left)}\n y2=${parseInt(this.querySelector<SVGLineElement>(`[identifier=${line.split(' ')[1]}]`).style.top)}\n stroke=\"var(--qti-correct)\"\n stroke-width=\"3\"\n stroke-dasharray=\"5,5\"\n />\n `\n )}\n ${this.startPoint &&\n svg`<line\n part=\"point\"\n x1=${this.startCoord.x}\n y1=${this.startCoord.y}\n x2=${this.mouseCoord.x}\n y2=${this.mouseCoord.y}\n stroke=\"var(--qti-border-active)\"\n stroke-width=\"3\"\n />`}\n </svg>\n <slot></slot>\n </line-container>\n <div role=\"alert\" part=\"message\" id=\"validation-message\"></div>`;\n }\n\n private positionHotspotOnRegister(e: CustomEvent<QtiHotspotChoice>): void {\n const img = this.querySelector('img') as HTMLImageElement;\n const hotspot = e.target as QtiHotspotChoice;\n const coords = hotspot.getAttribute('coords');\n const shape = hotspot.getAttribute('shape');\n const coordsNumber = coords.split(',').map(s => parseInt(s));\n positionShapes(shape, coordsNumber, img, hotspot);\n }\n\n override firstUpdated(): void {\n this.hotspots = this.querySelectorAll('qti-associable-hotspot');\n\n this.addEventListener('mousemove', event => {\n const img = this.grImage[0];\n if (!img) return;\n\n const rect = img.getBoundingClientRect();\n // const scaleX = img.naturalWidth / img.clientWidth;\n // const scaleY = img.naturalHeight / img.clientHeight;\n\n // console.log(`scaleX: ${scaleX}, scaleY: ${scaleY}`);\n\n this.mouseCoord = {\n x: event.clientX - rect.left, // * scaleX,\n y: event.clientY - rect.top // * scaleY\n };\n });\n\n this.hotspots.forEach(hotspot => {\n // const img = this.grImage[0];\n // const scaleX = img.naturalWidth / img.clientWidth;\n // const scaleY = img.naturalHeight / img.clientHeight;\n\n hotspot.style.left = hotspot.getAttribute('coords').split(',')[0] + 'px';\n hotspot.style.top = hotspot.getAttribute('coords').split(',')[1] + 'px';\n\n hotspot.addEventListener('click', event => {\n if (!this.startPoint) {\n this.startPoint = event.target as HTMLElement;\n\n this.startCoord = {\n x: parseInt(this.startPoint.getAttribute('coords').split(',')[0]),\n y: parseInt(this.startPoint.getAttribute('coords').split(',')[1])\n };\n } else if (!this.endPoint) {\n this.endPoint = event.target as HTMLElement;\n\n this._response = this.getResponseArray();\n this._response = [\n ...this._response,\n `${this.startPoint.getAttribute('identifier')} ${this.endPoint.getAttribute('identifier')}`\n ];\n this.saveResponse(this.response);\n this.startPoint = null;\n this.endPoint = null;\n }\n });\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('qti-register-hotspot', this.positionHotspotOnRegister);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-graphic-associate-interaction': QtiGraphicAssociateInteraction;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: flex;\n align-items: flex-start;\n flex-direction: column;\n flex-wrap: wrap;\n gap: 0.5rem;\n }\n\n :host(.qti-choices-top) {\n flex-direction: column-reverse;\n }\n :host(.qti-choices-bottom) {\n flex-direction: column;\n }\n :host(.qti-choices-left) {\n flex-direction: row-reverse;\n & [name='drags'] {\n width: 25%;\n }\n & [part='image'] {\n width: 75%;\n }\n }\n :host(.qti-choices-right) {\n flex-direction: row;\n & [name='drags'] {\n width: 25%;\n }\n & [part='image'] {\n width: 75%;\n }\n }\n [part='image'] {\n display: block;\n position: relative;\n }\n /* [part='drops'] , */\n\n [name='drags'] {\n display: flex;\n align-items: flex-start;\n flex-wrap: wrap;\n flex: 1;\n border: 2px solid transparent;\n padding: 0.3rem;\n border-radius: 0.3rem;\n gap: 0.5rem;\n }\n ::slotted(img) {\n display: inline-block;\n user-select: none;\n pointer-events: none;\n }\n`;\n","import { html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { DragDropInteractionMixin } from '../../mixins/drag-drop';\nimport styles from './qti-graphic-gap-match-interaction.styles';\n\nimport type { QtiHotspotChoice } from '../../elements/qti-hotspot-choice';\nimport type { CSSResultGroup } from 'lit';\nexport class QtiGraphicGapMatchInteraction extends DragDropInteractionMixin(\n Interaction,\n 'qti-gap-img, qti-gap-text',\n 'qti-associable-hotspot',\n `slot[part='drags']`\n) {\n static override styles: CSSResultGroup = styles;\n\n override render() {\n return html` <slot name=\"prompt\"></slot>\n <slot part=\"image\"></slot>\n <slot part=\"drags\" name=\"drags\" class=\"hover-border\"></slot>\n <div role=\"alert\" part=\"message\" id=\"validation-message\"></div>`;\n }\n\n private positionHotspotOnRegister(e: CustomEvent<null>): void {\n const hotspot = e.target as QtiHotspotChoice;\n const coords = hotspot.getAttribute('coords');\n const shape = hotspot.getAttribute('shape');\n const coordsNumber = coords.split(',').map(s => parseInt(s));\n\n // positionHotspots(shape, coordsNumber, img, hotspot);\n switch (shape) {\n case 'circle':\n {\n const [centerX, centerY, radius] = coordsNumber;\n hotspot.style.left = centerX - radius + 'px';\n hotspot.style.top = centerY - radius + 'px';\n hotspot.style.width = hotspot.style.height = 2 * radius + 'px';\n }\n break;\n\n case 'rect':\n {\n const [leftX, topY, rightX, bottomY] = coordsNumber;\n hotspot.style.left = leftX + 'px';\n hotspot.style.top = topY + 'px';\n hotspot.style.width = rightX - leftX + 'px';\n hotspot.style.height = bottomY - topY + 'px';\n }\n break;\n\n default:\n break;\n }\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('qti-register-hotspot', this.positionHotspotOnRegister);\n }\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('qti-register-hotspot', this.positionHotspotOnRegister);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-graphic-gap-match-interaction': QtiGraphicGapMatchInteraction;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n slot:not([name='prompt']) {\n position: relative; /* qti-hotspot-choice relative to the slot */\n display: block;\n width: fit-content; /* hotspots not stretching further if image is at max size */\n }\n ::slotted(img) {\n /* image not selectable anymore */\n pointer-events: none;\n user-select: none;\n }\n`;\n","import { html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { ChoicesMixin } from '../../mixins/choices/choices.mixin';\nimport { positionShapes } from '../../internal/hotspots/hotspot';\nimport styles from './qti-graphic-order-interaction.styles';\n\nimport type { QtiHotspotChoice } from '../../elements/qti-hotspot-choice';\nimport type { Choice } from '../../mixins/choices/choices.mixin';\nimport type { CSSResultGroup } from 'lit';\n\ntype HotspotChoice = Choice & { order: number; orderCorrect?: number };\nexport class QtiGraphicOrderInteraction extends ChoicesMixin(Interaction, 'qti-hotspot-choice') {\n static override styles: CSSResultGroup = styles;\n\n protected choiceOrdering: boolean;\n\n protected _choiceElements: Choice[] = [];\n\n override render() {\n return html`\n <slot name=\"prompt\"></slot>\n <slot></slot>\n <div role=\"alert\" part=\"message\" id=\"validation-message\"></div>\n `;\n }\n\n private setHotspotOrder(e: CustomEvent<{ identifier: string }>): void {\n const { identifier } = e.detail;\n\n const hotspot = this._choiceElements.find(el => el.getAttribute('identifier') === identifier) as HotspotChoice;\n\n if (!hotspot) return;\n\n const maxSelection = this._choiceElements.length;\n\n if (!this.choiceOrdering) {\n this.choiceOrdering = true;\n\n if (hotspot.order == null) {\n // Hotspot is not selected, so assign the next available order\n const currentSelection = (this._choiceElements as HotspotChoice[]).filter(i => i.order != null).length;\n\n if (currentSelection >= maxSelection) {\n this.choiceOrdering = false;\n return; // Maximum selection reached\n }\n\n hotspot.order = currentSelection + 1;\n } else {\n // Hotspot is already selected, so remove its order and renumber the rest\n const removedOrder = hotspot.order;\n\n hotspot.order = null;\n\n (this._choiceElements as HotspotChoice[]).forEach(hotspot => {\n if (hotspot.order != null && hotspot.order > removedOrder) {\n hotspot.order--;\n }\n });\n }\n\n this.choiceOrdering = false;\n }\n }\n\n public override toggleCorrectResponse(show: boolean) {\n const responseVariable = this.responseVariable;\n const hotspots = this._choiceElements as HotspotChoice[];\n for (const hotspot of hotspots) {\n if (show && responseVariable?.correctResponse?.length > 0 && Array.isArray(responseVariable.correctResponse)) {\n const index = responseVariable.correctResponse.findIndex(identifier => identifier === hotspot.identifier);\n if (index >= 0) {\n hotspot.orderCorrect = index + 1;\n } else {\n hotspot.orderCorrect = null;\n }\n } else {\n hotspot.orderCorrect = null;\n }\n }\n }\n\n private positionHotspotOnRegister(e: CustomEvent<QtiHotspotChoice>): void {\n const img = this.querySelector('img') as HTMLImageElement;\n const hotspot = e.target as QtiHotspotChoice;\n const coords = hotspot.getAttribute('coords');\n const shape = hotspot.getAttribute('shape');\n const coordsNumber = coords.split(',').map(s => parseInt(s));\n\n positionShapes(shape, coordsNumber, img, hotspot);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('activate-qti-hotspot-choice', this.setHotspotOrder);\n this.addEventListener('register-qti-hotspot-choice', this.positionHotspotOnRegister);\n }\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('activate-qti-hotspot-choice', this.setHotspotOrder);\n this.removeEventListener('register-qti-hotspot-choice', this.positionHotspotOnRegister);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-graphic-order-interaction': QtiGraphicOrderInteraction;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n slot:not([name='prompt']) {\n position: relative; /* qti-hotspot-choice relative to the slot */\n display: inline-block;\n width: fit-content; /* hotspots not stretching further if image is at max size */\n line-height: 0; /* remove gaps below image */\n }\n ::slotted(img) {\n /* image not selectable anymore */\n display: block;\n pointer-events: none;\n user-select: none;\n /* width:100%; */\n }\n`;\n","import { html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { ChoicesMixin } from '../../mixins/choices/choices.mixin';\nimport { positionShapes } from '../../internal/hotspots/hotspot';\nimport styles from './qti-hotspot-interaction.styles';\n\nimport type { QtiHotspotChoice } from '../../elements/qti-hotspot-choice';\nimport type { CSSResultGroup } from 'lit';\nexport class QtiHotspotInteraction extends ChoicesMixin(Interaction, 'qti-hotspot-choice') {\n static override styles: CSSResultGroup = styles;\n\n override render() {\n return html`\n <slot name=\"prompt\"></slot>\n <slot></slot>\n `;\n }\n\n private imageLoadPromise: Promise<HTMLImageElement> | null = null;\n\n private getImageLoadPromise(img: HTMLImageElement): Promise<HTMLImageElement> {\n if (!this.imageLoadPromise) {\n if (img.naturalWidth > 0 && img.naturalHeight > 0) {\n this.imageLoadPromise = Promise.resolve(img);\n } else {\n this.imageLoadPromise = new Promise(resolve => {\n const handler = () => {\n img.removeEventListener('load', handler);\n resolve(img);\n };\n img.addEventListener('load', handler);\n });\n }\n }\n return this.imageLoadPromise;\n }\n\n private async positionHotspotOnRegister(e: CustomEvent<QtiHotspotChoice>): Promise<void> {\n const img = this.querySelector('img') as HTMLImageElement;\n const hotspot = e.target as QtiHotspotChoice;\n const coords = hotspot.getAttribute('coords');\n const shape = hotspot.getAttribute('shape');\n const coordsNumber = coords.split(',').map(s => parseInt(s));\n const loadedImg = await this.getImageLoadPromise(img);\n positionShapes(shape, coordsNumber, loadedImg, hotspot);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('register-qti-hotspot-choice', this.positionHotspotOnRegister);\n }\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('unregister-qti-hotspot-choice', this.positionHotspotOnRegister);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-hotspot-interaction': QtiHotspotInteraction;\n }\n}\n","import { html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { ChoicesMixin } from '../../mixins/choices/choices.mixin';\n\nimport type { PropertyValues } from 'lit';\nexport class QtiHottextInteraction extends ChoicesMixin(Interaction, 'qti-hottext') {\n @property({ type: String, reflect: true })\n class = '';\n\n // NOTE: there is no way to get the variant with radiobuttons or checkboxes\n // as the QTI standard does not define a way to specify this.\n // The default is to not show any radio or checkbox buttons just like amp-up does.\n // If they should be shown in the future, we should make a configuration option for it.\n private get classObject() {\n const classes: { [key: string]: boolean } = {\n 'qti-input-control-hidden': true\n };\n\n if (this.class) {\n this.class.split(' ').forEach(className => {\n if (className.trim()) {\n classes[className.trim()] = true;\n }\n });\n }\n\n return classes;\n }\n\n override render = () =>\n html`<slot></slot>\n <div part=\"message\" role=\"alert\" id=\"validation-message\"></div>`;\n\n override connectedCallback() {\n super.connectedCallback();\n this.updateHostClasses();\n }\n\n override updated(_changedProperties: PropertyValues) {\n super.updated(_changedProperties);\n this.updateHostClasses();\n }\n\n private updateHostClasses() {\n // Clear existing classes and apply merged ones\n const classString = Object.keys(this.classObject).join(' ');\n \n this.className = classString;\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {nothing, TemplateResult, noChange} from '../lit-html.js';\nimport {directive, Directive, PartInfo, PartType} from '../directive.js';\n\nconst HTML_RESULT = 1;\n\nexport class UnsafeHTMLDirective extends Directive {\n static directiveName = 'unsafeHTML';\n static resultType = HTML_RESULT;\n\n private _value: unknown = nothing;\n private _templateResult?: TemplateResult;\n\n constructor(partInfo: PartInfo) {\n super(partInfo);\n if (partInfo.type !== PartType.CHILD) {\n throw new Error(\n `${\n (this.constructor as typeof UnsafeHTMLDirective).directiveName\n }() can only be used in child bindings`\n );\n }\n }\n\n render(value: string | typeof nothing | typeof noChange | undefined | null) {\n if (value === nothing || value == null) {\n this._templateResult = undefined;\n return (this._value = value);\n }\n if (value === noChange) {\n return value;\n }\n if (typeof value != 'string') {\n throw new Error(\n `${\n (this.constructor as typeof UnsafeHTMLDirective).directiveName\n }() called with a non-string value`\n );\n }\n if (value === this._value) {\n return this._templateResult;\n }\n this._value = value;\n const strings = [value] as unknown as TemplateStringsArray;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (strings as any).raw = strings;\n // WARNING: impersonating a TemplateResult like this is extremely\n // dangerous. Third-party directives should not do this.\n return (this._templateResult = {\n // Cast to a known set of integers that satisfy ResultType so that we\n // don't have to export ResultType and possibly encourage this pattern.\n // This property needs to remain unminified.\n ['_$litType$']: (this.constructor as typeof UnsafeHTMLDirective)\n .resultType as 1 | 2,\n strings,\n values: [],\n });\n }\n}\n\n/**\n * Renders the result as HTML, rather than text.\n *\n * The values `undefined`, `null`, and `nothing`, will all result in no content\n * (empty string) being rendered.\n *\n * Note, this is unsafe to use with any user-provided input that hasn't been\n * sanitized or escaped, as it may lead to cross-site-scripting\n * vulnerabilities.\n */\nexport const unsafeHTML = directive(UnsafeHTMLDirective);\n","import { css, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { consume } from '@lit/context';\n\nimport { Interaction } from '@qti-components/base';\nimport { configContext } from '@qti-components/base';\n\nimport type { PropertyValues } from 'lit';\nimport type { ConfigContext } from '@qti-components/base';\n\ninterface OptionType {\n textContent: string;\n value: string;\n selected: boolean;\n}\nexport class QtiInlineChoiceInteraction extends Interaction {\n override get isInline(): boolean {\n return true;\n }\n\n private static _supportsCustomizableSelectCache: boolean | null = null;\n\n static override get styles() {\n return [\n css`\n :host {\n display: inline-block;\n vertical-align: baseline;\n position: relative;\n }\n\n /* --- Progressive enhancement: Customizable select (MDN / WHATWG) --- */\n select[part='select'] {\n font: inherit;\n color: inherit;\n background-color: var(--qti-bg, white);\n border: var(--qti-border-thickness, 2px) var(--qti-border-style, solid) var(--qti-border-color, #c6cad0);\n border-radius: var(--qti-border-radius, 0.3rem);\n padding: 0.25rem 0.75rem;\n /* Enables full styling when supported (Chromium behind a flag / rolling out). */\n appearance: base-select;\n }\n\n select[part='select']:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n select[part='select']::picker(select) {\n border: var(--qti-border-thickness, 2px) var(--qti-border-style, solid) var(--qti-border-color, #c6cad0);\n border-radius: var(--qti-border-radius, 0.3rem);\n background: var(--qti-bg, white);\n box-shadow:\n 0 10px 15px -3px rgb(0 0 0 / 10%),\n 0 4px 6px -4px rgb(0 0 0 / 10%);\n padding: 4px;\n width: max-content;\n min-width: 100%;\n max-width: min(90vw, 36rem);\n }\n\n select[part='select']::picker-icon {\n color: var(--qti-border-color, #c6cad0);\n transition: 0.4s rotate;\n font-size: 1.75em;\n }\n\n select[part='select']:open::picker-icon {\n color: var(--qti-border-active, #f86d70);\n rotate: 180deg;\n }\n\n select[part='select'] > button {\n font: inherit;\n color: inherit;\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0;\n background: transparent;\n border: 0;\n cursor: pointer;\n }\n\n select[part='select'] selectedcontent {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n white-space: nowrap;\n }\n\n option {\n font: inherit;\n color: inherit;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.5rem;\n white-space: nowrap;\n }\n\n option:hover {\n background-color: var(--qti-hover-bg, #f9fafb);\n }\n\n option:checked {\n background-color: var(--qti-bg-active, #ffecec);\n }\n\n option::checkmark {\n color: var(--qti-border-active, #f86d70);\n }\n\n /* --- Fallback custom listbox (for browsers without customizable select) --- */\n button[part='trigger'] {\n font: inherit;\n color: inherit;\n background-color: var(--qti-bg, white);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n justify-content: space-between;\n border: var(--qti-border-thickness, 2px) var(--qti-border-style, solid) var(--qti-border-color, #c6cad0);\n border-radius: var(--qti-border-radius, 0.3rem);\n padding: 0.25rem 0.75rem;\n }\n\n [part='value'] {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n min-width: 0;\n }\n\n [part='dropdown-icon'] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n transition: transform 150ms ease;\n transform-origin: 50% 50%;\n color: var(--qti-border-color, #c6cad0);\n font-size: 1.75em;\n line-height: 1;\n }\n\n button[part='trigger'][aria-expanded='true'] [part='dropdown-icon'] {\n transform: rotate(180deg);\n color: var(--qti-border-active, #f86d70);\n }\n\n button[part='trigger'][disabled] {\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n [part='menu'] {\n position: absolute;\n z-index: 1000;\n top: calc(100% + 4px);\n left: 0;\n min-width: 100%;\n max-width: min(90vw, 36rem);\n max-height: min(40vh, 20rem);\n overflow: auto;\n background-color: var(--qti-bg, white);\n border: var(--qti-border-thickness, 2px) var(--qti-border-style, solid) var(--qti-border-color, #c6cad0);\n border-radius: var(--qti-border-radius, 0.3rem);\n box-shadow:\n 0 10px 15px -3px rgb(0 0 0 / 10%),\n 0 4px 6px -4px rgb(0 0 0 / 10%);\n padding: 4px;\n transform: translate(\n var(--qti-menu-shift-x, 0px),\n var(--qti-menu-shift-y, 0px)\n );\n }\n\n [part='menu'][data-placement='top'] {\n top: auto;\n bottom: calc(100% + 4px);\n }\n\n button[part='option'] {\n font: inherit;\n color: inherit;\n background-color: transparent;\n border: 0;\n padding: 0.5rem 0.5rem;\n width: 100%;\n text-align: left;\n border-radius: calc(var(--qti-border-radius, 0.3rem) - 2px);\n cursor: pointer;\n white-space: nowrap;\n }\n\n button[part='option'][aria-selected='true'] {\n background-color: var(--qti-bg-active, #ffecec);\n }\n\n button[part='option']:hover {\n background-color: var(--qti-hover-bg, #f9fafb);\n }\n\n button[part='option']:focus-visible {\n outline: 2px solid var(--qti-border-active, #f86d70);\n outline-offset: 2px;\n }\n\n [part='option-content'] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-wrap: nowrap;\n white-space: nowrap;\n }\n\n select[part='select'] img,\n button[part='option'] img,\n button[part='trigger'] img,\n [part='menu'] img {\n display: inline-block;\n max-height: 1em;\n max-width: 1.5em;\n vertical-align: middle;\n }\n `\n ];\n }\n\n public static inputWidthClass = [\n '',\n 'qti-input-width-2',\n 'qti-input-width-1',\n 'qti-input-width-3',\n 'qti-input-width-4',\n 'qti-input-width-6',\n 'qti-input-width-10',\n 'qti-input-width-15',\n 'qti-input-width-20',\n 'qti-input-width-72'\n ];\n\n @state()\n protected options: OptionType[] = [];\n\n @state()\n protected correctOption: string = '';\n\n @state()\n private _dropdownOpen = false;\n\n @property({ attribute: 'data-prompt', type: String })\n dataPrompt: string = '';\n\n @consume({ context: configContext, subscribe: true })\n @property({ attribute: false })\n declare configContext: ConfigContext;\n\n override render() {\n const selected = this._selectedOption();\n const useCustomizableSelect = this._supportsCustomizableSelect();\n\n return html`\n ${useCustomizableSelect\n ? html`\n <select\n part=\"select\"\n @change=${this._onNativeChange}\n ?disabled=\"${this.disabled || this.readonly}\"\n .value=\"${selected?.value ?? ''}\"\n >\n <button type=\"button\">\n <selectedcontent></selectedcontent>\n </button>\n ${this.options.map(\n option => html`<option value=\"${option.value}\">${unsafeHTML(option.textContent)}</option>`\n )}\n </select>\n `\n : html`\n <button\n part=\"trigger\"\n type=\"button\"\n @click=${this._onToggleCustomDropdown}\n @keydown=${this._onCustomTriggerKeyDown}\n aria-haspopup=\"listbox\"\n aria-expanded=\"${this._dropdownOpen ? 'true' : 'false'}\"\n ?disabled=\"${this.disabled}\"\n data-readonly=\"${this.readonly ? 'true' : 'false'}\"\n >\n <span part=\"value\">${unsafeHTML(selected?.textContent ?? '')}</span>\n <span part=\"dropdown-icon\" aria-hidden=\"true\">▾</span>\n </button>\n ${this._dropdownOpen\n ? html`\n <div part=\"menu\" role=\"listbox\" @keydown=${this._onCustomMenuKeyDown}>\n ${this.options.map(\n option => html`\n <button\n part=\"option\"\n type=\"button\"\n role=\"option\"\n aria-selected=\"${option.selected ? 'true' : 'false'}\"\n @click=\"${() => this._selectValue(option.value)}\"\n >\n <span part=\"option-content\">${unsafeHTML(option.textContent)}</span>\n </button>\n `\n )}\n </div>\n `\n : null}\n `}\n ${unsafeHTML(this.correctOption)}\n `;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n this._updateOptions();\n if (!this._supportsCustomizableSelect()) {\n document.addEventListener('pointerdown', this._onDocumentPointerDown, true);\n document.addEventListener('keydown', this._onDocumentKeyDown, true);\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (!this._supportsCustomizableSelect()) {\n document.removeEventListener('pointerdown', this._onDocumentPointerDown, true);\n document.removeEventListener('keydown', this._onDocumentKeyDown, true);\n }\n }\n\n override willUpdate(changed: PropertyValues<this>) {\n if (changed.has('configContext') || changed.has('dataPrompt')) {\n this._updateOptions();\n }\n }\n\n private _selectedOption(): OptionType | undefined {\n return this.options.find(option => option.selected) ?? this.options[0];\n }\n\n /**\n * Progressive enhancement for \"customizable select\" (WHATWG / MDN: `appearance: base-select` + `::picker()`).\n *\n * Notes on current browser behavior (observed around Feb 2026):\n * - Chromium-based browsers can support customizable select in light DOM, but it does not reliably work when the\n * `<select>` lives inside a shadow root (e.g. the internal `<button>/<selectedcontent>` can end up effectively\n * not rendered, so rich content like images disappears).\n * - Firefox support is not generally available yet, so we fall back to our custom listbox there as well.\n *\n * Because `CSS.supports(...)` may return syntax-only true, we do a final DOM probe to ensure the customizable-select\n * markup actually takes effect in the current environment before opting in.\n */\n private _supportsCustomizableSelect(): boolean {\n if (QtiInlineChoiceInteraction._supportsCustomizableSelectCache !== null) {\n return QtiInlineChoiceInteraction._supportsCustomizableSelectCache;\n }\n\n if (typeof CSS === 'undefined' || typeof CSS.supports !== 'function') {\n QtiInlineChoiceInteraction._supportsCustomizableSelectCache = false;\n return false;\n }\n\n // CSS.supports can be a false-positive (syntax-only). We only enable the customizable-select\n // markup if we can verify that `appearance: base-select` actually affects computed styles.\n const supportsPickerSelector =\n CSS.supports('selector(::picker(select))') || CSS.supports('selector(select::picker(select))');\n const supportsAppearanceValue =\n CSS.supports('appearance: base-select') || CSS.supports('-webkit-appearance: base-select');\n if (!supportsPickerSelector || !supportsAppearanceValue) {\n QtiInlineChoiceInteraction._supportsCustomizableSelectCache = false;\n return false;\n }\n\n try {\n // Final check: verify that the customizable select markup actually takes effect.\n // In some browsers `CSS.supports(...)` returns true, but the internal <button> is not\n // rendered (0x0 rect), meaning we effectively get a native select with broken rich content.\n const container = document.createElement('div');\n container.style.position = 'absolute';\n container.style.top = '-9999px';\n container.style.left = '-9999px';\n\n const select = document.createElement('select');\n select.style.appearance = 'base-select';\n select.style.webkitAppearance = 'base-select';\n\n const button = document.createElement('button');\n button.type = 'button';\n const selected = document.createElement('selectedcontent');\n selected.textContent = 'probe';\n button.appendChild(selected);\n\n const option = document.createElement('option');\n option.value = 'probe';\n option.textContent = 'probe';\n\n select.appendChild(button);\n select.appendChild(option);\n container.appendChild(select);\n (document.body || document.documentElement).appendChild(container);\n\n const rect = button.getBoundingClientRect();\n container.remove();\n\n const supported = rect.width > 0 && rect.height > 0;\n QtiInlineChoiceInteraction._supportsCustomizableSelectCache = supported;\n return supported;\n } catch {\n QtiInlineChoiceInteraction._supportsCustomizableSelectCache = false;\n return false;\n }\n }\n\n private _updateOptions() {\n const choices = Array.from(this.querySelectorAll('qti-inline-choice'));\n const prompt = this.dataPrompt || this.configContext?.inlineChoicePrompt || 'select';\n\n const currentlySelectedValue = this.options.find(o => o.selected)?.value ?? '';\n const nextOptions: OptionType[] = [\n {\n textContent: prompt,\n value: '',\n selected: currentlySelectedValue === ''\n },\n ...choices.map(choice => {\n const value = choice.getAttribute('identifier') ?? '';\n return {\n textContent: choice.innerHTML,\n value,\n selected: value !== '' && value === currentlySelectedValue\n };\n })\n ];\n\n const hasSelected = nextOptions.some(o => o.selected);\n this.options = hasSelected ? nextOptions : nextOptions.map((o, i) => ({ ...o, selected: i === 0 }));\n }\n\n public validate(): boolean {\n const selectedOption = this.options.find(option => option.selected);\n return selectedOption ? selectedOption.value !== '' : false;\n }\n\n public override reset() {\n this._setDropdownOpen(false);\n this.options = this.options.map((option, i) => ({ ...option, selected: i === 0 }));\n }\n\n public set response(value: string | null) {\n const nextValue = value ?? '';\n this.options = this.options.map(option => ({ ...option, selected: option.value === nextValue }));\n }\n get response(): string | null {\n const value = this.options.find(option => option.selected)?.value ?? '';\n return value === '' ? null : value;\n }\n\n override toggleInternalCorrectResponse(show: boolean) {\n // Call base class implementation to manage CSS states\n super.toggleInternalCorrectResponse(show);\n\n // Get correct response from either responseVariable (item context) or local property (standalone)\n const correctResponseValue = this.correctResponse;\n\n if (!show || !correctResponseValue) {\n this.correctOption = '';\n return;\n }\n\n const correctOptionData = this.options.find(option => correctResponseValue === option.value);\n if (!correctOptionData) {\n this.correctOption = '';\n return;\n }\n\n this.correctOption = `<span part=\"correct-option\" style=\"border:1px solid var(--qti-correct); border-radius:4px; padding: 2px 4px; margin: 4px; display:inline-block\">${correctOptionData.textContent}</span>`;\n }\n\n private _onNativeChange = (event: Event) => {\n if (this.readonly) return;\n const selectedOptionValue = (event.target as HTMLSelectElement).value;\n this._selectValue(selectedOptionValue);\n };\n\n private _selectValue(value: string) {\n this.options = this.options.map(option => ({ ...option, selected: option.value === value }));\n this.saveResponse(value);\n this._setDropdownOpen(false);\n }\n\n private _setDropdownOpen(open: boolean) {\n if (this._dropdownOpen === open) return;\n this._dropdownOpen = open;\n\n if (open) {\n void this.updateComplete.then(() => {\n this._positionCustomMenu();\n const selected = this.renderRoot.querySelector<HTMLButtonElement>(\n 'button[part=\"option\"][aria-selected=\"true\"]'\n );\n selected?.focus();\n });\n }\n }\n\n private _onToggleCustomDropdown = () => {\n if (this.disabled || this.readonly) return;\n this._setDropdownOpen(!this._dropdownOpen);\n };\n\n private _onCustomTriggerKeyDown = (event: KeyboardEvent) => {\n if (this.disabled || this.readonly) return;\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this._setDropdownOpen(true);\n }\n };\n\n private _onCustomMenuKeyDown = (event: KeyboardEvent) => {\n if (!this._dropdownOpen) return;\n if (event.key === 'Escape') {\n event.preventDefault();\n this._setDropdownOpen(false);\n this._focusTrigger();\n return;\n }\n\n const optionButtons = Array.from(this.renderRoot.querySelectorAll<HTMLButtonElement>('button[part=\"option\"]'));\n const active = (this.renderRoot as ShadowRoot).activeElement as HTMLElement | null;\n const activeIndex = optionButtons.findIndex(btn => btn === active);\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n optionButtons[Math.min(optionButtons.length - 1, Math.max(0, activeIndex + 1))]?.focus();\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n optionButtons[Math.max(0, activeIndex - 1)]?.focus();\n }\n };\n\n private _focusTrigger() {\n this.renderRoot.querySelector<HTMLButtonElement>('button[part=\"trigger\"]')?.focus();\n }\n\n private _onDocumentPointerDown = (event: Event) => {\n if (!this._dropdownOpen) return;\n const path = (event as any).composedPath?.() as EventTarget[] | undefined;\n if (path && path.includes(this)) return;\n this._setDropdownOpen(false);\n };\n\n private _onDocumentKeyDown = (event: KeyboardEvent) => {\n if (!this._dropdownOpen) return;\n if (event.key !== 'Escape') return;\n event.preventDefault();\n this._setDropdownOpen(false);\n this._focusTrigger();\n };\n\n private _positionCustomMenu() {\n if (!this._dropdownOpen) return;\n const menu = this.renderRoot.querySelector<HTMLElement>('[part=\"menu\"]');\n const trigger = this.renderRoot.querySelector<HTMLElement>('button[part=\"trigger\"]');\n if (!menu || !trigger) return;\n\n menu.dataset.placement = 'bottom';\n menu.style.setProperty('--qti-menu-shift-x', '0px');\n menu.style.setProperty('--qti-menu-shift-y', '0px');\n\n const viewportWidth = document.documentElement?.clientWidth || window.innerWidth;\n const viewportHeight = document.documentElement?.clientHeight || window.innerHeight;\n const margin = 8;\n\n const triggerRect = trigger.getBoundingClientRect();\n let menuRect = menu.getBoundingClientRect();\n\n const spaceBelow = viewportHeight - triggerRect.bottom;\n const spaceAbove = triggerRect.top;\n if (menuRect.bottom > viewportHeight - margin && spaceAbove > spaceBelow) {\n menu.dataset.placement = 'top';\n menuRect = menu.getBoundingClientRect();\n }\n\n let shiftX = 0;\n if (menuRect.right > viewportWidth - margin) {\n shiftX = viewportWidth - margin - menuRect.right;\n } else if (menuRect.left < margin) {\n shiftX = margin - menuRect.left;\n }\n\n if (shiftX !== 0) {\n const scaleX = menu.offsetWidth > 0 ? menuRect.width / menu.offsetWidth : 1;\n const adjustedShiftX = Number.isFinite(scaleX) && scaleX !== 0 ? shiftX / scaleX : shiftX;\n menu.style.setProperty('--qti-menu-shift-x', `${adjustedShiftX}px`);\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-inline-choice-interaction': QtiInlineChoiceInteraction;\n }\n}\n","import { css } from 'lit';\n// import componentStyles from '../../utilities/styles/component.styles';\n\n/* ${componentStyles} */\nexport default css`\n slot:not([hidden]) {\n /* slot where the */\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n :host(.qti-choices-top) slot {\n flex-direction: column;\n }\n :host(.qti-choices-bottom) slot {\n flex-direction: column-reverse;\n }\n :host(.qti-choices-left) slot {\n flex-direction: row;\n }\n :host(.qti-choices-right) slot {\n flex-direction: row-reverse;\n }\n slot[name='prompt'] {\n display: block;\n }\n ::slotted(qti-simple-match-set) {\n /* Make sure the drag and drop container slots have the same width */\n flex: 1;\n }\n`;\n","import { html, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { DragDropInteractionMixin } from '../../mixins/drag-drop';\nimport styles from './qti-match-interaction.styles';\n\nimport type { ResponseVariable } from '@qti-components/base';\nimport type { CSSResultGroup } from 'lit';\nimport type { ResponseInteraction } from '@qti-components/base';\nimport type { QtiSimpleAssociableChoice } from '../../elements/qti-simple-associable-choice';\nexport class QtiMatchInteraction extends DragDropInteractionMixin(\n Interaction,\n 'qti-simple-match-set:first-of-type qti-simple-associable-choice, qti-simple-match-set:last-of-type > qti-simple-associable-choice > qti-simple-associable-choice',\n 'qti-simple-match-set:last-of-type > qti-simple-associable-choice',\n 'qti-simple-match-set:first-of-type'\n) {\n static override styles: CSSResultGroup = styles;\n\n protected sourceChoices: QtiSimpleAssociableChoice[];\n protected targetChoices: QtiSimpleAssociableChoice[];\n protected lastCheckedRadio: HTMLInputElement | null = null;\n\n @property({ type: String }) class: string = '';\n\n @state() protected _response: string | string[] = [];\n // dragDropApi: TouchDragAndDrop;\n get response(): string[] {\n if (!this.classList.contains('qti-match-tabular')) return super.response as string[];\n else return this._response as string[];\n }\n set response(val: string[]) {\n if (!this.classList.contains('qti-match-tabular')) super.response = val;\n else this._response = val;\n }\n\n @property({ type: String, attribute: 'response-identifier' }) override responseIdentifier: string = '';\n\n @state() protected correctOptions: { source: string; target: string }[] = null;\n\n override async connectedCallback(): Promise<void> {\n super.connectedCallback();\n this.sourceChoices = Array.from<QtiSimpleAssociableChoice>(\n this.querySelectorAll('qti-simple-match-set:first-of-type qti-simple-associable-choice')\n );\n this.targetChoices = Array.from<QtiSimpleAssociableChoice>(\n this.querySelectorAll('qti-simple-match-set:last-of-type qti-simple-associable-choice')\n );\n\n this.response = [];\n }\n\n protected handleRadioClick = (e: { target: HTMLInputElement }) => {\n const radio = e.target as HTMLInputElement;\n if (this.lastCheckedRadio === radio) {\n radio.checked = false;\n this.lastCheckedRadio = null;\n this.handleRadioChange(e);\n } else {\n this.lastCheckedRadio = radio;\n }\n };\n\n protected handleRadioChange = (e: { target: any }) => {\n const checkbox = e.target as HTMLInputElement;\n const value = checkbox.value;\n const name = checkbox.name;\n const type = checkbox.type;\n\n if (checkbox.checked) {\n if (!this.response) {\n this.response = [value];\n } else if (this.response.indexOf(value) === -1) {\n if (type === 'radio') {\n this.response = (this.response || []).filter(v => v.indexOf(name) === -1);\n }\n this.response = [...this.response, value];\n }\n this.lastCheckedRadio = checkbox;\n } else {\n this.response = (this.response || []).filter(v => v !== value);\n this.lastCheckedRadio = null;\n }\n\n this.requestUpdate();\n this.dispatchEvent(\n new CustomEvent<ResponseInteraction>('qti-interaction-response', {\n bubbles: true,\n composed: true,\n detail: {\n responseIdentifier: this.responseIdentifier,\n response: Array.isArray(this.response) ? [...this.response] : this.response\n }\n })\n );\n };\n\n validate(): boolean {\n if (this.class.split(' ').includes('qti-match-tabular')) {\n return this.response?.length === this.sourceChoices.length;\n } else {\n return super.validate();\n }\n }\n\n private getMatches(responseVariable: ResponseVariable): { source: string; target: string }[] {\n if (!responseVariable.correctResponse) {\n return [];\n }\n const correctResponse = Array.isArray(responseVariable.correctResponse)\n ? responseVariable.correctResponse\n : [responseVariable.correctResponse];\n\n const matches: { source: string; target: string }[] = [];\n if (correctResponse) {\n correctResponse.forEach(x => {\n const split = x.split(' ');\n matches.push({ source: split[0], target: split[1] });\n });\n }\n return matches;\n }\n\n public override toggleInternalCorrectResponse(show: boolean): void {\n const responseVariable = this.responseVariable;\n\n if (!responseVariable?.correctResponse) {\n // Remove all previously added correct responses\n this.querySelectorAll('.correct-option').forEach(el => el.remove());\n return;\n }\n const matches = this.getMatches(responseVariable);\n\n if (!this.class.split(' ').includes('qti-match-tabular')) {\n if (show) {\n // Clear old correct options first\n this.querySelectorAll('.correct-option').forEach(el => el.remove());\n\n this.targetChoices.forEach(targetChoice => {\n const targetId = targetChoice.getAttribute('identifier');\n const match = matches.find(m => m.target === targetId);\n\n if (match?.source) {\n const sourceChoice = this.querySelector(`qti-simple-associable-choice[identifier=\"${match.source}\"]`);\n const text = sourceChoice?.textContent?.trim();\n\n if (text && !targetChoice.previousElementSibling?.classList.contains('correct-option')) {\n const textSpan = document.createElement('span');\n textSpan.classList.add('correct-option');\n textSpan.textContent = text;\n\n // Style the span\n textSpan.style.border = '1px solid var(--qti-correct)';\n textSpan.style.borderRadius = '4px';\n textSpan.style.padding = '2px 4px';\n textSpan.style.display = 'inline-block';\n\n // Insert before the target choice\n targetChoice.insertAdjacentElement('beforebegin', textSpan);\n }\n }\n });\n } else {\n this.correctOptions = null;\n }\n } else {\n if (show) {\n this.correctOptions = matches || [];\n } else {\n this.correctOptions = null;\n }\n }\n }\n\n public override toggleCandidateCorrection(show: boolean) {\n const responseVariable = this.responseVariable;\n\n if (!responseVariable?.correctResponse) {\n return;\n }\n const matches = this.getMatches(responseVariable);\n\n this.targetChoices.forEach(targetChoice => {\n const targetId = targetChoice.getAttribute('identifier');\n const targetMatches = matches.filter(m => m.target === targetId);\n\n const selectedChoices = targetChoice.querySelectorAll(`qti-simple-associable-choice`);\n\n selectedChoices.forEach(selectedChoice => {\n selectedChoice.internals.states.delete('candidate-correct');\n selectedChoice.internals.states.delete('candidate-incorrect');\n\n if (!show) {\n return;\n }\n\n const isCorrect = targetMatches.find(m => m.source === selectedChoice.identifier)?.source !== undefined;\n if (isCorrect) {\n selectedChoice.internals.states.add('candidate-correct');\n } else {\n selectedChoice.internals.states.add('candidate-incorrect');\n }\n });\n });\n }\n\n override render() {\n const isTabular = this.class.split(' ').includes('qti-match-tabular');\n const hasCorrectResponse = this.correctOptions !== null;\n return html`\n <slot name=\"prompt\"></slot>\n <slot ?hidden=${isTabular}></slot>\n\n ${isTabular\n ? html`\n <table part=\"table\">\n <tr part=\"r-header\">\n <td></td>\n ${this.targetChoices.map(col => html`<th part=\"r-header\">${unsafeHTML(col.innerHTML)}</th>`)}\n </tr>\n\n ${this.sourceChoices.map(\n row =>\n html`<tr part=\"row\">\n <td part=\"c-header\">${unsafeHTML(row.innerHTML)}</td>\n ${this.targetChoices.map(col => {\n const rowId = row.getAttribute('identifier');\n const colId = col.getAttribute('identifier');\n const value = `${rowId} ${colId}`;\n const selectedInRowCount =\n (this.response || []).filter(v => v.split(' ')[0] === rowId).length || 0;\n const checked = this.response?.includes(value) || false;\n const type = row.matchMax === 1 ? 'radio' : 'checkbox';\n const isCorrect = !!this.correctOptions?.find(\n option => option.source === rowId && option.target === colId\n );\n const part =\n type === 'radio'\n ? `rb ${checked ? 'rb-checked' : ''} ${hasCorrectResponse ? (isCorrect ? 'rb-correct' : 'rb-incorrect') : ''}`\n : `cb ${checked ? 'cb-checked' : ''} ${hasCorrectResponse ? (isCorrect ? 'cb-correct' : 'cb-incorrect') : ''}`;\n\n // disable if match max is greater than 1 and max is reached\n const disable =\n this.correctOptions?.length > 0\n ? true\n : row.matchMax === 1\n ? false\n : row.matchMax !== 0 && selectedInRowCount >= row.matchMax && !checked;\n return html`<td part=\"input-cell\">\n <div\n class=\"input-container\"\n style=\"position: relative; width: 24px; height: 24px; margin: 0 auto;\"\n >\n <input\n type=${type}\n part=${part}\n name=${rowId}\n value=${value}\n .disabled=${disable}\n @change=${(e: { target: any }) => this.handleRadioChange(e)}\n @click=${(e: { target: HTMLInputElement }) =>\n row.matchMax === 1 ? this.handleRadioClick(e) : null}\n />\n ${type === 'checkbox' && checked\n ? html`\n <svg\n part=\"checkmark\"\n viewBox=\"0 0 24 24\"\n style=\"position: absolute; width: 20px; height: 20px; top: 2px; left: 2px; pointer-events: none;\"\n >\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z\" fill=\"white\" />\n </svg>\n `\n : ''}\n </div>\n </td>`;\n })}\n </tr>`\n )}\n </table>\n `\n : nothing}\n\n <div role=\"alert\" part=\"message\" id=\"validation-message\"></div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-match-interaction': QtiMatchInteraction;\n }\n}\n","import { css, html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\nexport class QtiMediaInteraction extends Interaction {\n private _value: number = null;\n\n override reset() {\n this._value = null;\n }\n validate(): boolean {\n return true;\n }\n\n get response(): string | null {\n return this._value ? this._value.toString() : null;\n }\n\n set response(val: string | null) {\n if (val) {\n const isNumber = !isNaN(parseInt(val?.toString()));\n if (isNumber) {\n this._value = parseInt(val.toString());\n } else {\n throw new Error(`Value must be a number ${val}`);\n }\n }\n }\n\n static override get properties() {\n return {\n ...Interaction.properties,\n ...{\n step: {\n type: Number,\n attribute: 'step',\n default: 10\n }\n }\n };\n }\n\n static override styles = [css``];\n\n override render() {\n return html` <slot name=\"prompt\"></slot>\n <slot></slot>`;\n }\n\n constructor() {\n super();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n // get audio, video of object tag.\n const mediaObject = this.querySelector('audio') || this.querySelector('video') || this.querySelector('object');\n if (mediaObject) {\n // listen to ended event\n mediaObject.addEventListener('ended', () => {\n // set value to 0\n // check if this.value is a number\n this._value++;\n this.saveResponse(this.value);\n });\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-media-interaction': QtiMediaInteraction;\n }\n}\n","import { css } from 'lit';\n// import componentStyles from '../../utilities/styles/component.styles';\n// :host {\n// display: inline-block;\n// position: relative;\n// }\n/* ${componentStyles} */\nexport default css`\n [part='drags'] {\n display: flex;\n align-items: flex-start;\n flex: 1;\n flex-wrap: wrap;\n }\n\n [part='drops'] {\n flex: 1;\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n }\n\n :host([orientation='horizontal']) [part='drags'] {\n flex-direction: row;\n }\n :host([orientation='horizontal']) [part='drops'] {\n grid-auto-flow: column;\n }\n :host([orientation='vertical']) [part='drags'] {\n flex-direction: column;\n }\n :host([orientation='vertical']) [part='drops'] {\n grid-auto-flow: row;\n }\n\n [part='drop-list'] {\n display: block;\n flex: 1;\n }\n\n [part='drop-list'][active] {\n border-color: var(--qti-border-active) !important;\n background-color: var(--qti-bg-active) !important;\n }\n\n [part='drop-list'][enabled] {\n background-color: var(--qti-bg-active) !important;\n }\n\n [part='container'] {\n display: flex;\n gap: 0.5rem;\n }\n :host(.qti-choices-top) [part='container'] {\n flex-direction: column;\n }\n :host(.qti-choices-bottom) [part='container'] {\n flex-direction: column-reverse;\n }\n :host(.qti-choices-left) [part='container'] {\n flex-direction: row;\n }\n :host(.qti-choices-right) [part='container'] {\n flex-direction: row-reverse;\n }\n`;\n","import { html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\n\nimport { DragDropInteractionMixin } from '../../mixins/drag-drop';\nimport styles from './qti-order-interaction.styles';\n\nimport type { PropertyValueMap } from 'lit';\nimport type { QtiSimpleChoice } from '../../elements/qti-simple-choice';\nexport class QtiOrderInteraction extends DragDropInteractionMixin(\n Interaction,\n `qti-simple-choice`,\n 'drop-list',\n `slot[part='drags']`\n) {\n static override styles = styles;\n protected childrenMap: Element[];\n\n @state() protected nrChoices: number = 0;\n @state() correctResponses: string[] = [];\n @state() showCorrectResponses: boolean = false;\n\n /** orientation of choices */\n @property({ type: String })\n public orientation: 'horizontal' | 'vertical';\n\n override render() {\n const choices = Array.from(this.querySelectorAll('qti-simple-choice'));\n if (this.nrChoices < choices.length) {\n this.nrChoices = choices.length;\n }\n\n return html` <slot name=\"prompt\"> </slot>\n <div part=\"container\">\n <slot part=\"drags\"> </slot>\n <div part=\"drops\">\n ${[...Array(this.nrChoices)].map(\n (_, i) => html`<drop-list role=\"region\" part=\"drop-list\" identifier=\"droplist${i}\"></drop-list>`\n )}\n </div>\n </div>`;\n }\n\n public override toggleCorrectResponse(show: boolean): void {\n const responseVariable = this.responseVariable;\n // Always start by removing old correct answers\n this.shadowRoot.querySelectorAll('.correct-option').forEach(option => option.remove());\n\n if (show && responseVariable?.correctResponse) {\n const response = Array.isArray(responseVariable.correctResponse)\n ? responseVariable.correctResponse\n : [responseVariable.correctResponse];\n\n const correctIds = response.map(r => r.split(' ')[0]); // e.g., ['A', 'B', 'C']\n\n const used = new Set<string>(); // to track already rendered correct-answers\n\n const gaps = this.querySelectorAll('qti-simple-choice');\n\n gaps.forEach((gap, i) => {\n const identifier = gap.getAttribute('identifier');\n if (!identifier || !correctIds.includes(identifier)) return;\n\n // Only render once per identifier\n if (used.has(identifier)) return;\n used.add(identifier);\n\n // Get the choice label\n const text = gap.textContent?.trim();\n if (!text) return;\n\n const relativeDrop = this.shadowRoot.querySelector(`drop-list[identifier=\"droplist${i}\"]`);\n if (!relativeDrop) return;\n\n const span = document.createElement('span');\n span.classList.add('correct-option');\n span.textContent = text;\n\n // Style\n span.style.border = '1px solid var(--qti-correct)';\n span.style.borderRadius = '4px';\n span.style.padding = '2px 4px';\n span.style.display = 'inline-block';\n span.style.marginTop = '4px';\n\n relativeDrop.insertAdjacentElement('afterend', span);\n });\n }\n }\n\n // some interactions have a different way of getting the response\n // this is called from the drag and drop mixin class\n // you have to implement your own getResponse method in the superclass\n // cause they are different for some interactions.\n getValue(val: string[]) {\n return val?.map((v, i) => `${v} droplist${i}`) || [];\n }\n\n // some interactions have a different way of getting the response\n // this is called from the drag and drop mixin class\n // you have to implement your own getResponse method in the superclass\n // cause they are different for some interactions.\n // MH: is this function called? Shouldn't we use getValue?\n protected getResponse(): string[] {\n const droppables = Array.from<QtiSimpleChoice>(this.shadowRoot.querySelectorAll('drop-list'));\n\n const response = droppables.map(droppable => {\n const dragsInDroppable = droppable.querySelectorAll('[qti-draggable=\"true\"]');\n const identifiers = Array.from(dragsInDroppable).map(d => d.getAttribute('identifier'));\n return [...identifiers].join(' ');\n });\n return response;\n }\n\n override async firstUpdated() {\n super.firstUpdated();\n this.childrenMap = Array.from(this.querySelectorAll('qti-simple-choice'));\n this.childrenMap.forEach(el => el.setAttribute('part', 'qti-simple-choice'));\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-order-interaction': QtiOrderInteraction;\n }\n}\n","import { css } from 'lit';\n// import componentStyles from '../../utilities/styles/component.styles';\n\n/* ${componentStyles} */\nexport default css`\n ::slotted(qti-interaction-markup) {\n display: none;\n }\n`;\n","import { css, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { consume } from '@lit/context';\n\nimport { removeDoubleSlashes } from '@qti-components/base';\nimport { Interaction } from '@qti-components/base';\nimport { itemContext } from '@qti-components/base';\n\nimport styles from './qti-portable-custom-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nimport type { ItemContext } from '@qti-components/base';\nimport type { BaseType, Cardinality } from '@qti-components/base';\nimport type { QtiVariableJSON, ResponseVariableType } from './interface';\n\nexport class QtiPortableCustomInteraction extends Interaction {\n private _value: string | string[];\n\n protected _iframeLoaded = false;\n protected _pendingMessages: Array<{ method: string; params: any }> = [];\n protected iframe: HTMLIFrameElement;\n protected _iframeMessageOrigin: string | null = null;\n\n // This implementation always renders inside an iframe.\n static override styles: CSSResultGroup = [\n styles,\n css`\n :host {\n display: block;\n width: 100%;\n min-height: 50px;\n }\n `\n ];\n\n @property({ type: String, attribute: 'module' })\n module: string;\n\n @property({ type: String, attribute: 'custom-interaction-type-identifier' })\n customInteractionTypeIdentifier: string;\n\n @property({ type: String, attribute: 'data-require-paths' })\n requirePathsJson: string = '';\n\n @property({ type: String, attribute: 'data-require-shim' })\n requireShimJson: string = '';\n\n @property({ type: String, attribute: 'data-require-js-url' })\n requireJsUrl: string = 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js';\n\n @property({ type: String, attribute: 'data-base-url' })\n baseUrl: string = '';\n\n @property({ type: Boolean, attribute: 'data-use-default-shims' })\n useDefaultShims = false;\n\n @property({ type: Boolean, attribute: 'data-use-default-paths' })\n useDefaultPaths = false;\n\n @state()\n private _errorMessage: string = null;\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n protected context?: ItemContext;\n\n @state() response: string | string[] | null = null;\n\n private _parsedRequirePaths: Record<string, string | string[]> = null;\n private _parsedRequireShim: Record<string, any> = null;\n\n /**\n * Parse the require paths JSON string into an object\n */\n private getRequirePaths(): Record<string, string | string[]> {\n if (this._parsedRequirePaths === null && this.requirePathsJson) {\n try {\n // Handle the array format [{name: \"path/name\", value: \"path/value\"}, ...]\n // and convert to object format {name: value, ...}\n const parsedJson = JSON.parse(this.requirePathsJson);\n if (Array.isArray(parsedJson)) {\n this._parsedRequirePaths = {};\n parsedJson.forEach(item => {\n if (item.name && item.value) {\n this._parsedRequirePaths[item.name] = item.value;\n }\n });\n } else {\n // If it's already in object format, use it directly\n this._parsedRequirePaths = parsedJson;\n }\n } catch (e) {\n console.error('Error parsing require paths JSON:', e);\n this._errorMessage = `Error parsing require paths JSON: ${e.message}`;\n this._parsedRequirePaths = {};\n }\n }\n return this._parsedRequirePaths || {};\n }\n\n /**\n * Parse the require shim JSON string into an object\n */\n private getRequireShim(): Record<string, any> {\n if (this._parsedRequireShim === null && this.requireShimJson) {\n try {\n this._parsedRequireShim = JSON.parse(this.requireShimJson);\n } catch (e) {\n console.error('Error parsing require shim JSON:', e);\n this._errorMessage = `Error parsing require shim JSON: ${e.message}`;\n this._parsedRequireShim = {};\n }\n }\n return this._parsedRequireShim || {};\n }\n\n /**\n * Get the default require paths\n */\n private getDefaultRequirePaths(): Record<string, string | string[]> {\n return {\n 'taoQtiItem/portableLib/OAT/util/event': '/assets/pci-scripts/portableLib/OAT/util/event',\n 'taoQtiItem/portableLib/OAT/util/html': '/assets/pci-scripts/portableLib/OAT/util/html',\n 'taoQtiItem/portableLib/OAT/util/EventMgr': '/assets/pci-scripts/portableLib/OAT/util/EventMgr',\n 'taoQtiItem/portableLib/OAT/util/math': '/assets/pci-scripts/portableLib/OAT/util/math',\n 'taoQtiItem/portableLib/OAT/util/xml': '/assets/pci-scripts/portableLib/OAT/util/xml',\n 'taoQtiItem/portableLib/OAT/util/tooltip': '/assets/pci-scripts/portableLib/OAT/util/tooltip',\n 'taoQtiItem/portableLib/jquery_2_1_1': '/assets/pci-scripts/portableLib/jquery_2_1_1',\n 'taoQtiItem/pci-scripts/portableLib/jquery.qtip': '/assets/portableLib/jquery.qtip',\n 'taoQtiItem/pci-scripts/portableLib/lodash': '/assets/pci-scripts/portableLib/lodash',\n 'taoQtiItem/pci-scripts/portableLib/raphael': '/assets/pci-scripts/portableLib/raphael',\n 'IMSGlobal/jquery_2_1_1': '/assets/pci-scripts/IMSGlobal/jquery_2_1_1',\n 'OAT/util/event': '/assets/pci-scripts/legacyPortableSharedLib/OAT/util/event',\n 'OAT/util/html': '/assets/pci-scripts/legacyPortableSharedLib/OAT/util/html',\n 'OAT/util/EventMgr': '/assets/pci-scripts/legacyPortableSharedLib/OAT/util/EventMgr',\n 'OAT/util/math': '/assets/pci-scripts/legacyPortableSharedLib/OAT/util/math',\n 'OAT/util/xml': '/assets/pci-scripts/legacyPortableSharedLib/OAT/util/xml',\n 'OAT/util/tooltip': '/assets/pci-scripts/legacyPortableSharedLib/OAT/util/tooltip',\n 'OAT/lodash': '/assets/pci-scripts/legacyPortableSharedLib/lodash',\n mathJax: '/assets/pci-scripts/mathjax/mathJax',\n css: '/assets/pci-scripts/css/css'\n };\n }\n\n /**\n * Get the default require shim\n */\n private getDefaultRequireShim(): Record<string, any> {\n return {\n mathJax: {\n exports: 'MathJax',\n init: function () {\n const anyWindow = window as any;\n if (anyWindow.MathJax) {\n anyWindow.MathJax.Hub.Config({\n showMathMenu: false,\n showMathMenuMSIE: false,\n menuSettings: { inTabOrder: false }\n });\n anyWindow.MathJax.Hub.Startup.MenuZoom = function () {\n /* nothing */\n };\n anyWindow.MathJax.Hub.Startup.onload();\n return anyWindow.MathJax;\n }\n }\n }\n };\n }\n\n /**\n * Get the final require paths by combining defaults with user-provided paths\n */\n private getFinalRequirePaths(): Record<string, string | string[]> {\n const defaults = this.getDefaultRequirePaths();\n const userPaths = this.getRequirePaths();\n if (this.useDefaultPaths) {\n return { ...defaults, ...userPaths };\n }\n return userPaths;\n }\n\n /**\n * Get the final require shim by combining defaults with user-provided shim\n */\n private getFinalRequireShim(): Record<string, any> {\n const userShim = this.getRequireShim();\n const defaults = this.getDefaultRequireShim();\n if (this.useDefaultShims) {\n return { ...defaults, ...userShim };\n }\n return userShim;\n }\n\n /**\n * Converts QtiVariableJSON to a string or string array\n */\n private convertQtiVariableJSON(input: QtiVariableJSON): string | string[] {\n for (const topLevelKey in input) {\n // eslint-disable-next-line no-prototype-builtins\n if (input.hasOwnProperty(topLevelKey)) {\n const nestedObject = input[topLevelKey as 'list' | 'base'];\n if (nestedObject) {\n for (const nestedKey in nestedObject) {\n // eslint-disable-next-line no-prototype-builtins\n if (nestedObject.hasOwnProperty(nestedKey)) {\n const value = nestedObject[nestedKey as keyof typeof nestedObject];\n if (Array.isArray(value)) {\n return value.map(String); // Convert each element in the array to string\n } else if (value !== undefined && value !== null) {\n return String(value); // Convert the single value to string\n }\n }\n }\n }\n }\n }\n return null;\n }\n\n /**\n * Adds hyphenated versions of camelCase keys to properties object\n */\n private addHyphenatedKeys(properties: Record<string, any>): Record<string, any> {\n const updatedProperties = { ...properties };\n\n for (const key in properties) {\n if (Object.prototype.hasOwnProperty.call(properties, key)) {\n const hyphenatedKey = key.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`);\n updatedProperties[hyphenatedKey] = properties[key];\n }\n }\n\n return updatedProperties;\n }\n\n /**\n * Converts response variables to QtiVariableJSON\n */\n protected responseVariablesToQtiVariableJSON(\n input: string | string[],\n cardinality: Cardinality,\n baseType: BaseType\n ): QtiVariableJSON {\n if (cardinality !== 'single') {\n const list = { list: {} };\n list.list[baseType] = input;\n return list;\n } else {\n const base = { base: {} };\n base.base[baseType] = input;\n return base;\n }\n }\n\n validate(): boolean {\n if (this.response === null || this.response === undefined) return false;\n if (Array.isArray(this.response)) {\n if (this.response.length === 0) return false;\n return this.response.some(v => v !== '' && v !== null && v !== undefined);\n }\n return this.response !== '';\n }\n\n override set value(v: string | null) {\n if (v === null) {\n this._value = [];\n } else {\n this._value = Array.isArray(v) ? v : v.split(',');\n }\n // PCI handles response setting via boundTo property during initialization\n // No need to call setResponse directly\n }\n\n override get value(): string | null {\n if (this._value === null || this._value === undefined) return null;\n return Array.isArray(this._value) ? this._value.join(',') : String(this._value);\n }\n\n set boundTo(newValue: Record<string, ResponseVariableType>) {\n if (!newValue || !newValue[this.responseIdentifier]) {\n return;\n }\n\n const value = this.convertQtiVariableJSON(newValue[this.responseIdentifier]);\n this._value = value;\n\n // No direct call to setResponse - PCI will handle this during initialization\n // through the boundTo property in the config\n\n this.saveResponse(value);\n }\n\n get boundTo(): Record<string, QtiVariableJSON> {\n const responseVariable: Record<string, QtiVariableJSON> = {};\n const variable = this.context?.variables?.find(v => v.identifier === this.responseIdentifier);\n if (variable) {\n const cardinality =\n this.context?.variables?.find(v => v.identifier === this.responseIdentifier)?.cardinality || 'single';\n const baseType =\n this.context?.variables?.find(v => v.identifier === this.responseIdentifier)?.baseType || 'string';\n const value = this.context?.variables?.find(v => v.identifier === this.responseIdentifier)?.value || null;\n const responseVal = this.responseVariablesToQtiVariableJSON(value as string | string[], cardinality, baseType);\n responseVariable[this.responseIdentifier] = responseVal;\n }\n\n return responseVariable;\n }\n\n /**\n * Unescape HTML entities in a string\n */\n private unescapeHtml(str: string): string {\n if (!str) return str;\n\n return str\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#x27;/g, \"'\")\n .replace(/&#x2F;/g, '/')\n .replace(/&#x60;/g, '`')\n .replace(/&#x3D;/g, '=');\n }\n\n /**\n * Unescape HTML entities in all values of an object\n */\n private unescapeDataAttributes(obj: Record<string, any>): Record<string, any> {\n const unescaped: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'string') {\n unescaped[key] = this.unescapeHtml(value);\n } else {\n unescaped[key] = value;\n }\n }\n\n return unescaped;\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('message', this.handleIframeMessage);\n }\n\n /**\n * IFRAME MODE: Send message to iframe\n */\n protected sendMessageToIframe(method: string, params: any) {\n const targetWindow = this.iframe?.contentWindow;\n if (!this._iframeLoaded || !targetWindow) {\n this._pendingMessages.push({ method, params });\n return;\n }\n targetWindow.postMessage(\n {\n source: 'qti-portable-custom-interaction',\n responseIdentifier: this.responseIdentifier,\n method,\n params\n },\n '*'\n );\n }\n\n /**\n * IFRAME MODE: Process pending messages\n */\n private processPendingMessages() {\n if (this._pendingMessages.length) {\n this._pendingMessages.forEach(message => {\n this.sendMessageToIframe(message.method, message.params);\n });\n this._pendingMessages = [];\n }\n }\n\n /**\n * IFRAME MODE: Handle iframe messages\n */\n protected handleIframeMessage = (event: MessageEvent) => {\n const { data } = event;\n // Ensure the message is from our iframe\n if (!data || data.source !== 'qti-pci-iframe') {\n return;\n }\n if (!this.iframe?.contentWindow || event.source !== this.iframe.contentWindow) {\n return;\n }\n if (data.responseIdentifier && data.responseIdentifier !== this.responseIdentifier) {\n return;\n }\n if (this._iframeMessageOrigin === null) {\n this._iframeMessageOrigin = event.origin;\n } else if (event.origin !== this._iframeMessageOrigin) {\n return;\n }\n switch (data.method) {\n case 'iframeReady':\n this.initializeInteraction();\n this.processPendingMessages();\n this.dispatchEvent(\n new CustomEvent('qti-portable-custom-interaction-loaded', {\n bubbles: true\n })\n );\n break;\n\n case 'resize':\n if (typeof data.height === 'number' && this.iframe) {\n this.iframe.style.height = `${data.height}px`;\n this.iframe.style.width = `${data.width}px`;\n }\n break;\n\n case 'interactionChanged': {\n const raw = data?.params?.value;\n const converted = raw && typeof raw === 'object' ? this.convertQtiVariableJSON(raw as QtiVariableJSON) : null;\n // PCI state \"should\" be an opaque string, but a lot of existing PCIs (including the\n // IMS conformance examples) return a structured object from getState().\n //\n // We store a string in itemContext.state, so we serialize non-string states with a\n // prefix to safely round-trip them without accidentally parsing user-provided strings.\n const stateRaw = data?.params?.state as unknown;\n let state: string | null | undefined;\n if (stateRaw === undefined) {\n state = undefined;\n } else if (stateRaw === null) {\n state = null;\n } else if (typeof stateRaw === 'string') {\n state = stateRaw;\n } else {\n try {\n state = `__qti_json__::${JSON.stringify(stateRaw)}`;\n } catch {\n state = null;\n }\n }\n\n // Treat null/undefined or unconvertible responses as \"cleared\".\n // The iframe side is responsible for not emitting an initial clear on load.\n if (converted === null) {\n const emptyResponse = this.responseVariable?.cardinality === 'single' ? '' : [];\n this.response = emptyResponse;\n this.validate();\n this.saveResponse(emptyResponse, state);\n break;\n }\n\n this.response = converted;\n this.validate();\n this.saveResponse(converted, state);\n break;\n }\n case 'error':\n this._errorMessage = data.params.message;\n console.error('Error from PCI iframe:', data.params.message);\n break;\n }\n };\n\n /**\n * IFRAME MODE: Create iframe element\n */\n protected createIframe() {\n this.iframe = document.createElement('iframe');\n this.iframe.id = `pci-iframe-${this.responseIdentifier}`;\n this.iframe.setAttribute('title', 'QTI PCI Iframe');\n this.iframe.setAttribute('aria-label', 'QTI PCI Iframe');\n this.iframe.setAttribute('aria-hidden', 'false');\n this.iframe.setAttribute('role', 'application');\n this.iframe.style.width = '100%';\n this.iframe.style.border = 'none';\n this.iframe.style.display = 'block';\n\n // Handle iframe load event\n this.iframe.onload = () => {\n this._iframeLoaded = true;\n this.addMarkupToIframe();\n // Send initialization data to iframe\n this.sendIframeInitData();\n };\n\n // Create a unique name for the iframe\n const iframeName = `qti-pci-${this.responseIdentifier}-${Date.now()}`;\n this.iframe.name = iframeName;\n\n // Generate iframe HTML content with all required scripts\n const iframeContent = this.generateIframeContent();\n\n // Set iframe src as data URI\n const encodedContent = encodeURIComponent(iframeContent);\n this.iframe.src = `data:text/html;charset=utf-8,${encodedContent}`;\n\n // Append iframe to component\n this.appendChild(this.iframe);\n }\n\n /**\n * IFRAME MODE: Send initialization data to iframe\n */\n private sendIframeInitData() {\n // Once iframe is loaded, send initialization data\n const properties = this.addHyphenatedKeys(this.unescapeDataAttributes({ ...this.dataset }));\n const storedStateRaw = this.context?.state?.[this.responseIdentifier];\n const storedState = typeof storedStateRaw === 'string' && storedStateRaw.length > 0 ? storedStateRaw : null;\n const initData = {\n module: this.module,\n customInteractionTypeIdentifier: this.customInteractionTypeIdentifier,\n baseUrl: !this.baseUrl\n ? window.location.origin\n : this.baseUrl.startsWith('http') || this.baseUrl.startsWith('blob') || this.baseUrl.startsWith('base64')\n ? this.baseUrl\n : removeDoubleSlashes(`${window.location.origin}${this.baseUrl}`),\n responseIdentifier: this.responseIdentifier,\n properties,\n dataAttributes: { ...this.dataset },\n interactionModules: this.getInteractionModules(),\n boundTo: storedState ? null : this.boundTo,\n state: storedState\n };\n\n this.sendMessageToIframe('initialize', initData);\n }\n\n /**\n * IFRAME MODE: Get interaction modules from DOM\n */\n private getInteractionModules() {\n const modules = [];\n const interactionModules = this.querySelector('qti-interaction-modules');\n\n if (interactionModules) {\n const moduleElements = interactionModules.querySelectorAll('qti-interaction-module');\n for (const module of moduleElements) {\n modules.push({\n id: module.getAttribute('id'),\n primaryPath: module.getAttribute('primary-path'),\n fallbackPath: module.getAttribute('fallback-path')\n });\n }\n }\n\n return modules;\n }\n\n /**\n * IFRAME MODE: Add markup and properties to iframe\n */\n private addMarkupToIframe() {\n // Get interaction markup if any\n const markup = this.querySelector('qti-interaction-markup');\n if (markup) {\n this.sendMessageToIframe('setMarkup', markup.innerHTML);\n }\n // Get properties if any\n const properties = this.querySelector('properties');\n if (properties) {\n this.sendMessageToIframe('setProperties', properties.innerHTML);\n }\n }\n\n /**\n * IFRAME MODE: Initialize the interaction\n */\n private initializeInteraction() {\n // No explicit action needed, as the PCI will initialize\n // with the boundTo property already provided\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Reflect any pre-existing response (e.g. restored session) for validation/completionStatus.\n this.response = (this.responseVariable?.value as string | string[] | null) ?? null;\n window.addEventListener('message', this.handleIframeMessage);\n this.createIframe();\n }\n\n /**\n * IFRAME MODE: Generate iframe HTML content\n */\n protected generateIframeContent(): string {\n const parentStyles = window.getComputedStyle(document.body);\n\n // Get the configured require paths and shim\n const requirePaths = JSON.stringify(this.getFinalRequirePaths());\n const requireShim = JSON.stringify(this.getFinalRequireShim());\n\n // Extract just the font-related properties you want to copy\n const fontStyles = `\n font-family: ${parentStyles.getPropertyValue('font-family')};\n font-size: ${parentStyles.getPropertyValue('font-size')};\n line-height: ${parentStyles.getPropertyValue('line-height')};\n font-weight: ${parentStyles.getPropertyValue('font-weight')};\n color: ${parentStyles.getPropertyValue('color')};\n `;\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <title>QTI PCI Container</title>\n <base href=\"${window.location.origin}\" />\n <style>\n body, html {\n margin: 0;\n padding: 0;\n width: 100%;\n height: auto;\n overflow: hidden;\n /* Add the extracted font styles here */\n ${fontStyles}\n }\n .qti-customInteraction {\n width: 100%;\n height: 100%;\n }\n #pci-container {\n width: 100%;\n }\n qti-interaction-markup {\n display: block;\n width: 100%;\n min-height: 50px;\n }\n </style>\n <script src=\"${this.requireJsUrl}\"></script>\n <script>\n // Define standard paths and shims\n window.requirePaths = ${requirePaths};\n\n window.requireShim = ${requireShim};\n\n // Single initial RequireJS configuration with error handling\n window.requirejs.config({\n catchError: true,\n waitSeconds: 30,\n paths: window.requirePaths,\n baseUrl: '${this.dataset.baseUrl}',\n shim: window.requireShim,\n onNodeCreated: function(node, config, moduleName, url) {\n // Add error handler to script node\n node.addEventListener('error', function(evt) {\n console.error('Script load error for module:', moduleName, 'URL:', url, 'Event:', evt);\n });\n },\n onError: function(err) {\n console.error('RequireJS error:', {\n type: err.requireType,\n modules: err.requireModules,\n error: err\n });\n\n if (err.requireType === 'scripterror') {\n console.error('Script error usually indicates a network or CORS issue with:', err.requireModules);\n }\n\n\t // Notify parent window about the error\n\t window.parent.postMessage({\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: (window.PCIManager && window.PCIManager.responseIdentifier) || null,\n\t method: 'error',\n\t params: {\n\t message: 'RequireJS ' + err.requireType + ' error for modules: ' + err.requireModules,\n\t details: {\n\t type: err.requireType,\n modules: err.requireModules,\n error: err.toString()\n }\n }\n }, '*');\n }\n });\n\n // PCI Manager for iframe implementation\n window.PCIManager = {\n pciInstance: null,\n container: null,\n markupEl: null,\n propertiesEl: null,\n customInteractionTypeIdentifier: null,\n responseIdentifier: null,\n pendingBoundTo: null,\n pendingMarkup: null,\n pendingProperties: null,\n pendingState: null,\n interactionChangedViaEvent: false,\n eventBridgeAttached: false,\n lastResponseStr: null,\n hadResponse: false,\n\n initialize: function(config) {\n this.customInteractionTypeIdentifier = config.customInteractionTypeIdentifier;\n this.responseIdentifier = config.responseIdentifier;\n this.container = document.getElementById('pci-container');\n this.container.classList.add('qti-customInteraction');\n\n function qtiVariableHasValue(qtiVar) {\n if (!qtiVar) return false;\n if (qtiVar.base) {\n for (const k in qtiVar.base) {\n if (!Object.prototype.hasOwnProperty.call(qtiVar.base, k)) continue;\n const v = qtiVar.base[k];\n if (v !== null && v !== undefined && v !== '') return true;\n }\n }\n if (qtiVar.list) {\n for (const k in qtiVar.list) {\n if (!Object.prototype.hasOwnProperty.call(qtiVar.list, k)) continue;\n const v = qtiVar.list[k];\n if (Array.isArray(v) && v.some(x => x !== null && x !== undefined && x !== '')) return true;\n }\n }\n if (Array.isArray(qtiVar.record) && qtiVar.record.length > 0) return true;\n return false;\n }\n\n const initialBoundTo = config.boundTo && config.boundTo[this.responseIdentifier];\n this.hadResponse = qtiVariableHasValue(initialBoundTo);\n this.lastResponseStr = this.hadResponse ? JSON.stringify(initialBoundTo) : null;\n // Ensure expected DOM structure exists (markup + properties)\n this.markupEl = this.container.querySelector('qti-interaction-markup');\n if (!this.markupEl) {\n this.markupEl = document.createElement('qti-interaction-markup');\n this.container.appendChild(this.markupEl);\n }\n this.markupEl.classList.add('qti-customInteraction');\n this.propertiesEl = this.container.querySelector('properties');\n if (!this.propertiesEl) {\n this.propertiesEl = document.createElement('properties');\n this.propertiesEl.style.display = 'none';\n this.container.appendChild(this.propertiesEl);\n } else {\n this.propertiesEl.style.display = 'none';\n }\n\n // Apply any markup/properties that arrived before initialization\n if (this.pendingMarkup !== null) {\n this.setMarkup(this.pendingMarkup);\n this.pendingMarkup = null;\n }\n if (this.pendingProperties !== null) {\n this.setProperties(this.pendingProperties);\n this.pendingProperties = null;\n }\n\n // Bridge qti-interaction-changed events (preferred over polling)\n if (!this.eventBridgeAttached) {\n this.eventBridgeAttached = true;\n const self = this;\n\t this.container.addEventListener(\n\t 'qti-interaction-changed',\n\t function(evt) {\n\t try {\n\t self.interactionChangedViaEvent = true;\n\t const value = evt && evt.detail ? evt.detail.value : undefined;\n\t if (value !== undefined) {\n\t const state = self.pciInstance && typeof self.pciInstance.getState === 'function' ? self.pciInstance.getState() : null;\n\t self.notifyInteractionChanged(value, state);\n\t }\n\t } catch (e) {\n\t // ignore bridge errors, polling fallback may still work\n\t }\n\t },\n true\n );\n }\n\n function getResolvablePath(path, basePath) {\n if (Array.isArray(path)) {\n return path.map(p => getResolvablePathString(p, basePath));\n } else {\n return getResolvablePathString(path, basePath);\n }\n }\n\n function removeDoubleSlashes(str) {\n return str\n .replace(/([^:\\\\/])\\\\/\\\\/+/g, '$1/')\n .replace(/\\\\/\\\\//g, '/')\n .replace('http:/', 'http://')\n .replace('https:/', 'https://');\n }\n\n function getResolvablePathString(path, basePath) {\n path = path.replace(/\\\\.js$/, '');\n return path?.toLocaleLowerCase().startsWith('http') || !basePath\n ? path\n : removeDoubleSlashes(\\`\\${basePath}/\\${path}\\`);\n }\n\n function combineRequireResolvePaths(path1, path2, baseUrl) {\n path1 = getResolvablePath(path1, baseUrl);\n const path1Array = Array.isArray(path1) ? path1 : [path1];\n if (!path2) {\n return path1Array;\n }\n path2 = getResolvablePath(path2, baseUrl);\n const path2Array = Array.isArray(path2) ? path2 : [path2];\n return path1Array.concat(path2Array).filter((value, index, self) => self.indexOf(value) === index);\n }\n\n // Update paths with modules from the config\n if (config.interactionModules && config.interactionModules.length > 0) {\n config.interactionModules.forEach(module => {\n if (module.id && module.primaryPath) {\n const currentPath = window.requirePaths[module.id] || [];\n const currentPaths = Array.isArray(currentPath) ? currentPath : [currentPath];\n const newPath = combineRequireResolvePaths(\n module.primaryPath, module.fallbackPath, config.baseUrl\n );\n window.requirePaths[module.id] = currentPaths.concat(newPath).filter((value, index, self) => self.indexOf(value) === index);\n }\n });\n }\n\n // The ONLY other requirejs.config call - with the context for this specific PCI\n window.requirejs.config({\n context: this.customInteractionTypeIdentifier,\n paths: window.requirePaths,\n shim: window.requireShim\n });\n\n // Define qtiCustomInteractionContext for the PCI\n define('qtiCustomInteractionContext', () => {\n return {\n register: pciInstance => {\n this.pciInstance = pciInstance;\n // Configure PCI instance\n const pciConfig = {\n properties: config.properties || {},\n contextVariables: config.contextVariables || {},\n templateVariables: config.templateVariables || {},\n onready: pciInstance => {\n this.pciInstance = pciInstance;\n // Apply any pending updates that arrived before onready\n if (this.pendingBoundTo) {\n this.applyBoundTo(this.pendingBoundTo);\n this.pendingBoundTo = null;\n }\n if (this.pendingState && typeof this.pciInstance.setState === 'function') {\n this.pciInstance.setState(this.pendingState);\n this.pendingState = null;\n }\n this.notifyReady();\n },\n\t ondone: (pciInstance, response, state, status) => {\n\t this.notifyInteractionChanged(response, typeof state === 'string' ? state : null);\n\t },\n\t responseIdentifier: config.responseIdentifier,\n\t boundTo: config.boundTo,\n\t };\n\n\t if (pciInstance.getInstance) {\n\t const dom = this.markupEl || this.container;\n\t // Round-trip support for object states (stored as a prefixed JSON string by the host).\n\t // For strict string-based PCIs we pass the original string through unchanged.\n\t let restoredState = config.state;\n\t if (typeof restoredState === 'string' && restoredState.indexOf('__qti_json__::') === 0) {\n\t try {\n\t restoredState = JSON.parse(restoredState.substring('__qti_json__::'.length));\n\t } catch (e) {\n\t // If parsing fails, fall back to the raw string.\n\t restoredState = config.state;\n\t }\n\t }\n\t pciInstance.getInstance(dom, pciConfig, restoredState || undefined);\n\t } else {\n // TAO custom interaction initialization\n const restoreTAOConfig = (dataset) => {\n const config = {};\n const parseDataAttributes = () => {\n const result = {};\n\n // Separate direct attributes from nested ones\n Object.entries(dataset || {}).forEach(([key, value]) => {\n if (!key.includes('__')) {\n // Direct attributes (like version)\n result[key] = value;\n }\n });\n\n // Parse nested attributes\n const nestedData = {};\n\n Object.entries(dataset || {}).forEach(([key, value]) => {\n const parts = key.split('__');\n if (parts.length > 1) {\n const [group, index, prop] = parts;\n nestedData[group] = nestedData[group] || {};\n nestedData[group][index] = nestedData[group][index] || {};\n nestedData[group][index][prop] = value;\n }\n });\n\n // Convert nested groups to arrays\n Object.entries(nestedData).forEach(([key, group]) => {\n result[key] = Object.values(group);\n });\n return result;\n };\n const data = parseDataAttributes();\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n const value = data[key];\n if (key === 'config') {\n config[key] = JSON.parse(value);\n } else {\n config[key] = value;\n }\n }\n }\n return config;\n };\n const taoConfig = restoreTAOConfig(config.dataAttributes);\n\n this.pciInstance.initialize(\n this.customInteractionTypeIdentifier,\n (this.markupEl || this.container).firstElementChild || (this.markupEl || this.container),\n Object.keys(taoConfig).length ? taoConfig : null\n );\n }\n },\n notifyReady: () => {\n PCIManager.notifyReady();\n }\n };\n });\n\n // Load the PCI module\n this.loadModule(config.module);\n },\n\n loadModule: function(modulePath) {\n try {\n // Get the context-specific require\n const contextRequire = window.requirejs.config({\n context: this.customInteractionTypeIdentifier\n });\n contextRequire(['require'], require => {\n // Now load the actual module\n require([modulePath], () => {\n }, err => {\n console.error('Error loading module:', modulePath, err);\n this.notifyError('Module load error: ' + err.toString());\n });\n });\n } catch (error) {\n console.error('Exception in loadModule:', modulePath);\n console.error(error);\n this.notifyError('Error in require call: ' + error.toString());\n }\n },\n\n\t notifyReady: function() {\n\t window.parent.postMessage({\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: this.responseIdentifier,\n\t method: 'iframeReady'\n\t }, '*');\n\t },\n\n\t notifyInteractionChanged: function(response, state) {\n\t window.parent.postMessage({\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: this.responseIdentifier,\n\t method: 'interactionChanged',\n\t params: { value: response, state: state }\n\t }, '*');\n\t },\n\n\t notifyError: function(message) {\n\t console.error('PCI Error:', message);\n\t window.parent.postMessage({\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: this.responseIdentifier,\n\t method: 'error',\n\t params: { message: message }\n\t }, '*');\n\t },\n\n setMarkup: function(markupHtml) {\n if (!this.container) {\n this.container = document.getElementById('pci-container');\n }\n if (!this.container) {\n this.pendingMarkup = markupHtml;\n return;\n }\n this.markupEl = this.container.querySelector('qti-interaction-markup');\n if (!this.markupEl) {\n this.markupEl = document.createElement('qti-interaction-markup');\n this.container.appendChild(this.markupEl);\n }\n this.markupEl.classList.add('qti-customInteraction');\n this.markupEl.innerHTML = markupHtml || '';\n },\n\n setProperties: function(propertiesHtml) {\n if (!this.container) {\n this.container = document.getElementById('pci-container');\n }\n if (!this.container) {\n this.pendingProperties = propertiesHtml;\n return;\n }\n this.propertiesEl = this.container.querySelector('properties');\n if (!this.propertiesEl) {\n this.propertiesEl = document.createElement('properties');\n this.container.appendChild(this.propertiesEl);\n }\n this.propertiesEl.style.display = 'none';\n this.propertiesEl.innerHTML = propertiesHtml || '';\n },\n\n applyBoundTo: function(boundTo) {\n if (!this.pciInstance || typeof this.pciInstance.setResponse !== 'function') return;\n const value = boundTo && (boundTo[this.responseIdentifier] || boundTo[Object.keys(boundTo)[0]]);\n if (value) this.pciInstance.setResponse(value);\n },\n };\n\n\t // Set up message listener for communication with parent\n\t let expectedParentOrigin = null;\n\t window.addEventListener('message', function(event) {\n\t const { data } = event;\n\n\t // Ensure the message is from our parent\n\t if (event.source !== window.parent || !data || data.source !== 'qti-portable-custom-interaction') {\n\t return;\n\t }\n\t if (expectedParentOrigin === null) {\n\t expectedParentOrigin = event.origin;\n\t } else if (event.origin !== expectedParentOrigin) {\n\t return;\n\t }\n\n function deepQuerySelector(root, selector) {\n if (!root) return null;\n try {\n const direct = root.querySelector ? root.querySelector(selector) : null;\n if (direct) return direct;\n } catch (e) {\n // ignore invalid selector for this root\n }\n if (!root.querySelectorAll) return null;\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if (node && node.shadowRoot) {\n const found = deepQuerySelector(node.shadowRoot, selector);\n if (found) return found;\n }\n }\n return null;\n }\n\n function deepFindElementByExactText(root, text) {\n if (!root || !text) return null;\n if (root.querySelectorAll) {\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if ((node.textContent || '').trim() === text) return node;\n if (node.shadowRoot) {\n const found = deepFindElementByExactText(node.shadowRoot, text);\n if (found) return found;\n }\n }\n }\n return null;\n }\n\n switch(data.method) {\n case 'initialize':\n PCIManager.initialize(data.params);\n break;\n\n case 'setMarkup':\n PCIManager.setMarkup(data.params);\n break;\n\n case 'setBoundTo':\n if (PCIManager.pciInstance) {\n PCIManager.applyBoundTo(data.params);\n } else {\n PCIManager.pendingBoundTo = data.params;\n }\n break;\n\n case 'setProperties':\n PCIManager.setProperties(data.params);\n break;\n\n case 'setState':\n if (PCIManager.pciInstance && typeof PCIManager.pciInstance.setState === 'function') {\n PCIManager.pciInstance.setState((data.params && data.params.state) || data.params);\n } else {\n PCIManager.pendingState = (data.params && data.params.state) || data.params;\n }\n break;\n\n case 'getContent': {\n const messageId = data.params && data.params.messageId;\n const collectShadowHtml = root => {\n const parts = [];\n if (!root || !root.querySelectorAll) return parts;\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if (node && node.shadowRoot) {\n parts.push(node.shadowRoot.innerHTML || '');\n parts.push(...collectShadowHtml(node.shadowRoot));\n }\n }\n return parts;\n };\n const shadowHtml = collectShadowHtml(document).join('\\\\n');\n\t window.parent.postMessage(\n\t {\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'getContentResponse',\n\t messageId: messageId,\n\t content: (document.documentElement ? document.documentElement.outerHTML : '') + '\\\\n' + shadowHtml\n\t },\n\t '*'\n\t );\n break;\n }\n\n case 'simulateClick': {\n const messageId = data.params && data.params.messageId;\n const x = data.params && data.params.x;\n const y = data.params && data.params.y;\n const el = typeof x === 'number' && typeof y === 'number' ? document.elementFromPoint(x, y) : null;\n\t if (el && typeof el.click === 'function') el.click();\n\t window.parent.postMessage(\n\t {\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'clickResponse',\n\t messageId: messageId\n\t },\n\t '*'\n\t );\n\t break;\n\t }\n\n case 'clickOnSelector': {\n const messageId = data.params && data.params.messageId;\n const selector = data.params && data.params.selector;\n const el = selector ? deepQuerySelector(document, selector) : null;\n\t const success = !!el;\n\t if (el && typeof el.click === 'function') el.click();\n\t window.parent.postMessage(\n\t {\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'clickSelectorResponse',\n\t messageId: messageId,\n\t success: success\n\t },\n\t '*'\n\t );\n\t break;\n\t }\n\n case 'clickOnElementByText': {\n const messageId = data.params && data.params.messageId;\n const text = data.params && data.params.text;\n const target = text ? deepFindElementByExactText(document, text) : null;\n\t const success = !!target;\n\t if (target && typeof target.click === 'function') target.click();\n\t window.parent.postMessage(\n\t {\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'clickTextResponse',\n\t messageId: messageId,\n\t success: success\n\t },\n\t '*'\n\t );\n\t break;\n\t }\n\n case 'setValueElement': {\n const messageId = data.params && data.params.messageId;\n const selector = data.params && data.params.selector;\n const value = data.params && data.params.value;\n const el = selector ? deepQuerySelector(document, selector) : null;\n let success = false;\n if (el && 'value' in el) {\n try {\n el.value = value;\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n success = true;\n } catch (e) {\n success = false;\n }\n\t }\n\t window.parent.postMessage(\n\t {\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'setValueResponse',\n\t messageId: messageId,\n\t success: success\n\t },\n\t '*'\n\t );\n\t break;\n\t }\n }\n });\n\n let resizeTimeout;\n let previousHeight = 0;\n const notifyResize = () => {\n const container = document.getElementById('pci-container');\n const newHeight = container.scrollHeight + 100;\n if (newHeight !== previousHeight) {\n previousHeight = newHeight;\n clearTimeout(resizeTimeout);\n\t resizeTimeout = setTimeout(() => {\n\t window.parent.postMessage({\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'resize',\n\t height: newHeight,\n\t width: container.scrollWidth\n\t }, '*');\n\t }, 100); // Adjust debounce time as needed\n }\n };\n\n function setupResizeObserver() {\n const container = document.getElementById('pci-container');\n if (!container || !(container instanceof Element)) {\n console.warn('ResizeObserver: document.container is not an Element');\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n notifyResize();\n });\n\n resizeObserver.observe(container);\n }\n\n // Run setup once DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n notifyResize(); // initial resize\n setupResizeObserver();\n });\n } else {\n notifyResize();\n setupResizeObserver();\n }\n\n window.addEventListener('load', () => {\n notifyResize();\n });\n let lastResponseStr = '';\n setInterval(() => {\n if (PCIManager.interactionChangedViaEvent) return;\n if (PCIManager.pciInstance && PCIManager.pciInstance.getResponse) {\n const response = PCIManager.pciInstance.getResponse();\n\t if (response === undefined) {\n\t // Don't emit an initial empty on load; only emit a clear if we previously had a value\n\t if (!PCIManager.hadResponse) return;\n\t PCIManager.hadResponse = false;\n\t PCIManager.lastResponseStr = null;\n\t const state = PCIManager.pciInstance && typeof PCIManager.pciInstance.getState === 'function' ? PCIManager.pciInstance.getState() : null;\n\t window.parent.postMessage(\n\t {\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'interactionChanged',\n\t params: { value: null, state: state }\n\t },\n\t '*'\n\t );\n\t return;\n\t }\n\n const responseStr = JSON.stringify(response);\n\n\t if (responseStr !== PCIManager.lastResponseStr) {\n\t PCIManager.lastResponseStr = responseStr;\n\t PCIManager.hadResponse = true;\n\t const state = PCIManager.pciInstance && typeof PCIManager.pciInstance.getState === 'function' ? PCIManager.pciInstance.getState() : null;\n\t window.parent.postMessage(\n\t {\n\t source: 'qti-pci-iframe',\n\t responseIdentifier: PCIManager.responseIdentifier,\n\t method: 'interactionChanged',\n\t params: { value: response, state: state }\n\t },\n\t '*'\n\t );\n\t }\n }\n }, 500); // Check every 500ms\n </script>\n</head>\n<body>\n <div id=\"pci-container\"></div>\n</body>\n</html>`;\n }\n\n /**\n * Toggle the display of the correct response\n * @param responseVariable The response variable containing the correct response\n * @param show Whether to show or hide the correct response\n */\n public override toggleInternalCorrectResponse(show: boolean) {\n const responseVariable = this.responseVariable;\n\n // Store the correct response or clear it based on the show parameter\n this.correctResponse = show\n ? responseVariable?.correctResponse\n : responseVariable.cardinality === 'single'\n ? ''\n : [];\n\n // Get unique identifiers for this PCI's correct response elements\n const containerId = `correct-response-container-${this.responseIdentifier}`;\n\n // Check the parent element for any existing containers with this ID\n const existingContainers = this.parentElement?.querySelectorAll(`#${containerId}`);\n if (existingContainers) {\n existingContainers.forEach(existingContainer => {\n existingContainer.remove();\n });\n }\n\n // Handle the current interaction's state\n if (show) {\n // Disable the current interaction when showing correct response\n this.disable();\n } else {\n // Enable the current interaction when hiding correct response\n this.enable();\n return; // Exit early, nothing else to do\n }\n\n // If there's no correct response to show, exit\n if (!show || !responseVariable?.correctResponse) {\n return;\n }\n\n // Create a container for the correct response viewer\n const correctResponseContainer = document.createElement('div');\n correctResponseContainer.id = containerId;\n correctResponseContainer.className = 'pci-correct-response-container';\n correctResponseContainer.style.position = 'relative';\n correctResponseContainer.style.marginTop = '20px';\n correctResponseContainer.style.border = '2px solid green';\n correctResponseContainer.style.padding = '16px';\n correctResponseContainer.style.borderRadius = '4px';\n correctResponseContainer.style.backgroundColor = 'rgba(0, 128, 0, 0.05)';\n\n // Add a label for the correct response\n const label = document.createElement('div');\n label.textContent = 'Correct Response:';\n label.style.fontWeight = 'bold';\n label.style.marginBottom = '10px';\n label.style.color = 'green';\n correctResponseContainer.appendChild(label);\n\n // Instead of cloning, we'll create a new instance and copy necessary attributes\n const correctResponseViewer = document.createElement(\n 'qti-portable-custom-interaction'\n ) as QtiPortableCustomInteraction;\n\n // Copy all attributes from the original PCI\n Array.from(this.attributes).forEach(attr => {\n if (attr.name !== 'id' && attr.name !== 'response-identifier') {\n correctResponseViewer.setAttribute(attr.name, attr.value);\n }\n });\n\n // Set a unique response identifier to avoid conflicts\n const originalResponseId = this.responseIdentifier;\n correctResponseViewer.responseIdentifier = `${originalResponseId}-correct`;\n\n // Copy any light DOM content from the original PCI\n // This includes markup and properties\n Array.from(this.children).forEach(child => {\n const clonedChild = child.cloneNode(true);\n correctResponseViewer.appendChild(clonedChild);\n });\n\n // Store the correct response value\n const correctResponseValue = responseVariable.correctResponse;\n\n // Ensure the correct-response viewer is initialized and then configured in the iframe\n const originalConnectedCallback = correctResponseViewer.connectedCallback;\n correctResponseViewer.connectedCallback = function () {\n originalConnectedCallback.call(this);\n\n const checkIframeLoaded = () => {\n if (!this._iframeLoaded) return false;\n\n // Set response after a small delay to ensure PCI is ready\n setTimeout(() => {\n const qtiVariableJSON = this.responseVariablesToQtiVariableJSON(\n correctResponseValue,\n responseVariable.cardinality,\n responseVariable.baseType\n );\n\n this.sendMessageToIframe('setBoundTo', {\n [originalResponseId]: qtiVariableJSON\n });\n this.sendMessageToIframe('setState', { state: 'review' });\n }, 1000);\n\n return true;\n };\n\n if (!checkIframeLoaded()) {\n const intervalId = setInterval(() => {\n if (checkIframeLoaded()) clearInterval(intervalId);\n }, 100);\n\n setTimeout(() => {\n clearInterval(intervalId);\n }, 10000);\n }\n };\n\n // Make sure the viewer is not interactive\n correctResponseViewer.style.pointerEvents = 'none';\n\n // Add the correct response viewer to the container\n correctResponseContainer.appendChild(correctResponseViewer);\n\n // Append the container after this PCI\n this.after(correctResponseContainer);\n }\n /**\n * Method to disable the PCI for review mode\n * This can be used when showing the correct response\n */\n public disable() {\n // First, store the current state of the PCI\n this._previousState = {\n pointerEvents: this.style.pointerEvents,\n position: this.style.position\n };\n\n this.sendMessageToIframe('setState', { state: 'disabled' });\n\n // Add an overlay to prevent interaction if not already there\n const existingOverlay = this.querySelector('.pci-interaction-overlay');\n if (!existingOverlay) {\n const overlay = document.createElement('div');\n overlay.className = 'pci-interaction-overlay';\n overlay.style.position = 'absolute';\n overlay.style.top = '0';\n overlay.style.left = '0';\n overlay.style.width = '100%';\n overlay.style.height = '100%';\n overlay.style.backgroundColor = 'rgba(200, 200, 200, 0.3)';\n overlay.style.zIndex = '100';\n overlay.style.pointerEvents = 'all';\n overlay.style.cursor = 'not-allowed';\n\n // Make sure the container is relatively positioned\n if (getComputedStyle(this).position === 'static') {\n this.style.position = 'relative';\n }\n\n this.appendChild(overlay);\n }\n }\n\n /**\n * Method to enable the PCI for interactive mode\n */\n public enable() {\n // Remove any overlays\n const overlay = this.querySelector('.pci-interaction-overlay');\n if (overlay) {\n overlay.remove();\n }\n\n // Restore previous state if available\n if (this._previousState) {\n if (this._previousState.pointerEvents) {\n this.style.pointerEvents = this._previousState.pointerEvents;\n }\n if (this._previousState.position) {\n this.style.position = this._previousState.position;\n }\n this._previousState = null;\n }\n\n this.sendMessageToIframe('setState', { state: 'interacting' });\n }\n\n // Add this property to store the previous state\n private _previousState: {\n pointerEvents?: string;\n position?: string;\n } = null;\n\n override render() {\n return html`\n <slot></slot>\n ${this._errorMessage\n ? html`<div style=\"color:red\">\n <h1>Error</h1>\n ${this._errorMessage}\n </div>`\n : ''}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-portable-custom-interaction': QtiPortableCustomInteraction;\n }\n}\n","import { LitElement, css, html } from 'lit';\n\nexport class QtiPositionObjectInteraction extends LitElement {\n override render() {\n return html`<slot></slot>`;\n }\n\n static override styles = [\n css`\n :host {\n display: block;\n }\n ::slotted(img) {\n position: absolute;\n cursor: move;\n user-select: none;\n left: 50%;\n transform: translateX(-50%);\n }\n `\n ];\n}\n","import { LitElement, css, html } from 'lit';\n\nimport type { PropertyValueMap } from 'lit';\nexport class QtiPositionObjectStage extends LitElement {\n choiceOrdering: boolean;\n startX: any;\n startY: any;\n dragElement: any;\n\n override render() {\n return html`<slot></slot>`;\n }\n\n static override styles = [\n css`\n :host {\n display: inline-block;\n position: relative;\n }\n `\n ];\n\n constructor() {\n super();\n this.removeMoveListener = this.removeMoveListener.bind(this);\n this.dragElementHandler = this.dragElementHandler.bind(this);\n }\n\n // Define a function to handle the mousemove event on the draggable element\n dragElementHandler(event: MouseEvent): void {\n event.preventDefault();\n\n // Calculate the distance the mouse has moved since the last event\n const deltaX: number = event.clientX - this.startX;\n const deltaY: number = event.clientY - this.startY;\n\n // Update the position of the draggable element\n this.dragElement.style.left = this.dragElement.offsetLeft + deltaX + 'px';\n this.dragElement.style.top = this.dragElement.offsetTop + deltaY + 'px';\n\n // Update the starting position of the mouse\n this.startX = event.clientX;\n this.startY = event.clientY;\n }\n\n override firstUpdated(a: PropertyValueMap<any>): void {\n super.firstUpdated(a);\n\n // Get the draggable and drop zone elements\n this.dragElement = this.querySelector('qti-position-object-interaction>img');\n // const canvasElement = document.getElementById('canvas');\n\n // Initialize variables for the starting position of the draggable element\n this.startX = 0;\n this.startY = 0;\n\n // Add a mousedown event listener to the draggable element\n this.dragElement.addEventListener('mousedown', (event: MouseEvent) => {\n // Save the starting position of the mouse\n this.startX = event.clientX;\n this.startY = event.clientY;\n\n // Add a mousemove event listener to the document\n document.addEventListener('mousemove', this.dragElementHandler, true);\n });\n document.addEventListener('mouseup', this.removeMoveListener);\n }\n\n removeMoveListener() {\n document.removeEventListener('mousemove', this.dragElementHandler, true);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('mousemove', this.dragElementHandler);\n document.removeEventListener('mouseup', this.removeMoveListener);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-position-object-stage': QtiPositionObjectStage;\n }\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {AttributePart, noChange} from '../lit-html.js';\nimport {\n directive,\n Directive,\n DirectiveParameters,\n PartInfo,\n PartType,\n} from '../directive.js';\n\n/**\n * A key-value set of CSS properties and values.\n *\n * The key should be either a valid CSS property name string, like\n * `'background-color'`, or a valid JavaScript camel case property name\n * for CSSStyleDeclaration like `backgroundColor`.\n */\nexport interface StyleInfo {\n [name: string]: string | number | undefined | null;\n}\n\nconst important = 'important';\n// The leading space is important\nconst importantFlag = ' !' + important;\n// How many characters to remove from a value, as a negative number\nconst flagTrim = 0 - importantFlag.length;\n\nclass StyleMapDirective extends Directive {\n private _previousStyleProperties?: Set<string>;\n\n constructor(partInfo: PartInfo) {\n super(partInfo);\n if (\n partInfo.type !== PartType.ATTRIBUTE ||\n partInfo.name !== 'style' ||\n (partInfo.strings?.length as number) > 2\n ) {\n throw new Error(\n 'The `styleMap` directive must be used in the `style` attribute ' +\n 'and must be the only part in the attribute.'\n );\n }\n }\n\n render(styleInfo: Readonly<StyleInfo>) {\n return Object.keys(styleInfo).reduce((style, prop) => {\n const value = styleInfo[prop];\n if (value == null) {\n return style;\n }\n // Convert property names from camel-case to dash-case, i.e.:\n // `backgroundColor` -> `background-color`\n // Vendor-prefixed names need an extra `-` appended to front:\n // `webkitAppearance` -> `-webkit-appearance`\n // Exception is any property name containing a dash, including\n // custom properties; we assume these are already dash-cased i.e.:\n // `--my-button-color` --> `--my-button-color`\n prop = prop.includes('-')\n ? prop\n : prop\n .replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, '-$&')\n .toLowerCase();\n return style + `${prop}:${value};`;\n }, '');\n }\n\n override update(part: AttributePart, [styleInfo]: DirectiveParameters<this>) {\n const {style} = part.element as HTMLElement;\n\n if (this._previousStyleProperties === undefined) {\n this._previousStyleProperties = new Set(Object.keys(styleInfo));\n return this.render(styleInfo);\n }\n\n // Remove old properties that no longer exist in styleInfo\n for (const name of this._previousStyleProperties) {\n // If the name isn't in styleInfo or it's null/undefined\n if (styleInfo[name] == null) {\n this._previousStyleProperties!.delete(name);\n if (name.includes('-')) {\n style.removeProperty(name);\n } else {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (style as any)[name] = null;\n }\n }\n }\n\n // Add or update properties\n for (const name in styleInfo) {\n const value = styleInfo[name];\n if (value != null) {\n this._previousStyleProperties.add(name);\n const isImportant =\n typeof value === 'string' && value.endsWith(importantFlag);\n if (name.includes('-') || isImportant) {\n style.setProperty(\n name,\n isImportant\n ? (value as string).slice(0, flagTrim)\n : (value as string),\n isImportant ? important : ''\n );\n } else {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (style as any)[name] = value;\n }\n }\n }\n return noChange;\n }\n}\n\n/**\n * A directive that applies CSS properties to an element.\n *\n * `styleMap` can only be used in the `style` attribute and must be the only\n * expression in the attribute. It takes the property names in the\n * {@link StyleInfo styleInfo} object and adds the properties to the inline\n * style of the element.\n *\n * Property names with dashes (`-`) are assumed to be valid CSS\n * property names and set on the element's style object using `setProperty()`.\n * Names without dashes are assumed to be camelCased JavaScript property names\n * and set on the element's style object using property assignment, allowing the\n * style object to translate JavaScript-style names to CSS property names.\n *\n * For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size':\n * '0'})` sets the `background-color`, `border-top` and `--size` properties.\n *\n * @param styleInfo\n * @see {@link https://lit.dev/docs/templates/directives/#stylemap styleMap code samples on Lit.dev}\n */\nexport const styleMap = directive(StyleMapDirective);\n\n/**\n * The type of the class that powers this directive. Necessary for naming the\n * directive's return type.\n */\nexport type {StyleMapDirective};\n","import { css, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport { Interaction } from '@qti-components/base';\nimport { ScoringHelper } from '@qti-components/base';\n\nimport { positionShapes } from '../../internal/hotspots/hotspot.js';\n\nimport type { QtiAreaMapEntry, QtiAreaMapping } from '@qti-components/base';\nexport class QtiSelectPointInteraction extends Interaction {\n static override styles = [\n css`\n :host {\n display: block;\n }\n point-container {\n display: block;\n position: relative;\n width: fit-content;\n }\n\n ::slotted(img) {\n max-width: 100%;\n height: auto;\n display: block;\n }\n `\n ];\n\n @property({\n type: Number,\n attribute: 'max-choices'\n })\n public maxChoices: number = Infinity;\n\n @property({\n type: Number,\n attribute: 'min-choices'\n })\n public minChoices: number = 0;\n\n @state() response: string[] | null = null;\n\n @state()\n private _correctAreas: { shape: string; coords: string }[] = [];\n\n @state()\n private _responseCorrection: boolean[] = [];\n\n // Reference to the image element\n private _imgElement: HTMLImageElement | null = null;\n\n private _scaleX = 1;\n private _scaleY = 1;\n private _imageWidthOriginal = 0;\n private _imageHeightOriginal = 0;\n\n // Extracted click handler method\n private _onImageClick = (event: MouseEvent) => {\n if (this.disabled) {\n return;\n }\n if (!this._imgElement) {\n console.warn('No <img> element found in <qti-select-point-interaction>');\n return;\n }\n this.calculateScale();\n // Get the image's bounding rectangle and calculate scaling factors\n const rect = this._imgElement.getBoundingClientRect();\n\n // Calculate the x and y coordinates relative to the original image size\n const x = (event.clientX - rect.left) * this._scaleX;\n const y = (event.clientY - rect.top) * this._scaleY;\n\n // Save the new point as a string\n const newPoint = `${x.toFixed()} ${y.toFixed()}`;\n\n if (this.maxChoices === 1) {\n // If maxChoices is 1, replace the existing marker with the new one\n this.response = [newPoint];\n } else {\n // If maxChoices > 1, add a new marker if within the limit\n if (this.maxChoices === 0 || (this.response || []).length < this.maxChoices) {\n this.response = [...(this.response || []), newPoint];\n } else {\n // Optional: Notify the user to remove a marker before adding a new one\n // console.warn('Maximum number of points reached. Remove a marker to add a new one.');\n }\n }\n // Save the response with the calculated points\n this.saveResponse(this.response);\n };\n\n override connectedCallback() {\n super.connectedCallback();\n window.addEventListener('resize', this._onResize);\n }\n\n private _onResize = () => {\n this.calculateScale();\n };\n\n get responsePoints() {\n return (this.response || [])\n .filter(point => point)\n .map(point => {\n const [x, y] = point.split(' ').map(Number);\n return { x, y };\n });\n }\n\n public override toggleCandidateCorrection(show: boolean) {\n this._responseCorrection = [];\n if (!show) {\n return;\n }\n this.responsePoints.forEach(point => {\n const correct = (this.responseVariable.areaMapping as QtiAreaMapping).areaMapEntries.some(correctArea =>\n ScoringHelper.isPointInArea(\n `${point.x} ${point.y}`,\n `${correctArea.shape},${correctArea.coords}`,\n this.responseVariable.baseType\n )\n );\n this._responseCorrection.push(correct);\n });\n }\n\n public override toggleCorrectResponse(show: boolean) {\n const responseVariable = this.responseVariable;\n if (!show || !responseVariable) {\n this._correctAreas = [];\n return;\n }\n // Find the area mapping element from the response variable\n const areaMapping = responseVariable.areaMapping as QtiAreaMapping;\n let areaMapEntries: QtiAreaMapEntry[] = [];\n if (!areaMapping || areaMapping.areaMapEntries.length === 0) {\n if (responseVariable.correctResponse) {\n const correctResponses = Array.isArray(responseVariable.correctResponse)\n ? responseVariable.correctResponse\n : [responseVariable.correctResponse];\n if (correctResponses.length === 0 || correctResponses.find(r => r.split(' ').length < 2)) {\n console.error('No valid correct responses found for the response variable.');\n return null;\n }\n console.warn(\n `No area mapping found for the response variable. Using the correct responses to display the correct response but it probably won't score correct.`\n );\n // Create a new area mapping object with the correct responses\n areaMapEntries = correctResponses.map(r => {\n const coords = r.split(' ').join(',').concat(',10'); // Add a radius of 10 pixels to the coordinates\n return { shape: 'circle', coords, defaultValue: 1, mappedValue: 1 };\n });\n } else {\n console.error('No area mapping found for the response variable.');\n return;\n }\n } else {\n // Get all map entries from the area mapping\n areaMapEntries = areaMapping.areaMapEntries;\n }\n this._correctAreas = areaMapEntries.map(e => ({ coords: e.coords, shape: e.shape }));\n }\n\n override updated(changedProperties: Map<string | number | symbol, unknown>) {\n super.updated(changedProperties);\n const img = this._imgElement;\n if (img && changedProperties.has('_correctAreas') && this._correctAreas.length > 0) {\n this.calculateScale();\n this.shadowRoot.querySelectorAll('div').forEach((el: HTMLElement) => {\n const coords = el.dataset.coord;\n const shape = el.dataset.shape;\n if (coords && shape) {\n positionShapes(\n shape,\n coords.split(',').map(c => +c),\n img,\n el\n );\n }\n });\n }\n }\n\n override render() {\n return html` <slot name=\"prompt\"></slot>\n <point-container>\n ${repeat(\n (this.response || []).filter(point => point),\n point => point,\n (point, index) => {\n const [x, y] = point.split(' ').map(Number);\n // point are based on the original image size, so we need calculate the percentage based on the original image\n const leftPercentage = (x / (this._imageWidthOriginal || 1)) * 100;\n const topPercentage = (y / (this._imageHeightOriginal || 1)) * 100;\n\n // Base size is 1rem (16px), scaled proportionally to the image's current size\n // Base size is 1rem in the original image size\n const baseSize = 16; // Assuming 1rem = 16px\n const widthPercentage = (baseSize / (this._imageWidthOriginal || 1)) * 100;\n const heightPercentage = (baseSize / (this._imageHeightOriginal || 1)) * 100;\n\n let correctionPart = '';\n if (this._responseCorrection[index] === true) {\n correctionPart = ' correct';\n } else if (this._responseCorrection[index] === false) {\n correctionPart = ' incorrect';\n }\n\n return html`\n <button\n part=\"point${correctionPart}\"\n style=${styleMap({\n pointerEvents: this.maxChoices === 1 ? 'none' : 'auto',\n position: 'absolute',\n transform: 'translate(-50%, -50%)',\n left: `${leftPercentage}%`,\n top: `${topPercentage}%`,\n width: `min(${widthPercentage}%, 1rem)`,\n height: `min(${heightPercentage}%, 1rem)`,\n minWidth: `min(${widthPercentage}%, 1rem)`,\n minHeight: `min(${heightPercentage}%, 1rem)`,\n borderRadius: '50%', // Ensures round shape\n background: 'red' // Example styling, adjust as needed\n })}\n aria-label=\"Remove point at ${point}\"\n ?disabled=${this.disabled}\n @click=${(e: Event) => {\n e.stopPropagation();\n this.response = (this.response || []).filter((_, i) => i !== index);\n this.saveResponse(this.response);\n }}\n ></button>\n `;\n }\n )}\n ${repeat(\n this._correctAreas?.filter(area => area) || [],\n area => area,\n (area, i) =>\n html`<div\n style=${styleMap({\n position: 'absolute',\n pointerEvents: 'none',\n backgroundColor: 'var(--qti-correct)',\n opacity: '0.5'\n })}\n data-coord=\"${area.coords}\"\n alt=${`correct-response-${i + 1}`}\n data-shape=\"${area.shape}\"\n ></div>`\n )}\n <slot></slot>\n </point-container>`;\n }\n\n validate(): boolean {\n return this.response !== null && this.response.length >= this.minChoices && this.response.length <= this.maxChoices;\n }\n\n private calculateScale() {\n // Get the image dimensions\n this._imageWidthOriginal = this._imgElement.getAttribute('width')\n ? parseFloat(this._imgElement.getAttribute('width')!)\n : this._imgElement.naturalWidth;\n this._imageHeightOriginal = this._imgElement.getAttribute('height')\n ? parseFloat(this._imgElement.getAttribute('height')!)\n : this._imgElement.naturalHeight;\n // Get the image's bounding rectangle and calculate scaling factors\n const rect = this._imgElement.getBoundingClientRect();\n this._scaleX = rect.width === 0 ? 1 : this._imageWidthOriginal / rect.width; // Horizontal scaling factor\n this._scaleY = rect.height === 0 ? 1 : this._imageHeightOriginal / rect.height; // Vertical scaling factor\n }\n\n override firstUpdated(): void {\n this._imgElement = this.querySelector('img');\n\n if (this._imgElement) {\n this.calculateScale();\n // Attach the click event listener to the image element\n this._imgElement.addEventListener('click', this._onImageClick);\n } else {\n console.warn('No <img> element found in <qti-select-point-interaction>');\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n\n window.removeEventListener('resize', this._onResize);\n if (this._imgElement) {\n // Remove the click event listener from the image element\n this._imgElement.removeEventListener('click', this._onImageClick);\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-select-point-interaction': QtiSelectPointInteraction;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: block;\n --show-bounds: true;\n --show-ticks: true;\n --show-value: true;\n }\n\n [part='slider'] {\n margin-left: 2rem; /* mx-8 */\n margin-right: 2rem;\n padding-bottom: 1rem; /* pb-4 */\n padding-top: 1.25rem; /* pt-5 */\n }\n\n [part='bounds'] {\n display: flex;\n width: 100%;\n justify-content: space-between;\n margin-bottom: 0.5rem; /* mb-2 */\n }\n\n [part='ticks'] {\n margin-left: 0.125rem; /* mx-0.5 */\n margin-right: 0.125rem;\n margin-bottom: 0.25rem; /* mb-1 */\n height: 0.5rem; /* h-2 */\n background: linear-gradient(to right, var(--qti-border-color) var(--qti-border-thickness), transparent 1px) repeat-x\n 0 center / calc(calc(100% - var(--qti-border-thickness)) / ((var(--max) - var(--min)) / var(--step))) 100%;\n }\n\n [part='rail'] {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n height: 0.375rem; /* h-1.5 */\n width: 100%;\n cursor: pointer;\n border-radius: 9999px; /* rounded-full */\n border: 1px solid #d1d5db; /* border-gray-300 */\n background-color: #e5e7eb; /* bg-gray-200 */\n }\n\n [part='knob'] {\n background-color: var(--qti-bg-active);\n border: 2px solid var(--qti-border-active);\n position: relative;\n height: 1rem; /* h-4 */\n width: 1rem; /* w-4 */\n transform-origin: center;\n transform: translateX(-50%);\n cursor: pointer;\n border-radius: 9999px; /* rounded-full */\n left: var(--value-percentage);\n }\n [part='knob-correct'] {\n background-color: var(--qti-correct-light);\n border: 2px solid var(--qti-correct);\n position: relative;\n height: 1rem; /* h-4 */\n width: 1rem; /* w-4 */\n transform-origin: center;\n transform: translateX(-50%);\n cursor: pointer;\n border-radius: 9999px; /* rounded-full */\n left: var(--value-percentage-correct);\n }\n\n [part='value'] {\n position: absolute;\n bottom: 2rem; /* bottom-8 */\n left: 0.5rem; /* left-2 */\n transform: translateX(-50%);\n cursor: pointer;\n border-radius: 0.25rem; /* rounded */\n background-color: #f3f4f6; /* bg-gray-100 */\n padding: 0.25rem 0.5rem; /* px-2 py-1 */\n text-align: center;\n color: #6b7280; /* text-gray-500 */\n }\n`;\n","import { html } from 'lit';\nimport { property, query } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\n\nimport styles from './qti-slider-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nexport class QtiSliderInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\n\n private _value = 0;\n private _correctResponseNumber: number | null = null;\n\n @query('#rail') private _rail!: HTMLElement;\n\n @property({ type: Number, attribute: 'lower-bound' }) min = 0;\n @property({ type: Number, attribute: 'upper-bound' }) max = 100;\n @property({ type: Number, attribute: 'step' }) step = 1;\n\n validate(): boolean {\n return true;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n this._updateValue(this.min); // Set initial value\n this.setAttribute('tabindex', '0');\n this.setAttribute('role', 'slider');\n }\n\n get response(): string {\n return this._value.toString();\n }\n\n set response(val: string) {\n const newValue = parseInt(val, 10);\n if (!isNaN(newValue)) {\n this._updateValue(newValue);\n }\n }\n\n public override toggleCorrectResponse(show: boolean) {\n const responseVariable = this.responseVariable;\n if (!responseVariable?.correctResponse) return;\n\n if (show) {\n this._correctResponse = responseVariable.correctResponse.toString();\n const nr = parseFloat(responseVariable.correctResponse.toString());\n if (!isNaN(nr)) {\n this._correctResponseNumber = nr;\n const valuePercentage = ((this._correctResponseNumber - this.min) / (this.max - this.min)) * 100;\n this.style.setProperty('--value-percentage-correct', `${valuePercentage}%`);\n } else {\n this._correctResponseNumber = null;\n }\n } else {\n this._correctResponseNumber = null;\n }\n this.requestUpdate();\n }\n\n private _updateValue(newValue: number) {\n const oldValue = this._value;\n this._value = Math.min(this.max, Math.max(this.min, newValue));\n if (this._value === oldValue) {\n return; // Do not update if the value is the same as before\n }\n const valuePercentage = ((this._value - this.min) / (this.max - this.min)) * 100;\n this.style.setProperty('--value-percentage', `${valuePercentage}%`);\n this._internals.setFormValue(this.value); // Update form value\n this.saveResponse(this.response);\n this.requestUpdate();\n }\n\n override render() {\n return html`\n <slot name=\"prompt\"></slot>\n <div id=\"slider\" part=\"slider\">\n <div id=\"bounds\" part=\"bounds\">\n <div>${this.min}</div>\n <div>${this.max}</div>\n </div>\n\n <div id=\"ticks\" part=\"ticks\"></div>\n\n <div id=\"rail\" part=\"rail\" @mousedown=${this._onMouseDown} @touchstart=${this._onTouchStart}>\n <div id=\"knob\" part=\"knob\">\n <div id=\"value\" part=\"value\">${this.response}</div>\n </div>\n\n ${this._correctResponseNumber !== null\n ? html`\n <div id=\"knob-correct\" part=\"knob-correct\">\n <div id=\"value\" part=\"value\">${this._correctResponseNumber}</div>\n </div>\n `\n : null}\n </div>\n </div>\n `;\n }\n\n private _onMouseDown(event: MouseEvent) {\n this._startDrag(event.pageX);\n const handleMouseMove = (e: MouseEvent) => this._onDrag(e.pageX);\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n this._onDragEnd();\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n }\n\n private _onTouchStart(event: TouchEvent) {\n this._startDrag(event.touches[0].pageX);\n const handleTouchMove = (e: TouchEvent) => this._onDrag(e.touches[0].pageX);\n const handleTouchEnd = () => {\n document.removeEventListener('touchmove', handleTouchMove);\n document.removeEventListener('touchend', handleTouchEnd);\n this._onDragEnd();\n };\n\n document.addEventListener('touchmove', handleTouchMove, { passive: false });\n document.addEventListener('touchend', handleTouchEnd);\n }\n\n private _startDrag(pageX: number) {\n this._onDrag(pageX);\n }\n\n private _onDrag(pageX: number) {\n const railRect = this._rail.getBoundingClientRect();\n const diffX = pageX - railRect.left;\n const percentage = Math.min(1, Math.max(0, diffX / railRect.width));\n const steppedValue = this.min + Math.round((percentage * (this.max - this.min)) / this.step) * this.step;\n this._updateValue(steppedValue);\n }\n\n private _onDragEnd() {\n this.dispatchEvent(new Event('change', { bubbles: true }));\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-slider-interaction': QtiSliderInteraction;\n }\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nimport {nothing, ElementPart} from '../lit-html.js';\nimport {directive, AsyncDirective} from '../async-directive.js';\n\n/**\n * Creates a new Ref object, which is container for a reference to an element.\n */\nexport const createRef = <T = Element>() => new Ref<T>();\n\n/**\n * An object that holds a ref value.\n */\nclass Ref<T = Element> {\n /**\n * The current Element value of the ref, or else `undefined` if the ref is no\n * longer rendered.\n */\n readonly value?: T;\n}\n\nexport type {Ref};\n\ninterface RefInternal {\n value: Element | undefined;\n}\n\n// When callbacks are used for refs, this map tracks the last value the callback\n// was called with, for ensuring a directive doesn't clear the ref if the ref\n// has already been rendered to a new spot. It is double-keyed on both the\n// context (`options.host`) and the callback, since we auto-bind class methods\n// to `options.host`.\nconst lastElementForContextAndCallback = new WeakMap<\n object,\n WeakMap<Function, Element | undefined>\n>();\n\nexport type RefOrCallback<T = Element> = Ref<T> | ((el: T | undefined) => void);\n\nclass RefDirective extends AsyncDirective {\n private _element?: Element;\n private _ref?: RefOrCallback;\n private _context?: object;\n\n render(_ref?: RefOrCallback) {\n return nothing;\n }\n\n override update(part: ElementPart, [ref]: Parameters<this['render']>) {\n const refChanged = ref !== this._ref;\n if (refChanged && this._ref !== undefined) {\n // The ref passed to the directive has changed;\n // unset the previous ref's value\n this._updateRefValue(undefined);\n }\n if (refChanged || this._lastElementForRef !== this._element) {\n // We either got a new ref or this is the first render;\n // store the ref/element & update the ref value\n this._ref = ref;\n this._context = part.options?.host;\n this._updateRefValue((this._element = part.element));\n }\n return nothing;\n }\n\n private _updateRefValue(element: Element | undefined) {\n if (!this.isConnected) {\n element = undefined;\n }\n if (typeof this._ref === 'function') {\n // If the current ref was called with a previous value, call with\n // `undefined`; We do this to ensure callbacks are called in a consistent\n // way regardless of whether a ref might be moving up in the tree (in\n // which case it would otherwise be called with the new value before the\n // previous one unsets it) and down in the tree (where it would be unset\n // before being set). Note that element lookup is keyed by\n // both the context and the callback, since we allow passing unbound\n // functions that are called on options.host, and we want to treat\n // these as unique \"instances\" of a function.\n const context = this._context ?? globalThis;\n let lastElementForCallback =\n lastElementForContextAndCallback.get(context);\n if (lastElementForCallback === undefined) {\n lastElementForCallback = new WeakMap();\n lastElementForContextAndCallback.set(context, lastElementForCallback);\n }\n if (lastElementForCallback.get(this._ref) !== undefined) {\n this._ref.call(this._context, undefined);\n }\n lastElementForCallback.set(this._ref, element);\n // Call the ref with the new element value\n if (element !== undefined) {\n this._ref.call(this._context, element);\n }\n } else {\n (this._ref as RefInternal)!.value = element;\n }\n }\n\n private get _lastElementForRef() {\n return typeof this._ref === 'function'\n ? lastElementForContextAndCallback\n .get(this._context ?? globalThis)\n ?.get(this._ref)\n : this._ref?.value;\n }\n\n override disconnected() {\n // Only clear the box if our element is still the one in it (i.e. another\n // directive instance hasn't rendered its element to it before us); that\n // only happens in the event of the directive being cleared (not via manual\n // disconnection)\n if (this._lastElementForRef === this._element) {\n this._updateRefValue(undefined);\n }\n }\n\n override reconnected() {\n // If we were manually disconnected, we can safely put our element back in\n // the box, since no rendering could have occurred to change its state\n this._updateRefValue(this._element);\n }\n}\n\n/**\n * Sets the value of a Ref object or calls a ref callback with the element it's\n * bound to.\n *\n * A Ref object acts as a container for a reference to an element. A ref\n * callback is a function that takes an element as its only argument.\n *\n * The ref directive sets the value of the Ref object or calls the ref callback\n * during rendering, if the referenced element changed.\n *\n * Note: If a ref callback is rendered to a different element position or is\n * removed in a subsequent render, it will first be called with `undefined`,\n * followed by another call with the new element it was rendered to (if any).\n *\n * ```js\n * // Using Ref object\n * const inputRef = createRef();\n * render(html`<input ${ref(inputRef)}>`, container);\n * inputRef.value.focus();\n *\n * // Using callback\n * const callback = (inputElement) => inputElement.focus();\n * render(html`<input ${ref(callback)}>`, container);\n * ```\n */\nexport const ref = directive(RefDirective);\n\n/**\n * The type of the class that powers this directive. Necessary for naming the\n * directive's return type.\n */\nexport type {RefDirective};\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: inline-block;\n }\n\n :host(.qti-input-width-1) [part='input'] {\n width: 1.1rem;\n min-width: 1.1rem;\n }\n\n :host(.qti-input-width-2) [part='input'] {\n width: 2.3rem;\n min-width: 2.3rem;\n }\n\n :host(.qti-input-width-3) [part='input'] {\n width: 3.3rem;\n min-width: 3.3rem;\n }\n\n :host(.qti-input-width-4) [part='input'] {\n width: 4.2rem;\n min-width: 4.2rem;\n }\n\n :host(.qti-input-width-6) [part='input'] {\n width: 6.6rem;\n min-width: 6.6rem;\n }\n\n :host(.qti-input-width-10) [part='input'] {\n width: 8rem;\n min-width: 8rem;\n }\n\n :host(.qti-input-width-15) [part='input'] {\n width: 12rem;\n min-width: 12rem;\n }\n\n :host(.qti-input-width-20) [part='input'] {\n width: 17rem;\n min-width: 17rem;\n }\n\n :host(.qti-input-width-25) [part='input'] {\n width: 20rem;\n min-width: 20rem;\n }\n\n :host(.qti-input-width-30) [part='input'] {\n width: 24rem;\n min-width: 24rem;\n }\n\n :host(.qti-input-width-35) [part='input'] {\n width: 28rem;\n min-width: 28rem;\n }\n\n :host(.qti-input-width-40) [part='input'] {\n width: 32rem;\n min-width: 32rem;\n }\n\n :host(.qti-input-width-45) [part='input'] {\n width: 36rem;\n min-width: 36rem;\n }\n\n :host(.qti-input-width-50) [part='input'] {\n width: 40rem;\n min-width: 40rem;\n }\n\n :host(.qti-input-width-72) [part='input'] {\n width: 57rem;\n min-width: 57rem;\n }\n\n :host {\n position: relative;\n }\n input {\n anchor-name: --text-entry-input;\n z-index: 100;\n position: relative;\n }\n\n [part='correct'] {\n padding: var(--qti-padding-vertical) var(--qti-padding-horizontal);\n background-color: var(--qti-bg);\n z-index: 0;\n position: absolute;\n left: 0;\n right: 0;\n position-anchor: --text-entry-input;\n bottom: anchor(top);\n left: anchor(left);\n /* opacity: 1; */\n transition: all 1s;\n\n @starting-style {\n display: grid;\n /* opacity: 0; */\n bottom: 0;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { createRef } from 'lit/directives/ref.js';\n\nimport { watch } from '@qti-components/utilities';\nimport { Correctness, Interaction } from '@qti-components/base';\n\nimport styles from './qti-text-entry-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nexport class QtiTextEntryInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\n inputRef = createRef<HTMLInputElement>();\n\n @property({ type: Number, attribute: 'expected-length' }) expectedLength: number;\n\n @property({ type: String, attribute: 'pattern-mask' }) patternMask: string;\n\n @property({ type: String, attribute: 'placeholder-text' }) placeholderText: string;\n\n @property({ type: String, attribute: 'data-patternmask-message' }) dataPatternmaskMessage: string;\n\n @state()\n response: string | null = null;\n\n @query('input') private _input!: HTMLInputElement;\n\n @watch('response', { waitUntilFirstUpdate: true })\n protected _handleValueChange = () => {\n // const formData = new FormData();\n // formData.append(this.responseIdentifier, this.response);\n this._internals.setFormValue(this.value);\n this.validate();\n };\n\n override get value(): string | null {\n return this.response || null;\n }\n override set value(val: string | null) {\n this.response = val || null;\n }\n\n override get correctness(): Readonly<Correctness | null> {\n const responseVariable = this.responseVariable;\n\n if (!responseVariable) {\n return null;\n }\n\n if (responseVariable.value === null) {\n return Correctness.Incorrect;\n }\n\n if (responseVariable.mapping) {\n const maxScore = responseVariable.mapping.mapEntries.reduce<number>(\n (currentMax, mapEntry) => Math.max(mapEntry.mappedValue, currentMax),\n 0\n );\n for (const mapEntry of responseVariable.mapping.mapEntries) {\n let mapAnswer = mapEntry.mapKey;\n let responseAnswer = responseVariable.value as string;\n if (!mapEntry.caseSensitive) {\n mapAnswer = mapAnswer.toLowerCase();\n responseAnswer = responseAnswer.toLowerCase();\n }\n if (mapAnswer === responseAnswer) {\n if (mapEntry.mappedValue === maxScore) {\n return Correctness.Correct;\n }\n if (mapEntry.mappedValue <= (responseVariable.mapping.defaultValue || 0)) {\n return Correctness.Incorrect;\n }\n return Correctness.PartiallyCorrect;\n }\n }\n }\n\n // Fallback to the correct response\n\n return responseVariable.correctResponse === responseVariable.value ? Correctness.Correct : Correctness.Incorrect;\n }\n\n override get isInline(): boolean {\n return true;\n }\n\n public override validate(): boolean {\n if (!this._input) return false;\n if (this.patternMask && this.dataPatternmaskMessage) {\n // Clear any custom error if the this._input is valid\n this._internals.setValidity({});\n this._input.setCustomValidity(''); // Clear the custom message\n const isValid = this._input.checkValidity();\n if (!isValid) {\n // Set custom error if invalid\n this._internals.setValidity({ customError: true }, this.dataPatternmaskMessage);\n this._input.setCustomValidity(this.dataPatternmaskMessage); // Set custom message only if invalid\n }\n } else {\n const isValid = this._input.checkValidity();\n this._internals.setValidity(isValid ? {} : { customError: false });\n }\n return this.response !== '' && this._input.checkValidity();\n }\n\n public override toggleInternalCorrectResponse(show: boolean): void {\n const responseVariable = this.responseVariable;\n\n if (show && responseVariable?.correctResponse) {\n const text = responseVariable.correctResponse.toString();\n this._correctResponse = text;\n // if (text) {\n // if (!this._input.nextElementSibling?.classList.contains('correct-option')) {\n // const textSpan = document.createElement('span');\n // textSpan.classList.add('correct-option');\n // textSpan.textContent = text;\n\n // // Apply styles\n // textSpan.style.border = '1px solid var(--qti-correct)';\n // textSpan.style.borderRadius = '4px';\n // textSpan.style.padding = '2px 4px';\n // textSpan.style.margin = '4px';\n // textSpan.style.display = 'inline-block';\n\n // this._input.insertAdjacentElement('afterend', textSpan);\n // }\n // } else if (this._input.nextElementSibling?.classList.contains('correct-option')) {\n // this._input.nextElementSibling?.remove();\n // }\n } else {\n // this._input.nextElementSibling?.remove();\n this._correctResponse = null;\n }\n }\n\n override render() {\n return html`\n <input\n part=\"input\"\n name=\"${this.responseIdentifier}\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n @blur=\"${(_: FocusEvent) => {\n this.reportValidity();\n }}\"\n @keydown=\"${(event: KeyboardEvent) => event.stopImmediatePropagation()}\"\n @keyup=\"${this.textChanged}\"\n @change=\"${this.textChanged}\"\n type=\"${this.patternMask == '[0-9]*' ? 'number' : 'text'}\"\n placeholder=\"${ifDefined(this.placeholderText ? this.placeholderText : undefined)}\"\n .value=\"${this.response}\"\n pattern=\"${ifDefined(this.patternMask ? this.patternMask : undefined)}\"\n maxlength=${1000}\n ?disabled=\"${this.disabled}\"\n ?readonly=\"${this.readonly}\"\n />\n ${this._correctResponse ? html`<div part=\"correct\">${this._correctResponse}</div>` : nothing}\n `;\n }\n // ${this._correctResponse ? html`<div popover part=\"correct\">${this._correctResponse}</div>` : nothing}\n\n protected textChanged(event: Event): void {\n if (this.disabled || this.readonly) return;\n const input = event.target as HTMLInputElement;\n this.setEmptyAttribute(input.value);\n if (this.response !== input.value) {\n this.value = input.value;\n this.saveResponse(input.value);\n }\n }\n\n override reportValidity(): boolean {\n const input = this.shadowRoot.querySelector('input');\n if (!input) return false;\n\n // Run the validate function to ensure the custom validity state is up to date\n const isValid = this.validate();\n if (!isValid) {\n input.reportValidity();\n }\n return isValid;\n }\n\n override reset(): void {\n this.response = '';\n }\n\n private setEmptyAttribute(text: string): void {\n this.setAttribute('empty', text === '' ? 'true' : 'false');\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-text-entry-interaction': QtiTextEntryInteraction;\n }\n}\n","import { css, html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\nexport class QtiUploadInteraction extends Interaction {\n private _file: File | null = null;\n private _base64: string | null = null;\n\n override reset() {\n this._file = null;\n this._base64 = null;\n this.saveResponse(null);\n }\n\n validate(): boolean {\n return this._base64 !== null; // Ensure the Base64 string is set\n }\n\n get response(): string | null {\n return this._base64; // Return the Base64 string\n }\n\n set response(base64: string | null) {\n if (typeof base64 === 'string') {\n this._base64 = base64;\n this.saveResponse(base64); // Save Base64 string as the response\n } else if (base64 === null) {\n this.reset();\n } else {\n throw new Error('Value must be a Base64-encoded string or null');\n }\n }\n\n static override get properties() {\n return {\n ...Interaction.properties\n };\n }\n\n static override styles = [\n css`\n :host {\n display: block;\n margin: 1em 0;\n }\n input[type='file'] {\n display: block;\n margin-top: 0.5em;\n }\n `\n ];\n\n override render() {\n return html`\n <div>\n <slot name=\"prompt\"></slot>\n <input type=\"file\" @change=\"${this._onFileChange}\" ?disabled=\"${this.disabled}\" ?readonly=\"${this.readonly}\" />\n </div>\n `;\n }\n\n private async _onFileChange(event: Event) {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this._file = input.files[0];\n this._base64 = await this._convertToBase64(this._file);\n this.saveResponse(this._base64); // Save the Base64 string\n this.dispatchEvent(\n new CustomEvent('qti-interaction-response', {\n detail: { response: this._base64 }\n })\n );\n }\n }\n\n private _convertToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(file); // Converts to Base64\n });\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-upload-interaction': QtiUploadInteraction;\n }\n}\n","import { LitElement, css, html } from 'lit';\nexport class QtiAssociableHotspot extends LitElement {\n static override styles = css`\n :host {\n display: flex;\n user-select: none;\n position: absolute;\n }\n `;\n\n override connectedCallback() {\n super.connectedCallback();\n this.dispatchEvent(\n new CustomEvent('qti-register-hotspot', {\n bubbles: true,\n composed: true,\n cancelable: false\n })\n );\n }\n\n override render() {\n return html` <slot name=\"drags\"></slot> `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-associable-hotspot': QtiAssociableHotspot;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nexport class QtiGap extends LitElement {\n static override styles = css`\n :host {\n display: flex;\n user-select: none;\n }\n `;\n\n @property({ type: Number, reflect: true }) tabindex: number | undefined = 0;\n\n override render() {\n return html` <slot name=\"drags\"></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-gap': QtiGap;\n }\n}\n","import { css, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nexport class QtiGapImg extends LitElement {\n static override styles = css`\n :host {\n display: flex;\n user-select: none;\n }\n `;\n\n @property({ type: Number, reflect: true }) tabindex: number | undefined = 0;\n\n override connectedCallback() {\n this.setAttribute('slot', 'drags');\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-gap-img': QtiGapImg;\n }\n}\n","import { html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { watch } from '@qti-components/utilities';\n\nimport type { ComplexAttributeConverter, LitElement } from 'lit';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\nexport interface ChoiceInterface {\n identifier: string;\n disabled: boolean;\n readonly: boolean;\n}\n\n/**\n * Converter to handle boolean attributes for ARIA properties,\n * ensuring they are set as 'true' or 'false' strings.\n */\nconst ariaBooleanConverter: ComplexAttributeConverter<boolean, boolean> = {\n toAttribute: (value: boolean) => (value ? 'true' : 'false'),\n fromAttribute: (value: string | null) => value === 'true'\n};\n\n/**\n * A mixin that adds choice functionality to a LitElement-based class.\n * It dispatches events with a custom `type` and handles selection logic.\n *\n * @param Base - The base class to extend.\n * @param type - The type of the choice, used in event names.\n * @returns A new class extending the base class with choice functionality.\n */\nexport interface ActiveElementMixinInterface {\n identifier: string;\n tabIndex: number;\n disabled: boolean;\n readonly: boolean;\n internals: ElementInternals;\n}\n\nexport function ActiveElementMixin<T extends Constructor<LitElement>>(Base: T, type: string) {\n abstract class QtiChoice extends Base {\n @property({ type: String })\n public identifier = '';\n\n @property({ type: Number, reflect: true, attribute: 'tabindex' })\n public override tabIndex = 0;\n\n @property({\n type: Boolean,\n reflect: true,\n attribute: 'aria-disabled',\n converter: ariaBooleanConverter\n })\n public disabled = false;\n\n @property({\n type: Boolean,\n reflect: true,\n attribute: 'aria-readonly',\n converter: ariaBooleanConverter\n })\n public readonly = false;\n\n public internals: ElementInternals;\n\n @watch('disabled', { waitUntilFirstUpdate: true })\n handleDisabledChange(_oldValue: boolean, disabled: boolean) {\n this.tabIndex = disabled ? -1 : 0;\n if (disabled) {\n this.blur();\n }\n }\n\n constructor(...args: any[]) {\n super(...args);\n this.internals = this.attachInternals();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n\n // Initialize ARIA checked state\n this.internals.ariaChecked = 'false';\n\n // Set initial tabIndex based on disabled state\n if (this.disabled) {\n this.tabIndex = -1;\n }\n\n this.addEventListener('keyup', this._onKeyUp);\n this.addEventListener('click', this._onClick);\n\n this.dispatchEvent(\n new CustomEvent(`register-${type}`, {\n bubbles: true,\n composed: true\n })\n );\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('keyup', this._onKeyUp);\n this.removeEventListener('click', this._onClick);\n this.dispatchEvent(\n new CustomEvent(`unregister-${type}`, {\n bubbles: true,\n composed: true\n })\n );\n }\n\n private _onKeyUp(event: KeyboardEvent) {\n if (event.altKey) return;\n\n if (event.code === 'Space' || event.code === 'Enter') {\n event.preventDefault();\n this._activate();\n }\n }\n\n private _onClick() {\n if (this.disabled || this.readonly) return;\n this.focus();\n this._activate();\n }\n\n private _activate() {\n if (this.disabled || this.readonly) return;\n\n this.dispatchEvent(\n new CustomEvent<{ identifier: string }>(`activate-${type}`, {\n bubbles: true,\n composed: true,\n detail: { identifier: this.identifier }\n })\n );\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n }\n return QtiChoice as Constructor<ActiveElementMixinInterface> & T;\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ActiveElementMixin } from '../../mixins/active-element/active-element.mixin';\nexport class QtiGapText extends ActiveElementMixin(LitElement, 'qti-gap-text') {\n static override styles = css`\n :host {\n display: inline-flex;\n user-select: none;\n }\n `;\n\n @property({ type: Number, reflect: true }) tabindex: number | undefined = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('slot', 'drags');\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-gap-text': QtiGapText;\n }\n}\n","import { css, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ActiveElementMixin } from '../../mixins/active-element/active-element.mixin';\n\n// type shape = { shape: 'rect' | 'circle' | 'poly'; coords: number[] };\nexport class QtiHotspotChoice extends ActiveElementMixin(LitElement, 'qti-hotspot-choice') {\n static override styles = css`\n :host {\n display: flex;\n user-select: none;\n position: absolute;\n }\n `;\n @property({ attribute: 'aria-ordervalue', type: Number, reflect: true }) order: number;\n @property({ attribute: 'aria-ordercorrectvalue', type: Number, reflect: true }) orderCorrect: number;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-hotspot-choice': QtiHotspotChoice;\n }\n}\n","import { css, html, LitElement } from 'lit';\n\nimport { ActiveElementMixin } from '../../mixins/active-element/active-element.mixin';\nexport class QtiHottext extends ActiveElementMixin(LitElement, 'qti-hottext') {\n static override styles = css`\n :host {\n display: flex;\n user-select: none;\n }\n `;\n\n override render() {\n return html`<div part=\"ch\"><div part=\"cha\"></div></div>\n <slot></slot> `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-hottext': QtiHottext;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nexport class QtiInlineChoice extends LitElement {\n static override get styles() {\n return [\n css`\n :host {\n display: block;\n cursor: pointer;\n }\n `\n ];\n }\n\n @property({ type: String })\n identifier: string;\n\n override connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('click', this._onSelectInlineChoice);\n\n this.dispatchEvent(\n new CustomEvent('qti-inline-choice-register', {\n bubbles: true,\n composed: true,\n cancelable: false\n })\n );\n }\n\n override disconnectedCallback() {\n this.removeEventListener('click', this._onSelectInlineChoice);\n }\n\n override render() {\n return html` <slot></slot> `;\n }\n\n private _onSelectInlineChoice() {\n // if (this.disabled || this.readonly) return;\n\n this.dispatchEvent(\n new CustomEvent('qti-inline-choice-select', {\n bubbles: true,\n cancelable: false,\n composed: true,\n detail: { identifier: this.identifier }\n })\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-inline-choice': QtiInlineChoice;\n }\n}\n","import { html, LitElement } from 'lit';\nexport class QtiPrompt extends LitElement {\n override render() {\n return html`<slot></slot>`;\n }\n\n override connectedCallback(): void {\n // if prompts are in interactions they should have a slot, so the prompt has to go there\n // if prompt is in the body, then just display the prompt there.\n // A better check would be the latter, but not can't get through the shadowroot to find the slot\n const inInteraction = this.parentElement.tagName.endsWith('INTERACTION');\n if (inInteraction) {\n this.setAttribute('slot', 'prompt');\n }\n // const promptSlot = this.parentElement.shadowRoot.querySelector(\"[name='prompt']\");\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-prompt': QtiPrompt;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ActiveElementMixin } from '../../mixins/active-element/active-element.mixin';\n\n/*\nqti-match-interaction\nqti-associate-interaction\n*/\n// tslint:disable: indent\nexport class QtiSimpleAssociableChoice extends ActiveElementMixin(LitElement, 'qti-simple-associable-choice') {\n static override styles = css`\n :host {\n display: flex;\n user-select: none;\n }\n slot {\n width: 100%;\n display: block;\n }\n slot[name='qti-simple-associable-choice'] {\n width: auto;\n }\n `;\n\n /** the minimal number of selections a candidate must make */\n @property({\n type: Number,\n attribute: 'match-min'\n })\n public matchMin: number = 0;\n\n /** the maximum number of selections a candidate must make, the other options will be disabled when max options is checked */\n @property({\n type: Number,\n attribute: 'match-max'\n })\n public matchMax: number = 1;\n\n @property({\n type: String,\n attribute: 'fixed',\n converter: {\n fromAttribute: (value: string | null) => value === 'true',\n toAttribute: (value: boolean) => String(value)\n }\n })\n public fixed: boolean = false;\n\n // pk: This needs some explanation\n // in the associate interaction there is a special slot for these qti-simple-associable-choices\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('slot', 'qti-simple-associable-choice');\n this.setAttribute('part', 'qti-simple-associable-choice');\n }\n\n // pk: This needs some explanation\n // in qti-match-interaction, qti-simple-associable-choice is used to denote the\n // draggable, but also the droppable. WEIRD.. but lets deal with it.\n // So we have a slot for whenever another qti-simple-associable-choice is dropped in here.\n // And we have slot for content like in this associate interaction\n override render() {\n return html`\n <slot part=\"slot\"></slot>\n <slot part=\"dropslot\" name=\"qti-simple-associable-choice\"></slot>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-simple-associable-choice': QtiSimpleAssociableChoice;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: flex;\n align-items: center;\n user-select: none;\n }\n slot {\n width: 100%;\n display: flex;\n align-items: center;\n }\n [part='ch'] {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n }\n`;\n","import { css, html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ActiveElementMixin } from '../../mixins/active-element/active-element.mixin';\nimport styles from './qti-simple-choice.styles';\n\nimport type { CSSResultGroup } from 'lit';\n\n/**\n * qti-order-interaction\n * qti-choice-interaction\n */\nexport class QtiSimpleChoice extends ActiveElementMixin(LitElement, 'qti-simple-choice') {\n static override styles: CSSResultGroup = styles;\n\n @property({ type: String, attribute: 'template-identifier' })\n public templateIdentifier: string | null = null;\n\n @property({ type: String, attribute: 'show-hide' })\n public showHide: string | null = 'show';\n\n @property({\n type: Boolean,\n converter: {\n fromAttribute: (value: string | null) => value === 'true',\n toAttribute: (value: boolean) => String(value)\n }\n })\n public fixed: boolean = false;\n\n // property label\n @property({ type: String, attribute: false })\n public marker: string;\n\n get checked() {\n return this['internals'].states.has('--checked');\n }\n\n override render() {\n return html`<div part=\"ch\">\n <div part=\"cha\"></div>\n </div>\n ${this.marker ? html`<div id=\"label\">${this.marker}</div>` : nothing}\n <slot part=\"slot\"></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-simple-choice': QtiSimpleChoice;\n }\n}\n","import { QtiAssociateInteraction } from './qti-associate-interaction';\ncustomElements.define('qti-associate-interaction', QtiAssociateInteraction);\n","import { QtiChoiceInteraction } from './qti-choice-interaction';\ncustomElements.define('qti-choice-interaction', QtiChoiceInteraction);\n","import { QtiCustomInteraction } from './qti-custom-interaction';\ncustomElements.define('qti-custom-interaction', QtiCustomInteraction);\n","import { QtiEndAttemptInteraction } from './qti-end-attempt-interaction';\ncustomElements.define('qti-end-attempt-interaction', QtiEndAttemptInteraction);\n","import { QtiExtendedTextInteraction } from './qti-extended-text-interaction';\ncustomElements.define('qti-extended-text-interaction', QtiExtendedTextInteraction);\n","import { QtiGapMatchInteraction } from './qti-gap-match-interaction';\ncustomElements.define('qti-gap-match-interaction', QtiGapMatchInteraction);\n","import { QtiGraphicAssociateInteraction } from './qti-graphic-associate-interaction';\ncustomElements.define('qti-graphic-associate-interaction', QtiGraphicAssociateInteraction);\n","import { QtiGraphicGapMatchInteraction } from './qti-graphic-gap-match-interaction';\ncustomElements.define('qti-graphic-gap-match-interaction', QtiGraphicGapMatchInteraction);\n","import { QtiGraphicOrderInteraction } from './qti-graphic-order-interaction';\ncustomElements.define('qti-graphic-order-interaction', QtiGraphicOrderInteraction);\n","import { QtiHotspotInteraction } from './qti-hotspot-interaction';\ncustomElements.define('qti-hotspot-interaction', QtiHotspotInteraction);\n","import { QtiHottextInteraction } from './qti-hottext-interaction';\ncustomElements.define('qti-hottext-interaction', QtiHottextInteraction);\n","import { QtiInlineChoiceInteraction } from './qti-inline-choice-interaction';\ncustomElements.define('qti-inline-choice-interaction', QtiInlineChoiceInteraction);\n","import { QtiMatchInteraction } from './qti-match-interaction';\ncustomElements.define('qti-match-interaction', QtiMatchInteraction);\n","import { QtiMediaInteraction } from './qti-media-interaction';\ncustomElements.define('qti-media-interaction', QtiMediaInteraction);\n","import { QtiOrderInteraction } from './qti-order-interaction';\ncustomElements.define('qti-order-interaction', QtiOrderInteraction);\n","import { QtiPortableCustomInteraction } from './qti-portable-custom-interaction';\n\nimport type { ItemContext } from '@qti-components/base';\n\n/**\n * Test-specific extension of QtiPortableCustomInteraction that adds methods\n * for interacting with the iframe content in tests.\n */\nexport class QtiPortableCustomInteractionTest extends QtiPortableCustomInteraction {\n private _recreatingIframe = false;\n\n /**\n * Gets the HTML content of the iframe for testing purposes\n * @returns Promise that resolves with the HTML content string\n */\n async getIFrameContent(): Promise<string> {\n return new Promise(resolve => {\n const messageId = `get-content-${Date.now()}`;\n\n const messageHandler = (event: MessageEvent) => {\n const { data } = event;\n if (\n data?.source === 'qti-pci-iframe' &&\n (!data?.responseIdentifier || data?.responseIdentifier === this.responseIdentifier) &&\n data?.method === 'getContentResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve(data.content);\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('getContent', { messageId });\n\n // Set timeout to avoid hanging promises\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve('');\n }, 5000);\n });\n }\n\n // Expose the protected context\n public setTestContext(newContext: ItemContext): void {\n this.context = newContext;\n\n // If needed, force an update to push the context changes to the iframe\n this.updateComplete.then(() => {\n // const responseVal = this.responseVariablesToQtiVariableJSON(\n // (newContext?.variables?.find(v => v.identifier === this.responseIdentifier)?.value as string | string[]) ||\n // null,\n // newContext?.variables?.find(v => v.identifier === this.responseIdentifier)?.cardinality || 'single',\n // newContext?.variables?.find(v => v.identifier === this.responseIdentifier)?.baseType || 'string'\n // );\n this.value = newContext?.variables?.find(v => v.identifier === this.responseIdentifier).value as string;\n // this.recreateIframe();\n });\n }\n\n /**\n * Recreates the iframe completely\n * @returns Promise that resolves when the iframe is loaded\n */\n public async recreateIframe(): Promise<void> {\n this._recreatingIframe = true;\n\n try {\n // Remove existing iframe if it exists\n if (this.iframe) {\n this._iframeLoaded = false;\n this.iframe.remove();\n }\n\n this._pendingMessages = [];\n\n // Create a new iframe\n this.createIframe();\n\n // Wait for iframe to load\n return new Promise<void>(resolve => {\n const loadHandler = () => {\n this.removeEventListener('qti-portable-custom-interaction-loaded', loadHandler);\n resolve();\n };\n\n this.addEventListener('qti-portable-custom-interaction-loaded', loadHandler);\n\n // Add timeout to avoid hanging if the event never fires\n setTimeout(() => {\n this.removeEventListener('qti-portable-custom-interaction-loaded', loadHandler);\n resolve();\n }, 5000);\n });\n } finally {\n this._recreatingIframe = false;\n }\n }\n\n /**\n * Override the original disconnectedCallback to handle iframe recreation\n */\n override disconnectedCallback(): void {\n // Only call super if we're not in the process of recreating the iframe\n // This prevents removing event listeners that we still need\n if (!this._recreatingIframe) {\n super.disconnectedCallback();\n }\n }\n\n /**\n * Simulates a mouse click at specific coordinates within the iframe\n * @param x The x coordinate\n * @param y The y coordinate\n * @returns Promise that resolves when the click is performed\n */\n async iFrameMouseClick(x: number, y: number): Promise<void> {\n return new Promise(resolve => {\n const messageId = `click-${Date.now()}`;\n\n const messageHandler = (event: MessageEvent) => {\n const { data } = event;\n if (\n data?.source === 'qti-pci-iframe' &&\n (!data?.responseIdentifier || data?.responseIdentifier === this.responseIdentifier) &&\n data?.method === 'clickResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve();\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('simulateClick', { x, y, messageId });\n\n // Set timeout to avoid hanging promises\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve();\n }, 5000);\n });\n }\n\n /**\n * Clicks on an element identified by a CSS selector\n * @param selector The CSS selector string\n * @returns Promise that resolves with boolean indicating if the element was found and clicked\n */\n async iFrameClickOnElement(selector: string): Promise<boolean> {\n return new Promise(resolve => {\n const messageId = `click-selector-${Date.now()}`;\n\n const messageHandler = (event: MessageEvent) => {\n const { data } = event;\n if (\n data?.source === 'qti-pci-iframe' &&\n (!data?.responseIdentifier || data?.responseIdentifier === this.responseIdentifier) &&\n data?.method === 'clickSelectorResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve(data.success);\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('clickOnSelector', { selector, messageId });\n\n // Set timeout to avoid hanging promises\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve(false);\n }, 5000);\n });\n }\n\n /**\n * Clicks on an element containing the specified text\n * @param text The text to search for within elements\n * @returns Promise that resolves with boolean indicating if the element was found and clicked\n */\n async iFrameClickOnElementByText(text: string): Promise<boolean> {\n return new Promise(resolve => {\n const messageId = `click-text-${Date.now()}`;\n\n const messageHandler = (event: MessageEvent) => {\n const { data } = event;\n if (\n data?.source === 'qti-pci-iframe' &&\n (!data?.responseIdentifier || data?.responseIdentifier === this.responseIdentifier) &&\n data?.method === 'clickTextResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve(data.success);\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('clickOnElementByText', { text, messageId });\n\n // Set timeout to avoid hanging promises\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve(false);\n }, 5000);\n });\n }\n\n /**\n * Sets the value of an input element identified by a CSS selector\n * @param selector The CSS selector string\n * @param value The value to set\n * @returns Promise that resolves with boolean indicating if the element was found and value was set\n */\n async iFrameSetValueElement(selector: string, value: string): Promise<boolean> {\n return new Promise(resolve => {\n const messageId = `set-value-${Date.now()}`;\n\n const messageHandler = (event: MessageEvent) => {\n const { data } = event;\n if (\n data?.source === 'qti-pci-iframe' &&\n (!data?.responseIdentifier || data?.responseIdentifier === this.responseIdentifier) &&\n data?.method === 'setValueResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve(data.success);\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('setValueElement', { selector, value, messageId });\n\n // Set timeout to avoid hanging promises\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve(false);\n }, 5000);\n });\n }\n\n /**\n * Sets the value of an input element containing the specified text\n * @param text The text to search for within elements\n * @param value The value to set\n * @returns Promise that resolves with boolean indicating if the element was found and value was set\n */\n async iFrameSetValueElementByText(text: string, value: string): Promise<boolean> {\n return new Promise(resolve => {\n const messageId = `set-value-text-${Date.now()}`;\n\n const messageHandler = (event: MessageEvent) => {\n const { data } = event;\n if (\n data?.source === 'qti-pci-iframe' &&\n (!data?.responseIdentifier || data?.responseIdentifier === this.responseIdentifier) &&\n data?.method === 'setValueByTextResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve(data.success);\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('setValueElementByText', { text, value, messageId });\n\n // Set timeout to avoid hanging promises\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve(false);\n }, 5000);\n });\n }\n\n /**\n * Performs a mousedown event on an element identified by a CSS selector\n * @param selector The CSS selector string\n * @returns Promise that resolves with boolean indicating if the element was found and mousedown was performed\n */\n async iFrameMousedownOnElement(selector: string): Promise<boolean> {\n return new Promise(resolve => {\n const messageId = `mousedown-selector-${Date.now()}`;\n\n const messageHandler = (event: MessageEvent) => {\n const { data } = event;\n if (\n data?.source === 'qti-pci-iframe' &&\n (!data?.responseIdentifier || data?.responseIdentifier === this.responseIdentifier) &&\n data?.method === 'mousedownSelectorResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve(data.success);\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('mousedownOnSelector', { selector, messageId });\n\n // Set timeout to avoid hanging promises\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve(false);\n }, 5000);\n });\n }\n\n /**\n * Override the original generateIframeContent method to include\n * the test message handlers in the iframe HTML\n */\n override generateIframeContent(): string {\n // Get the original iframe HTML from the parent class\n const originalContent = super.generateIframeContent();\n\n // Insert our test message handlers before the closing </script> tag\n const testHandlers = `\n // Test helper functions for QtiPortableCustomInteractionTest\n // Base iframe implementation already provides PCIManager.getContent\n \n // Base iframe implementation already provides PCIManager.simulateClick\n \n // Base iframe implementation already provides PCIManager.clickOnSelector\n \n // Base iframe implementation already provides PCIManager.clickOnElementByText\n \n // Base iframe implementation already provides PCIManager.setValueElement\n \n function deepQuerySelector(root, selector) {\n if (!root) return null;\n try {\n const direct = root.querySelector ? root.querySelector(selector) : null;\n if (direct) return direct;\n } catch (e) {\n // ignore invalid selector for this root\n }\n if (!root.querySelectorAll) return null;\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if (node && node.shadowRoot) {\n const found = deepQuerySelector(node.shadowRoot, selector);\n if (found) return found;\n }\n }\n return null;\n }\n\n function deepFindElementByExactText(root, text) {\n if (!root || !text) return null;\n if (root.querySelectorAll) {\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if ((node.textContent || '').trim() === text) return node;\n if (node.shadowRoot) {\n const found = deepFindElementByExactText(node.shadowRoot, text);\n if (found) return found;\n }\n }\n }\n return null;\n }\n\n function escapeSelectorId(id) {\n try {\n if (window.CSS && typeof window.CSS.escape === 'function') return window.CSS.escape(id);\n } catch (e) {\n // ignore\n }\n return String(id).replace(/([ #;?%&,.+*~\\\\':\"!^$[\\\\]()=>|\\\\/])/g, '\\\\\\\\$1');\n }\n\n PCIManager.setValueElementByText = function(params) {\n const messageId = params && params.messageId;\n try {\n const text = params && params.text;\n const value = params && params.value;\n\n const textEl = text ? deepFindElementByExactText(document, text) : null;\n let target = null;\n\n if (textEl) {\n const tag = (textEl.tagName || '').toUpperCase();\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') {\n target = textEl;\n } else if (tag === 'LABEL' && textEl.htmlFor) {\n const id = escapeSelectorId(textEl.htmlFor);\n target = deepQuerySelector(document, '#' + id);\n }\n\n if (!target) {\n let parent = textEl.parentElement;\n while (parent) {\n const candidate = parent.querySelector ? parent.querySelector('input, textarea, select') : null;\n if (candidate) {\n target = candidate;\n break;\n }\n parent = parent.parentElement;\n }\n }\n }\n\n const success = !!target && setValueOnElement(target, value);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'setValueByTextResponse',\n messageId: messageId,\n success: success\n },\n '*'\n );\n } catch (error) {\n console.error('Error setting value by text:', error);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'setValueByTextResponse',\n messageId: messageId,\n success: false,\n error: error.toString()\n },\n '*'\n );\n }\n };\n \n PCIManager.mousedownOnSelector = function(params) {\n try {\n const element = params && params.selector ? deepQuerySelector(document, params.selector) : null;\n \n let success = false;\n \n if (element) {\n const rect = element.getBoundingClientRect();\n const mousedownEvent = new MouseEvent('mousedown', {\n bubbles: true,\n cancelable: true,\n view: window,\n clientX: rect.left + rect.width / 2,\n clientY: rect.top + rect.height / 2\n });\n element.dispatchEvent(mousedownEvent);\n success = true;\n }\n \n window.parent.postMessage({\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'mousedownSelectorResponse',\n messageId: params.messageId,\n success\n }, '*');\n } catch (error) {\n console.error('Error performing mousedown on selector:', error);\n window.parent.postMessage({\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'mousedownSelectorResponse',\n messageId: params.messageId,\n success: false,\n error: error.toString()\n }, '*');\n }\n };\n \n // Helper function for setting values on elements\n function setValueOnElement(element, value) {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n element.value = value;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n element.dispatchEvent(new Event('change', { bubbles: true }));\n return true;\n } else if (element.tagName === 'SELECT') {\n element.value = value;\n element.dispatchEvent(new Event('change', { bubbles: true }));\n return true;\n } else if (element.isContentEditable) {\n element.textContent = value;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n }\n return false;\n }\n \n // Add test-related message handlers (do not override global handlers)\n let expectedParentOriginTest = null;\n window.addEventListener(\n 'message',\n function(event) {\n const { data } = event;\n\n if (event.source !== window.parent || !data || data.source !== 'qti-portable-custom-interaction') return;\n if (expectedParentOriginTest === null) expectedParentOriginTest = event.origin;\n else if (event.origin !== expectedParentOriginTest) return;\n if (data.responseIdentifier && data.responseIdentifier !== PCIManager.responseIdentifier) return;\n\n switch (data.method) {\n case 'setValueElementByText':\n PCIManager.setValueElementByText(data.params);\n return;\n case 'mousedownOnSelector':\n PCIManager.mousedownOnSelector(data.params);\n return;\n }\n },\n true\n );`;\n\n // Find the position to insert our test handlers\n const insertPosition = originalContent.lastIndexOf('</script>');\n\n // Insert our handlers\n const modifiedContent =\n originalContent.substring(0, insertPosition) + testHandlers + originalContent.substring(insertPosition);\n\n return modifiedContent;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-portable-custom-interaction-test': QtiPortableCustomInteractionTest;\n }\n}\n","import { QtiPortableCustomInteraction } from './qti-portable-custom-interaction';\nimport { QtiPortableCustomInteractionTest } from './qti-portable-custom-test-interaction';\n\ncustomElements.define('qti-portable-custom-interaction', QtiPortableCustomInteraction);\ncustomElements.define('qti-portable-custom-interaction-test', QtiPortableCustomInteractionTest);\n","import { QtiPositionObjectInteraction } from './qti-position-object-interaction';\nimport { QtiPositionObjectStage } from './qti-position-object-stage';\n\ncustomElements.define('qti-position-object-interaction', QtiPositionObjectInteraction);\ncustomElements.define('qti-position-object-stage', QtiPositionObjectStage);\n","import { QtiSelectPointInteraction } from './qti-select-point-interaction';\ncustomElements.define('qti-select-point-interaction', QtiSelectPointInteraction);\n","import { QtiSliderInteraction } from './qti-slider-interaction';\ncustomElements.define('qti-slider-interaction', QtiSliderInteraction);\n","import { QtiTextEntryInteraction } from './qti-text-entry-interaction';\ncustomElements.define('qti-text-entry-interaction', QtiTextEntryInteraction);\n","import { QtiUploadInteraction } from './qti-upload-interaction';\ncustomElements.define('qti-upload-interaction', QtiUploadInteraction);\n","import { QtiAssociableHotspot } from './qti-associable-hotspot';\ncustomElements.define('qti-associable-hotspot', QtiAssociableHotspot);\n","import { QtiGap } from './qti-gap';\ncustomElements.define('qti-gap', QtiGap);\n","import { QtiGapImg } from './qti-gap-img';\ncustomElements.define('qti-gap-img', QtiGapImg);\n","import { QtiGapText } from './qti-gap-text';\ncustomElements.define('qti-gap-text', QtiGapText);\n","import { QtiHotspotChoice } from './qti-hotspot-choice';\ncustomElements.define('qti-hotspot-choice', QtiHotspotChoice);\n","import { QtiHottext } from './qti-hottext';\ncustomElements.define('qti-hottext', QtiHottext);\n","import { QtiInlineChoice } from './qti-inline-choice';\ncustomElements.define('qti-inline-choice', QtiInlineChoice);\n","import { QtiPrompt } from './qti-prompt';\ncustomElements.define('qti-prompt', QtiPrompt);\n","import { QtiSimpleAssociableChoice } from './qti-simple-associable-choice';\ncustomElements.define('qti-simple-associable-choice', QtiSimpleAssociableChoice);\n","import { QtiSimpleChoice } from './qti-simple-choice';\ncustomElements.define('qti-simple-choice', QtiSimpleChoice);\n"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgqBpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOgB,8BAA8B,MAAe;AAC3D,UAAM,mBAAmB,KAAK;AAG9B,SAAK,kBAAkB,OACnB,kBAAkB,kBAClB,iBAAiB,gBAAgB,WAC/B,KACA,CAAC;AAGP,UAAM,cAAc,8BAA8B,KAAK,kBAAkB;AAGzE,UAAM,qBAAqB,KAAK,eAAe,iBAAiB,IAAI,WAAW,EAAE;AACjF,QAAI,oBAAoB;AACtB,yBAAmB,QAAQ,uBAAqB;AAC9C,0BAAkB,OAAO;AAAA,MAC3B,CAAC;AAAA,IACH;AAGA,QAAI,MAAM;AAER,WAAK,QAAQ;AAAA,IACf,OAAO;AAEL,WAAK,OAAO;AACZ;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,CAAC,kBAAkB,iBAAiB;AAC/C;AAAA,IACF;AAGA,UAAM,2BAA2B,SAAS,cAAc,KAAK;AAC7D,6BAAyB,KAAK;AAC9B,6BAAyB,YAAY;AACrC,6BAAyB,MAAM,WAAW;AAC1C,6BAAyB,MAAM,YAAY;AAC3C,6BAAyB,MAAM,SAAS;AACxC,6BAAyB,MAAM,UAAU;AACzC,6BAAyB,MAAM,eAAe;AAC9C,6BAAyB,MAAM,kBAAkB;AAGjD,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,cAAc;AACpB,UAAM,MAAM,aAAa;AACzB,UAAM,MAAM,eAAe;AAC3B,UAAM,MAAM,QAAQ;AACpB,6BAAyB,YAAY,KAAK;AAG1C,UAAM,wBAAwB,SAAS;AAAA,MACrC;AAAA,IACF;AAGA,UAAM,KAAK,KAAK,UAAU,EAAE,QAAQ,UAAQ;AAC1C,UAAI,KAAK,SAAS,QAAQ,KAAK,SAAS,uBAAuB;AAC7D,8BAAsB,aAAa,KAAK,MAAM,KAAK,KAAK;AAAA,MAC1D;AAAA,IACF,CAAC;AAGD,UAAM,qBAAqB,KAAK;AAChC,0BAAsB,qBAAqB,GAAG,kBAAkB;AAIhE,UAAM,KAAK,KAAK,QAAQ,EAAE,QAAQ,WAAS;AACzC,YAAM,cAAc,MAAM,UAAU,IAAI;AACxC,4BAAsB,YAAY,WAAW;AAAA,IAC/C,CAAC;AAGD,UAAM,uBAAuB,iBAAiB;AAG9C,UAAM,4BAA4B,sBAAsB;AACxD,0BAAsB,oBAAoB,WAAY;AACpD,gCAA0B,KAAK,IAAI;AAEnC,YAAM,oBAAoB,MAAM;AAC9B,YAAI,CAAC,KAAK,cAAe,QAAO;AAGhC,mBAAW,MAAM;AACf,gBAAM,kBAAkB,KAAK;AAAA,YAC3B;AAAA,YACA,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,UACnB;AAEA,eAAK,oBAAoB,cAAc;AAAA,YACrC,CAAC,kBAAkB,GAAG;AAAA,UACxB,CAAC;AACD,eAAK,oBAAoB,YAAY,EAAE,OAAO,SAAS,CAAC;AAAA,QAC1D,GAAG,GAAI;AAEP,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,kBAAkB,GAAG;AACxB,cAAM,aAAa,YAAY,MAAM;AACnC,cAAI,kBAAkB,EAAG,eAAc,UAAU;AAAA,QACnD,GAAG,GAAG;AAEN,mBAAW,MAAM;AACf,wBAAc,UAAU;AAAA,QAC1B,GAAG,GAAK;AAAA,MACV;AAAA,IACF;AAGA,0BAAsB,MAAM,gBAAgB;AAG5C,6BAAyB,YAAY,qBAAqB;AAG1D,SAAK,MAAM,wBAAwB;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKO,UAAU;AAEf,SAAK,iBAAiB;AAAA,MACpB,eAAe,KAAK,MAAM;AAAA,MAC1B,UAAU,KAAK,MAAM;AAAA,IACvB;AAEA,SAAK,oBAAoB,YAAY,EAAE,OAAO,WAAW,CAAC;AAG1D,UAAM,kBAAkB,KAAK,cAAc,0BAA0B;AACrE,QAAI,CAAC,iBAAiB;AACpB,YAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,cAAQ,YAAY;AACpB,cAAQ,MAAM,WAAW;AACzB,cAAQ,MAAM,MAAM;AACpB,cAAQ,MAAM,OAAO;AACrB,cAAQ,MAAM,QAAQ;AACtB,cAAQ,MAAM,SAAS;AACvB,cAAQ,MAAM,kBAAkB;AAChC,cAAQ,MAAM,SAAS;AACvB,cAAQ,MAAM,gBAAgB;AAC9B,cAAQ,MAAM,SAAS;AAGvB,UAAI,iBAAiB,IAAI,EAAE,aAAa,UAAU;AAChD,aAAK,MAAM,WAAW;AAAA,MACxB;AAEA,WAAK,YAAY,OAAO;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,SAAS;AAEd,UAAM,UAAU,KAAK,cAAc,0BAA0B;AAC7D,QAAI,SAAS;AACX,cAAQ,OAAO;AAAA,IACjB;AAGA,QAAI,KAAK,gBAAgB;AACvB,UAAI,KAAK,eAAe,eAAe;AACrC,aAAK,MAAM,gBAAgB,KAAK,eAAe;AAAA,MACjD;AACA,UAAI,KAAK,eAAe,UAAU;AAChC,aAAK,MAAM,WAAW,KAAK,eAAe;AAAA,MAC5C;AACA,WAAK,iBAAiB;AAAA,IACxB;AAEA,SAAK,oBAAoB,YAAY,EAAE,OAAO,cAAc,CAAC;AAAA,EAC/D;AAAA,EAQS,SAAS;AAChB,WAAO;AAAA;AAAA,QAEH,KAAK,gBACH;AAAA;AAAA,cAEI,KAAK,aAAa;AAAA,oBAEtB,EAAE;AAAA;AAAA,EAEV;AACF;AA/8CE;AAAA,EADC,EAAS,EAAE,MAAM,QAAQ,WAAW,SAAS,CAAC;AAAA,GApBpC,6BAqBX;AAGA;AAAA,EADC,EAAS,EAAE,MAAM,QAAQ,WAAW,qCAAqC,CAAC;AAAA,GAvBhE,6BAwBX;AAGA;AAAA,EADC,EAAS,EAAE,MAAM,QAAQ,WAAW,qBAAqB,CAAC;AAAA,GA1BhD,6BA2BX;AAGA;AAAA,EADC,EAAS,EAAE,MAAM,QAAQ,WAAW,oBAAoB,CAAC;AAAA,GA7B/C,6BA8BX;AAGA;AAAA,EADC,EAAS,EAAE,MAAM,QAAQ,WAAW,sBAAsB,CAAC;AAAA,GAhCjD,6BAiCX;AAGA;AAAA,EADC,EAAS,EAAE,MAAM,QAAQ,WAAW,gBAAgB,CAAC;AAAA,GAnC3C,6BAoCX;AAGA;AAAA,EADC,EAAS,EAAE,MAAM,SAAS,WAAW,yBAAyB,CAAC;AAAA,GAtCrD,6BAuCX;AAGA;AAAA,EADC,EAAS,EAAE,MAAM,SAAS,WAAW,yBAAyB,CAAC;AAAA,GAzCrD,6BA0CX;AAGQ;AAAA,EADP,EAAM;AAAA,GA5CI,6BA6CH;AAIE;AAAA,EAFT,EAAQ,EAAE,SAAS,aAAa,WAAW,KAAK,CAAC;AAAA,EACjD,EAAM;AAAA,GAhDI,6BAiDD;AAED;AAAA,EAAR,EAAM;AAAA,GAnDI,6BAmDF;;;AChEJ,IAAM,+BAAN,cAA2CC,GAAW;AAAA,EAClD,SAAS;AAChB,WAAO;AAAA,EACT;AAAA,EAEA;AAAA,SAAgB,SAAS;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYF;AAAA;AACF;;;AClBO,IAAM,yBAAN,cAAqCC,GAAW;AAAA,EAM5C,SAAS;AAChB,WAAO;AAAA,EACT;AAAA,EAEA;AAAA,SAAgB,SAAS;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMF;AAAA;AAAA,EAEA,cAAc;AACZ,UAAM;AACN,SAAK,qBAAqB,KAAK,mBAAmB,KAAK,IAAI;AAC3D,SAAK,qBAAqB,KAAK,mBAAmB,KAAK,IAAI;AAAA,EAC7D;AAAA;AAAA,EAGA,mBAAmB,OAAyB;AAC1C,UAAM,eAAe;AAGrB,UAAM,SAAiB,MAAM,UAAU,KAAK;AAC5C,UAAM,SAAiB,MAAM,UAAU,KAAK;AAG5C,SAAK,YAAY,MAAM,OAAO,KAAK,YAAY,aAAa,SAAS;AACrE,SAAK,YAAY,MAAM,MAAM,KAAK,YAAY,YAAY,SAAS;AAGnE,SAAK,SAAS,MAAM;AACpB,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAES,aAAa,GAAgC;AACpD,UAAM,aAAa,CAAC;AAGpB,SAAK,cAAc,KAAK,cAAc,qCAAqC;AAI3E,SAAK,SAAS;AACd,SAAK,SAAS;AAGd,SAAK,YAAY,iBAAiB,aAAa,CAAC,UAAsB;AAEpE,WAAK,SAAS,MAAM;AACpB,WAAK,SAAS,MAAM;AAGpB,eAAS,iBAAiB,aAAa,KAAK,oBAAoB,IAAI;AAAA,IACtE,CAAC;AACD,aAAS,iBAAiB,WAAW,KAAK,kBAAkB;AAAA,EAC9D;AAAA,EAEA,qBAAqB;AACnB,aAAS,oBAAoB,aAAa,KAAK,oBAAoB,IAAI;AAAA,EACzE;AAAA,EAES,uBAAuB;AAC9B,UAAM,qBAAqB;AAC3B,aAAS,oBAAoB,aAAa,KAAK,kBAAkB;AACjE,aAAS,oBAAoB,WAAW,KAAK,kBAAkB;AAAA,EACjE;AACF;;;ACnDA,IAAMC,KAAY;AAAlB,IAEMC,KAAgB,OAAOD;AAF7B,IAgHaE,KAAWC,GA1GxB,cAAgCC,GAAAA;EAG9B,YAAYC,IAAAA;AAEV,QADAC,MAAMD,EAAAA,GAEJA,GAASE,SAASC,EAASC,aACT,YAAlBJ,GAASK,QACRL,GAASM,SAASC,SAAoB,EAEvC,OAAUC,MACR,4GAAA;EAIL;EAED,OAAOC,IAAAA;AACL,WAAOC,OAAOC,KAAKF,EAAAA,EAAWG,QAAO,CAACC,IAAOC,OAAAA;AAC3C,YAAMC,KAAQN,GAAUK,EAAAA;AACxB,aAAa,QAATC,KACKF,KAcFA,KAAQ,GALfC,KAAOA,GAAKE,SAAS,GAAA,IACjBF,KACAA,GACGG,QAAQ,qCAAqC,KAAA,EAC7CC,YAAAA,CAAAA,IACmBH,EAAAA;IAAQ,IACjC,EAAA;EACJ;EAEQ,OAAOI,IAAAA,CAAsBV,EAAAA,GAAAA;AACpC,UAAA,EAAMI,OAACA,GAAAA,IAASM,GAAKC;AAErB,QAAA,WAAIC,KAAKC,GAEP,QADAD,KAAKC,KAA2B,IAAIC,IAAIb,OAAOC,KAAKF,EAAAA,CAAAA,GAC7CY,KAAKG,OAAOf,EAAAA;AAIrB,eAAWJ,MAAQgB,KAAKC,GAEC,SAAnBb,GAAUJ,EAAAA,MACZgB,KAAKC,GAA0BG,OAAOpB,EAAAA,GAClCA,GAAKW,SAAS,GAAA,IAChBH,GAAMa,eAAerB,EAAAA,IAGpBQ,GAAcR,EAAAA,IAAQ;AAM7B,eAAWA,MAAQI,IAAW;AAC5B,YAAMM,KAAQN,GAAUJ,EAAAA;AACxB,UAAa,QAATU,IAAe;AACjBM,aAAKC,GAAyBK,IAAItB,EAAAA;AAClC,cAAMuB,KACa,YAAA,OAAVb,MAAsBA,GAAMc,SAASjC,EAAAA;AAC1CS,QAAAA,GAAKW,SAAS,GAAA,KAAQY,KACxBf,GAAMiB,YACJzB,IACAuB,KACKb,GAAiBgB,MAAM,GAAA,GA1EvB,IA2EAhB,IACLa,KAAcjC,KAAY,EAAA,IAI3BkB,GAAcR,EAAAA,IAAQU;MAE1B;IACF;AACD,WAAOiB;EACR;AAAA,CAAA;;;ACxGI,IAAM,4BAAN,cAAwC,YAAY;AAAA,EAApD;AAAA;AAwBL,SAAO,aAAqB;AAM5B,SAAO,aAAqB;AAEnB,oBAA4B;AAGrC,SAAQ,gBAAqD,CAAC;AAG9D,SAAQ,sBAAiC,CAAC;AAG1C;AAAA,SAAQ,cAAuC;AAE/C,SAAQ,UAAU;AAClB,SAAQ,UAAU;AAClB,SAAQ,sBAAsB;AAC9B,SAAQ,uBAAuB;AAG/B;AAAA,SAAQ,gBAAgB,CAAC,UAAsB;AAC7C,UAAI,KAAK,UAAU;AACjB;AAAA,MACF;AACA,UAAI,CAAC,KAAK,aAAa;AACrB,gBAAQ,KAAK,0DAA0D;AACvE;AAAA,MACF;AACA,WAAK,eAAe;AAEpB,YAAM,OAAO,KAAK,YAAY,sBAAsB;AAGpD,YAAMC,MAAK,MAAM,UAAU,KAAK,QAAQ,KAAK;AAC7C,YAAM,KAAK,MAAM,UAAU,KAAK,OAAO,KAAK;AAG5C,YAAM,WAAW,GAAGA,GAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;AAE9C,UAAI,KAAK,eAAe,GAAG;AAEzB,aAAK,WAAW,CAAC,QAAQ;AAAA,MAC3B,OAAO;AAEL,YAAI,KAAK,eAAe,MAAM,KAAK,YAAY,CAAC,GAAG,SAAS,KAAK,YAAY;AAC3E,eAAK,WAAW,CAAC,GAAI,KAAK,YAAY,CAAC,GAAI,QAAQ;AAAA,QACrD,OAAO;AAAA,QAGP;AAAA,MACF;AAEA,WAAK,aAAa,KAAK,QAAQ;AAAA,IACjC;AAOA,SAAQ,YAAY,MAAM;AACxB,WAAK,eAAe;AAAA,IACtB;AAAA;AAAA,EA1FA;AAAA,SAAgB,SAAS;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgBF;AAAA;AAAA,EAkES,oBAAoB;AAC3B,UAAM,kBAAkB;AACxB,WAAO,iBAAiB,UAAU,KAAK,SAAS;AAAA,EAClD;AAAA,EAMA,IAAI,iBAAiB;AACnB,YAAQ,KAAK,YAAY,CAAC,GACvB,OAAO,WAAS,KAAK,EACrB,IAAI,WAAS;AACZ,YAAM,CAACA,IAAG,CAAC,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AAC1C,aAAO,EAAE,GAAAA,IAAG,EAAE;AAAA,IAChB,CAAC;AAAA,EACL;AAAA,EAEgB,0BAA0B,MAAe;AACvD,SAAK,sBAAsB,CAAC;AAC5B,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AACA,SAAK,eAAe,QAAQ,WAAS;AACnC,YAAM,UAAW,KAAK,iBAAiB,YAA+B,eAAe;AAAA,QAAK,iBACxF,cAAc;AAAA,UACZ,GAAG,MAAM,CAAC,IAAI,MAAM,CAAC;AAAA,UACrB,GAAG,YAAY,KAAK,IAAI,YAAY,MAAM;AAAA,UAC1C,KAAK,iBAAiB;AAAA,QACxB;AAAA,MACF;AACA,WAAK,oBAAoB,KAAK,OAAO;AAAA,IACvC,CAAC;AAAA,EACH;AAAA,EAEgB,sBAAsB,MAAe;AACnD,UAAM,mBAAmB,KAAK;AAC9B,QAAI,CAAC,QAAQ,CAAC,kBAAkB;AAC9B,WAAK,gBAAgB,CAAC;AACtB;AAAA,IACF;AAEA,UAAM,cAAc,iBAAiB;AACrC,QAAI,iBAAoC,CAAC;AACzC,QAAI,CAAC,eAAe,YAAY,eAAe,WAAW,GAAG;AAC3D,UAAI,iBAAiB,iBAAiB;AACpC,cAAM,mBAAmB,MAAM,QAAQ,iBAAiB,eAAe,IACnE,iBAAiB,kBACjB,CAAC,iBAAiB,eAAe;AACrC,YAAI,iBAAiB,WAAW,KAAK,iBAAiB,KAAK,CAAAC,OAAKA,GAAE,MAAM,GAAG,EAAE,SAAS,CAAC,GAAG;AACxF,kBAAQ,MAAM,6DAA6D;AAC3E,iBAAO;AAAA,QACT;AACA,gBAAQ;AAAA,UACN;AAAA,QACF;AAEA,yBAAiB,iBAAiB,IAAI,CAAAA,OAAK;AACzC,gBAAM,SAASA,GAAE,MAAM,GAAG,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK;AAClD,iBAAO,EAAE,OAAO,UAAU,QAAQ,cAAc,GAAG,aAAa,EAAE;AAAA,QACpE,CAAC;AAAA,MACH,OAAO;AACL,gBAAQ,MAAM,kDAAkD;AAChE;AAAA,MACF;AAAA,IACF,OAAO;AAEL,uBAAiB,YAAY;AAAA,IAC/B;AACA,SAAK,gBAAgB,eAAe,IAAI,CAAAC,QAAM,EAAE,QAAQA,GAAE,QAAQ,OAAOA,GAAE,MAAM,EAAE;AAAA,EACrF;AAAA,EAES,QAAQ,mBAA2D;AAC1E,UAAM,QAAQ,iBAAiB;AAC/B,UAAM,MAAM,KAAK;AACjB,QAAI,OAAO,kBAAkB,IAAI,eAAe,KAAK,KAAK,cAAc,SAAS,GAAG;AAClF,WAAK,eAAe;AACpB,WAAK,WAAW,iBAAiB,KAAK,EAAE,QAAQ,CAAC,OAAoB;AACnE,cAAM,SAAS,GAAG,QAAQ;AAC1B,cAAM,QAAQ,GAAG,QAAQ;AACzB,YAAI,UAAU,OAAO;AACnB;AAAA,YACE;AAAA,YACA,OAAO,MAAM,GAAG,EAAE,IAAI,CAAAC,OAAK,CAACA,EAAC;AAAA,YAC7B;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA,UAEDA;AAAA,OACC,KAAK,YAAY,CAAC,GAAG,OAAO,WAAS,KAAK;AAAA,MAC3C,WAAS;AAAA,MACT,CAAC,OAAO,UAAU;AAChB,cAAM,CAACH,IAAG,CAAC,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AAE1C,cAAM,iBAAkBA,MAAK,KAAK,uBAAuB,KAAM;AAC/D,cAAM,gBAAiB,KAAK,KAAK,wBAAwB,KAAM;AAI/D,cAAM,WAAW;AACjB,cAAM,kBAAmB,YAAY,KAAK,uBAAuB,KAAM;AACvE,cAAM,mBAAoB,YAAY,KAAK,wBAAwB,KAAM;AAEzE,YAAI,iBAAiB;AACrB,YAAI,KAAK,oBAAoB,KAAK,MAAM,MAAM;AAC5C,2BAAiB;AAAA,QACnB,WAAW,KAAK,oBAAoB,KAAK,MAAM,OAAO;AACpD,2BAAiB;AAAA,QACnB;AAEA,eAAO;AAAA;AAAA,6BAEU,cAAc;AAAA,wBACnBI,GAAS;AAAA,UACf,eAAe,KAAK,eAAe,IAAI,SAAS;AAAA,UAChD,UAAU;AAAA,UACV,WAAW;AAAA,UACX,MAAM,GAAG,cAAc;AAAA,UACvB,KAAK,GAAG,aAAa;AAAA,UACrB,OAAO,OAAO,eAAe;AAAA,UAC7B,QAAQ,OAAO,gBAAgB;AAAA,UAC/B,UAAU,OAAO,eAAe;AAAA,UAChC,WAAW,OAAO,gBAAgB;AAAA,UAClC,cAAc;AAAA;AAAA,UACd,YAAY;AAAA;AAAA,QACd,CAAC,CAAC;AAAA,8CAC4B,KAAK;AAAA,4BACvB,KAAK,QAAQ;AAAA,yBAChB,CAACF,OAAa;AACrB,UAAAA,GAAE,gBAAgB;AAClB,eAAK,YAAY,KAAK,YAAY,CAAC,GAAG,OAAO,CAAC,GAAGG,OAAMA,OAAM,KAAK;AAClE,eAAK,aAAa,KAAK,QAAQ;AAAA,QACjC,CAAC;AAAA;AAAA;AAAA,MAGP;AAAA,IACF,CAAC;AAAA,UACCF;AAAA,MACA,KAAK,eAAe,OAAO,UAAQ,IAAI,KAAK,CAAC;AAAA,MAC7C,UAAQ;AAAA,MACR,CAAC,MAAME,OACL;AAAA,sBACUD,GAAS;AAAA,QACf,UAAU;AAAA,QACV,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,SAAS;AAAA,MACX,CAAC,CAAC;AAAA,4BACY,KAAK,MAAM;AAAA,oBACnB,oBAAoBC,KAAI,CAAC,EAAE;AAAA,4BACnB,KAAK,KAAK;AAAA;AAAA,IAE9B,CAAC;AAAA;AAAA;AAAA,EAGP;AAAA,EAEA,WAAoB;AAClB,WAAO,KAAK,aAAa,QAAQ,KAAK,SAAS,UAAU,KAAK,cAAc,KAAK,SAAS,UAAU,KAAK;AAAA,EAC3G;AAAA,EAEQ,iBAAiB;AAEvB,SAAK,sBAAsB,KAAK,YAAY,aAAa,OAAO,IAC5D,WAAW,KAAK,YAAY,aAAa,OAAO,CAAE,IAClD,KAAK,YAAY;AACrB,SAAK,uBAAuB,KAAK,YAAY,aAAa,QAAQ,IAC9D,WAAW,KAAK,YAAY,aAAa,QAAQ,CAAE,IACnD,KAAK,YAAY;AAErB,UAAM,OAAO,KAAK,YAAY,sBAAsB;AACpD,SAAK,UAAU,KAAK,UAAU,IAAI,IAAI,KAAK,sBAAsB,KAAK;AACtE,SAAK,UAAU,KAAK,WAAW,IAAI,IAAI,KAAK,uBAAuB,KAAK;AAAA,EAC1E;AAAA,EAES,eAAqB;AAC5B,SAAK,cAAc,KAAK,cAAc,KAAK;AAE3C,QAAI,KAAK,aAAa;AACpB,WAAK,eAAe;AAEpB,WAAK,YAAY,iBAAiB,SAAS,KAAK,aAAa;AAAA,IAC/D,OAAO;AACL,cAAQ,KAAK,0DAA0D;AAAA,IACzE;AAAA,EACF;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAqB;AAE3B,WAAO,oBAAoB,UAAU,KAAK,SAAS;AACnD,QAAI,KAAK,aAAa;AAEpB,WAAK,YAAY,oBAAoB,SAAS,KAAK,aAAa;AAAA,IAClE;AAAA,EACF;AACF;AAvQS;AAAA,EAJN,EAAS;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AAAA,GAvBU,0BAwBJ;AAMA;AAAA,EAJN,EAAS;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AAAA,GA7BU,0BA8BJ;AAEE;AAAA,EAAR,EAAM;AAAA,GAhCI,0BAgCF;AAGD;AAAA,EADP,EAAM;AAAA,GAlCI,0BAmCH;AAGA;AAAA,EADP,EAAM;AAAA,GArCI,0BAsCH;;;AC/CV,IAAO,wCAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMR,IAAM,uBAAN,cAAmC,YAAY;AAAA,EAA/C;AAAA;AAGL,SAAQ,SAAS;AACjB,SAAQ,yBAAwC;AAIM,eAAM;AACN,eAAM;AACb,gBAAO;AAAA;AAAA,EATtD;AAAA,SAAgB,SAAyB;AAAA;AAAA,EAWzC,WAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EAES,oBAAoB;AAC3B,UAAM,kBAAkB;AACxB,SAAK,aAAa,KAAK,GAAG;AAC1B,SAAK,aAAa,YAAY,GAAG;AACjC,SAAK,aAAa,QAAQ,QAAQ;AAAA,EACpC;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEA,IAAI,SAAS,KAAa;AACxB,UAAM,WAAW,SAAS,KAAK,EAAE;AACjC,QAAI,CAAC,MAAM,QAAQ,GAAG;AACpB,WAAK,aAAa,QAAQ;AAAA,IAC5B;AAAA,EACF;AAAA,EAEgB,sBAAsB,MAAe;AACnD,UAAM,mBAAmB,KAAK;AAC9B,QAAI,CAAC,kBAAkB,gBAAiB;AAExC,QAAI,MAAM;AACR,WAAK,mBAAmB,iBAAiB,gBAAgB,SAAS;AAClE,YAAM,KAAK,WAAW,iBAAiB,gBAAgB,SAAS,CAAC;AACjE,UAAI,CAAC,MAAM,EAAE,GAAG;AACd,aAAK,yBAAyB;AAC9B,cAAM,mBAAoB,KAAK,yBAAyB,KAAK,QAAQ,KAAK,MAAM,KAAK,OAAQ;AAC7F,aAAK,MAAM,YAAY,8BAA8B,GAAG,eAAe,GAAG;AAAA,MAC5E,OAAO;AACL,aAAK,yBAAyB;AAAA,MAChC;AAAA,IACF,OAAO;AACL,WAAK,yBAAyB;AAAA,IAChC;AACA,SAAK,cAAc;AAAA,EACrB;AAAA,EAEQ,aAAa,UAAkB;AACrC,UAAM,WAAW,KAAK;AACtB,SAAK,SAAS,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,QAAQ,CAAC;AAC7D,QAAI,KAAK,WAAW,UAAU;AAC5B;AAAA,IACF;AACA,UAAM,mBAAoB,KAAK,SAAS,KAAK,QAAQ,KAAK,MAAM,KAAK,OAAQ;AAC7E,SAAK,MAAM,YAAY,sBAAsB,GAAG,eAAe,GAAG;AAClE,SAAK,WAAW,aAAa,KAAK,KAAK;AACvC,SAAK,aAAa,KAAK,QAAQ;AAC/B,SAAK,cAAc;AAAA,EACrB;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA,iBAIM,KAAK,GAAG;AAAA,iBACR,KAAK,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,gDAKuB,KAAK,YAAY,gBAAgB,KAAK,aAAa;AAAA;AAAA,2CAExD,KAAK,QAAQ;AAAA;AAAA;AAAA,YAG5C,KAAK,2BAA2B,OAC9B;AAAA;AAAA,iDAEmC,KAAK,sBAAsB;AAAA;AAAA,kBAG9D,IAAI;AAAA;AAAA;AAAA;AAAA,EAIhB;AAAA,EAEQ,aAAa,OAAmB;AACtC,SAAK,WAAW,MAAM,KAAK;AAC3B,UAAM,kBAAkB,CAACC,OAAkB,KAAK,QAAQA,GAAE,KAAK;AAC/D,UAAM,gBAAgB,MAAM;AAC1B,eAAS,oBAAoB,aAAa,eAAe;AACzD,eAAS,oBAAoB,WAAW,aAAa;AACrD,WAAK,WAAW;AAAA,IAClB;AAEA,aAAS,iBAAiB,aAAa,eAAe;AACtD,aAAS,iBAAiB,WAAW,aAAa;AAAA,EACpD;AAAA,EAEQ,cAAc,OAAmB;AACvC,SAAK,WAAW,MAAM,QAAQ,CAAC,EAAE,KAAK;AACtC,UAAM,kBAAkB,CAACA,OAAkB,KAAK,QAAQA,GAAE,QAAQ,CAAC,EAAE,KAAK;AAC1E,UAAM,iBAAiB,MAAM;AAC3B,eAAS,oBAAoB,aAAa,eAAe;AACzD,eAAS,oBAAoB,YAAY,cAAc;AACvD,WAAK,WAAW;AAAA,IAClB;AAEA,aAAS,iBAAiB,aAAa,iBAAiB,EAAE,SAAS,MAAM,CAAC;AAC1E,aAAS,iBAAiB,YAAY,cAAc;AAAA,EACtD;AAAA,EAEQ,WAAW,OAAe;AAChC,SAAK,QAAQ,KAAK;AAAA,EACpB;AAAA,EAEQ,QAAQ,OAAe;AAC7B,UAAM,WAAW,KAAK,MAAM,sBAAsB;AAClD,UAAM,QAAQ,QAAQ,SAAS;AAC/B,UAAM,aAAa,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,SAAS,KAAK,CAAC;AAClE,UAAM,eAAe,KAAK,MAAM,KAAK,MAAO,cAAc,KAAK,MAAM,KAAK,OAAQ,KAAK,IAAI,IAAI,KAAK;AACpG,SAAK,aAAa,YAAY;AAAA,EAChC;AAAA,EAEQ,aAAa;AACnB,SAAK,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,EAC3D;AACF;AAlI0B;AAAA,EAAvB,EAAM,OAAO;AAAA,GANH,qBAMa;AAE8B;AAAA,EAArD,EAAS,EAAE,MAAM,QAAQ,WAAW,cAAc,CAAC;AAAA,GARzC,qBAQ2C;AACA;AAAA,EAArD,EAAS,EAAE,MAAM,QAAQ,WAAW,cAAc,CAAC;AAAA,GATzC,qBAS2C;AACP;AAAA,EAA9C,EAAS,EAAE,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,GAVlC,qBAUoC;;;ACPpC,IAAAC,KAAY,MAAmB,IAAIC;AAKhD,IAAMA,IAAN,MAAMA;AAAAA;AAmBN,IAAMC,KAAmC,oBAAIC;AAA7C,IAqHaC,KAAMC,GA9GnB,cAA2BC,EAAAA;EAKzB,OAAOC,IAAAA;AACL,WAAOC;EACR;EAEQ,OAAOC,IAAAA,CAAoBL,EAAAA,GAAAA;AAClC,UAAMM,KAAaN,OAAQO,KAAKJ;AAahC,WAZIG,MAAAA,WAAcC,KAAKJ,KAGrBI,KAAKC,GAAAA,MAAgBC,IAEnBH,MAAcC,KAAKG,OAAuBH,KAAKI,QAGjDJ,KAAKJ,IAAOH,IACZO,KAAKK,KAAWP,GAAKQ,SAASC,MAC9BP,KAAKC,GAAiBD,KAAKI,KAAWN,GAAKU,OAAAA,IAEtCX;EACR;EAEO,GAAgBW,IAAAA;AAItB,QAHKR,KAAKS,gBACRD,KAAAA,SAEuB,cAAA,OAAdR,KAAKJ,GAAqB;AAUnC,YAAMc,KAAUV,KAAKK,MAAYM;AACjC,UAAIC,KACFrB,GAAiCsB,IAAIH,EAAAA;AAAAA,iBACnCE,OACFA,KAAyB,oBAAIpB,WAC7BD,GAAiCuB,IAAIJ,IAASE,EAAAA,IAAAA,WAE5CA,GAAuBC,IAAIb,KAAKJ,CAAAA,KAClCI,KAAKJ,EAAKmB,KAAKf,KAAKK,IAAAA,MAAUH,GAEhCU,GAAuBE,IAAId,KAAKJ,GAAMY,EAAAA,GAAAA,WAElCA,MACFR,KAAKJ,EAAKmB,KAAKf,KAAKK,IAAUG,EAAAA;IAEjC,MACER,MAAKJ,EAAsBoB,QAAQR;EAEvC;EAED,IAAA,KAAYL;AACV,WAA4B,cAAA,OAAdH,KAAKJ,IACfL,GACGsB,IAAIb,KAAKK,MAAYM,UAAAA,GACpBE,IAAIb,KAAKJ,CAAAA,IACbI,KAAKJ,GAAMoB;EAChB;EAEQ,eAAAC;AAKHjB,SAAKG,OAAuBH,KAAKI,MACnCJ,KAAKC,GAAAA,MAAgBC;EAExB;EAEQ,cAAAgB;AAGPlB,SAAKC,GAAgBD,KAAKI,EAAAA;EAC3B;AAAA,CAAA;;;AC1HH,IAAO,4CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACSR,IAAM,0BAAN,cAAsC,YAAY;AAAA,EAAlD;AAAA;AAEL,oBAAWe,GAA4B;AAWvC,oBAA0B;AAK1B,SAAU,qBAAqB,MAAM;AAGnC,WAAK,WAAW,aAAa,KAAK,KAAK;AACvC,WAAK,SAAS;AAAA,IAChB;AAAA;AAAA,EAtBA;AAAA,SAAgB,SAAyB;AAAA;AAAA,EAwBzC,IAAa,QAAuB;AAClC,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EACA,IAAa,MAAM,KAAoB;AACrC,SAAK,WAAW,OAAO;AAAA,EACzB;AAAA,EAEA,IAAa,cAA4C;AACvD,UAAM,mBAAmB,KAAK;AAE9B,QAAI,CAAC,kBAAkB;AACrB,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,UAAU,MAAM;AACnC;AAAA,IACF;AAEA,QAAI,iBAAiB,SAAS;AAC5B,YAAM,WAAW,iBAAiB,QAAQ,WAAW;AAAA,QACnD,CAAC,YAAY,aAAa,KAAK,IAAI,SAAS,aAAa,UAAU;AAAA,QACnE;AAAA,MACF;AACA,iBAAW,YAAY,iBAAiB,QAAQ,YAAY;AAC1D,YAAI,YAAY,SAAS;AACzB,YAAI,iBAAiB,iBAAiB;AACtC,YAAI,CAAC,SAAS,eAAe;AAC3B,sBAAY,UAAU,YAAY;AAClC,2BAAiB,eAAe,YAAY;AAAA,QAC9C;AACA,YAAI,cAAc,gBAAgB;AAChC,cAAI,SAAS,gBAAgB,UAAU;AACrC;AAAA,UACF;AACA,cAAI,SAAS,gBAAgB,iBAAiB,QAAQ,gBAAgB,IAAI;AACxE;AAAA,UACF;AACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAIA,WAAO,iBAAiB,oBAAoB,iBAAiB;AAAA,EAC/D;AAAA,EAEA,IAAa,WAAoB;AAC/B,WAAO;AAAA,EACT;AAAA,EAEgB,WAAoB;AAClC,QAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,QAAI,KAAK,eAAe,KAAK,wBAAwB;AAEnD,WAAK,WAAW,YAAY,CAAC,CAAC;AAC9B,WAAK,OAAO,kBAAkB,EAAE;AAChC,YAAM,UAAU,KAAK,OAAO,cAAc;AAC1C,UAAI,CAAC,SAAS;AAEZ,aAAK,WAAW,YAAY,EAAE,aAAa,KAAK,GAAG,KAAK,sBAAsB;AAC9E,aAAK,OAAO,kBAAkB,KAAK,sBAAsB;AAAA,MAC3D;AAAA,IACF,OAAO;AACL,YAAM,UAAU,KAAK,OAAO,cAAc;AAC1C,WAAK,WAAW,YAAY,UAAU,CAAC,IAAI,EAAE,aAAa,MAAM,CAAC;AAAA,IACnE;AACA,WAAO,KAAK,aAAa,MAAM,KAAK,OAAO,cAAc;AAAA,EAC3D;AAAA,EAEgB,8BAA8B,MAAqB;AACjE,UAAM,mBAAmB,KAAK;AAE9B,QAAI,QAAQ,kBAAkB,iBAAiB;AAC7C,YAAM,OAAO,iBAAiB,gBAAgB,SAAS;AACvD,WAAK,mBAAmB;AAAA,IAmB1B,OAAO;AAEL,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA,gBAGK,KAAK,kBAAkB;AAAA;AAAA;AAAA,iBAGtB,CAAC,MAAkB;AAC1B,WAAK,eAAe;AAAA,IACtB,CAAC;AAAA,oBACW,CAAC,UAAyB,MAAM,yBAAyB,CAAC;AAAA,kBAC5D,KAAK,WAAW;AAAA,mBACf,KAAK,WAAW;AAAA,gBACnB,KAAK,eAAe,WAAW,WAAW,MAAM;AAAA,uBACzCC,GAAU,KAAK,kBAAkB,KAAK,kBAAkB,MAAS,CAAC;AAAA,kBACvE,KAAK,QAAQ;AAAA,mBACZA,GAAU,KAAK,cAAc,KAAK,cAAc,MAAS,CAAC;AAAA,oBACzD,GAAI;AAAA,qBACH,KAAK,QAAQ;AAAA,qBACb,KAAK,QAAQ;AAAA;AAAA,QAE1B,KAAK,mBAAmB,wBAA2B,KAAK,gBAAgB,WAAW,CAAO;AAAA;AAAA,EAEhG;AAAA;AAAA,EAGU,YAAY,OAAoB;AACxC,QAAI,KAAK,YAAY,KAAK,SAAU;AACpC,UAAM,QAAQ,MAAM;AACpB,SAAK,kBAAkB,MAAM,KAAK;AAClC,QAAI,KAAK,aAAa,MAAM,OAAO;AACjC,WAAK,QAAQ,MAAM;AACnB,WAAK,aAAa,MAAM,KAAK;AAAA,IAC/B;AAAA,EACF;AAAA,EAES,iBAA0B;AACjC,UAAM,QAAQ,KAAK,WAAW,cAAc,OAAO;AACnD,QAAI,CAAC,MAAO,QAAO;AAGnB,UAAM,UAAU,KAAK,SAAS;AAC9B,QAAI,CAAC,SAAS;AACZ,YAAM,eAAe;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AAAA,EAES,QAAc;AACrB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,kBAAkB,MAAoB;AAC5C,SAAK,aAAa,SAAS,SAAS,KAAK,SAAS,OAAO;AAAA,EAC3D;AACF;AAhL4D;AAAA,EAAzD,EAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB,CAAC;AAAA,GAJ7C,wBAI+C;AAEH;AAAA,EAAtD,EAAS,EAAE,MAAM,QAAQ,WAAW,eAAe,CAAC;AAAA,GAN1C,wBAM4C;AAEI;AAAA,EAA1D,EAAS,EAAE,MAAM,QAAQ,WAAW,mBAAmB,CAAC;AAAA,GAR9C,wBAQgD;AAEQ;AAAA,EAAlE,EAAS,EAAE,MAAM,QAAQ,WAAW,2BAA2B,CAAC;AAAA,GAVtD,wBAUwD;AAGnE;AAAA,EADC,EAAM;AAAA,GAZI,wBAaX;AAEwB;AAAA,EAAvB,EAAM,OAAO;AAAA,GAfH,wBAea;AAGd;AAAA,EADT,MAAM,YAAY,EAAE,sBAAsB,KAAK,CAAC;AAAA,GAjBtC,wBAkBD;;;AC1BL,IAAM,uBAAN,cAAmC,YAAY;AAAA,EAA/C;AAAA;AACL,SAAQ,QAAqB;AAC7B,SAAQ,UAAyB;AAAA;AAAA,EAExB,QAAQ;AACf,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,aAAa,IAAI;AAAA,EACxB;AAAA,EAEA,WAAoB;AAClB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,IAAI,WAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAS,QAAuB;AAClC,QAAI,OAAO,WAAW,UAAU;AAC9B,WAAK,UAAU;AACf,WAAK,aAAa,MAAM;AAAA,IAC1B,WAAW,WAAW,MAAM;AAC1B,WAAK,MAAM;AAAA,IACb,OAAO;AACL,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,WAAoB,aAAa;AAC/B,WAAO;AAAA,MACL,GAAG,YAAY;AAAA,IACjB;AAAA,EACF;AAAA,EAEA;AAAA,SAAgB,SAAS;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUF;AAAA;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA,sCAG2B,KAAK,aAAa,gBAAgB,KAAK,QAAQ,gBAAgB,KAAK,QAAQ;AAAA;AAAA;AAAA,EAGhH;AAAA,EAEA,MAAc,cAAc,OAAc;AACxC,UAAM,QAAQ,MAAM;AACpB,QAAI,MAAM,SAAS,MAAM,MAAM,SAAS,GAAG;AACzC,WAAK,QAAQ,MAAM,MAAM,CAAC;AAC1B,WAAK,UAAU,MAAM,KAAK,iBAAiB,KAAK,KAAK;AACrD,WAAK,aAAa,KAAK,OAAO;AAC9B,WAAK;AAAA,QACH,IAAI,YAAY,4BAA4B;AAAA,UAC1C,QAAQ,EAAE,UAAU,KAAK,QAAQ;AAAA,QACnC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,MAA6B;AACpD,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,SAAS,IAAI,WAAW;AAC9B,aAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,aAAO,UAAU,MAAM,OAAO,OAAO,KAAK;AAC1C,aAAO,cAAc,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH;AACF;;;ACjFO,IAAM,uBAAN,cAAmCC,GAAW;AAAA,EACnD;AAAA,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhB,oBAAoB;AAC3B,UAAM,kBAAkB;AACxB,SAAK;AAAA,MACH,IAAI,YAAY,wBAAwB;AAAA,QACtC,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAES,SAAS;AAChB,WAAO;AAAA,EACT;AACF;;;ACtBO,IAAM,SAAN,cAAqBC,GAAW;AAAA,EAAhC;AAAA;AAQsC,oBAA+B;AAAA;AAAA,EAP1E;AAAA,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShB,SAAS;AAChB,WAAO;AAAA,EACT;AACF;AAL6C;AAAA,EAA1C,EAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAR9B,OAQgC;;;ACRtC,IAAM,YAAN,cAAwBC,GAAW;AAAA,EAAnC;AAAA;AAQsC,oBAA+B;AAAA;AAAA,EAP1E;AAAA,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShB,oBAAoB;AAC3B,SAAK,aAAa,QAAQ,OAAO;AAAA,EACnC;AACF;AAL6C;AAAA,EAA1C,EAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAR9B,UAQgC;;;ACS7C,IAAM,uBAAoE;AAAA,EACxE,aAAa,CAAC,UAAoB,QAAQ,SAAS;AAAA,EACnD,eAAe,CAAC,UAAyB,UAAU;AACrD;AAkBO,SAAS,mBAAsD,MAAS,MAAc;AAAA,EAC3F,MAAe,kBAAkB,KAAK;AAAA,IAiCpC,eAAe,MAAa;AAC1B,YAAM,GAAG,IAAI;AAhCf,WAAO,aAAa;AAGpB,WAAgB,WAAW;AAQ3B,WAAO,WAAW;AAQlB,WAAO,WAAW;AAchB,WAAK,YAAY,KAAK,gBAAgB;AAAA,IACxC;AAAA,IAVA,qBAAqB,WAAoB,UAAmB;AAC1D,WAAK,WAAW,WAAW,KAAK;AAChC,UAAI,UAAU;AACZ,aAAK,KAAK;AAAA,MACZ;AAAA,IACF;AAAA,IAOS,oBAAoB;AAC3B,YAAM,kBAAkB;AAGxB,WAAK,UAAU,cAAc;AAG7B,UAAI,KAAK,UAAU;AACjB,aAAK,WAAW;AAAA,MAClB;AAEA,WAAK,iBAAiB,SAAS,KAAK,QAAQ;AAC5C,WAAK,iBAAiB,SAAS,KAAK,QAAQ;AAE5C,WAAK;AAAA,QACH,IAAI,YAAY,YAAY,IAAI,IAAI;AAAA,UAClC,SAAS;AAAA,UACT,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAES,uBAAuB;AAC9B,YAAM,qBAAqB;AAC3B,WAAK,oBAAoB,SAAS,KAAK,QAAQ;AAC/C,WAAK,oBAAoB,SAAS,KAAK,QAAQ;AAC/C,WAAK;AAAA,QACH,IAAI,YAAY,cAAc,IAAI,IAAI;AAAA,UACpC,SAAS;AAAA,UACT,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEQ,SAAS,OAAsB;AACrC,UAAI,MAAM,OAAQ;AAElB,UAAI,MAAM,SAAS,WAAW,MAAM,SAAS,SAAS;AACpD,cAAM,eAAe;AACrB,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AAAA,IAEQ,WAAW;AACjB,UAAI,KAAK,YAAY,KAAK,SAAU;AACpC,WAAK,MAAM;AACX,WAAK,UAAU;AAAA,IACjB;AAAA,IAEQ,YAAY;AAClB,UAAI,KAAK,YAAY,KAAK,SAAU;AAEpC,WAAK;AAAA,QACH,IAAI,YAAoC,YAAY,IAAI,IAAI;AAAA,UAC1D,SAAS;AAAA,UACT,UAAU;AAAA,UACV,QAAQ,EAAE,YAAY,KAAK,WAAW;AAAA,QACxC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAES,SAAS;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AApGS;AAAA,IADN,EAAS,EAAE,MAAM,OAAO,CAAC;AAAA,KADb,UAEN;AAGS;AAAA,IADf,EAAS,EAAE,MAAM,QAAQ,SAAS,MAAM,WAAW,WAAW,CAAC;AAAA,KAJnD,UAKG;AAQT;AAAA,IANN,EAAS;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AAAA,KAZY,UAaN;AAQA;AAAA,IANN,EAAS;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AAAA,KApBY,UAqBN;AAKP;AAAA,IADC,MAAM,YAAY,EAAE,sBAAsB,KAAK,CAAC;AAAA,KAzBpC,UA0Bb;AA6EF,SAAO;AACT;;;AC7IO,IAAM,aAAN,cAAyB,mBAAmBC,IAAY,cAAc,EAAE;AAAA,EAAxE;AAAA;AAQsC,oBAA+B;AAAA;AAAA,EAP1E;AAAA,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShB,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,aAAa,QAAQ,OAAO;AAAA,EACnC;AAAA,EAES,SAAS;AAChB,WAAO;AAAA,EACT;AACF;AAV6C;AAAA,EAA1C,EAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAR9B,WAQgC;;;ACNtC,IAAM,mBAAN,cAA+B,mBAAmBC,IAAY,oBAAoB,EAAE;AAAA,EACzF;AAAA,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS3B;AAF2E;AAAA,EAAxE,EAAS,EAAE,WAAW,mBAAmB,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAR5D,iBAQ8D;AACO;AAAA,EAA/E,EAAS,EAAE,WAAW,0BAA0B,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GATnE,iBASqE;;;ACZ3E,IAAM,aAAN,cAAyB,mBAAmBC,IAAY,aAAa,EAAE;AAAA,EAC5E;AAAA,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,SAAS;AAChB,WAAO;AAAA;AAAA,EAET;AACF;;;ACbO,IAAM,kBAAN,cAA8BC,GAAW;AAAA,EAC9C,WAAoB,SAAS;AAC3B,WAAO;AAAA,MACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMF;AAAA,EACF;AAAA,EAKS,oBAAoB;AAC3B,UAAM,kBAAkB;AAExB,SAAK,iBAAiB,SAAS,KAAK,qBAAqB;AAEzD,SAAK;AAAA,MACH,IAAI,YAAY,8BAA8B;AAAA,QAC5C,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAES,uBAAuB;AAC9B,SAAK,oBAAoB,SAAS,KAAK,qBAAqB;AAAA,EAC9D;AAAA,EAES,SAAS;AAChB,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB;AAG9B,SAAK;AAAA,MACH,IAAI,YAAY,4BAA4B;AAAA,QAC1C,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,QAAQ,EAAE,YAAY,KAAK,WAAW;AAAA,MACxC,CAAC;AAAA,IACH;AAAA,EACF;AACF;AApCE;AAAA,EADC,EAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAZf,gBAaX;;;ACdK,IAAM,YAAN,cAAwBC,GAAW;AAAA,EAC/B,SAAS;AAChB,WAAO;AAAA,EACT;AAAA,EAES,oBAA0B;AAIjC,UAAM,gBAAgB,KAAK,cAAc,QAAQ,SAAS,aAAa;AACvE,QAAI,eAAe;AACjB,WAAK,aAAa,QAAQ,QAAQ;AAAA,IACpC;AAAA,EAEF;AACF;;;ACNO,IAAM,4BAAN,cAAwC,mBAAmBC,IAAY,8BAA8B,EAAE;AAAA,EAAvG;AAAA;AAoBL,SAAO,WAAmB;AAO1B,SAAO,WAAmB;AAU1B,SAAO,QAAiB;AAAA;AAAA,EApCxB;AAAA,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwChB,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,aAAa,QAAQ,8BAA8B;AACxD,SAAK,aAAa,QAAQ,8BAA8B;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOS,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA,EAIT;AACF;AAtCS;AAAA,EAJN,EAAS;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AAAA,GAnBU,0BAoBJ;AAOA;AAAA,EAJN,EAAS;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AAAA,GA1BU,0BA2BJ;AAUA;AAAA,EARN,EAAS;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,IACX,WAAW;AAAA,MACT,eAAe,CAAC,UAAyB,UAAU;AAAA,MACnD,aAAa,CAAC,UAAmB,OAAO,KAAK;AAAA,IAC/C;AAAA,EACF,CAAC;AAAA,GApCU,0BAqCJ;;;AC/CT;AAAA;AAAA;AAAA;AAEA,IAAO,mCAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACUR,IAAM,kBAAN,cAA8B,mBAAmBC,IAAY,mBAAmB,EAAE;AAAA,EAAlF;AAAA;AAIL,SAAO,qBAAoC;AAG3C,SAAO,WAA0B;AASjC,SAAO,QAAiB;AAAA;AAAA,EAfxB;AAAA,SAAgB,SAAyB;AAAA;AAAA,EAqBzC,IAAI,UAAU;AACZ,WAAO,KAAK,WAAW,EAAE,OAAO,IAAI,WAAW;AAAA,EACjD;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA,QAGH,KAAK,SAAS,oBAAuB,KAAK,MAAM,WAAW,CAAO;AAAA;AAAA,EAExE;AACF;AA7BS;AAAA,EADN,EAAS,EAAE,MAAM,QAAQ,WAAW,sBAAsB,CAAC;AAAA,GAHjD,gBAIJ;AAGA;AAAA,EADN,EAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GANvC,gBAOJ;AASA;AAAA,EAPN,EAAS;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,MACT,eAAe,CAAC,UAAyB,UAAU;AAAA,MACnD,aAAa,CAAC,UAAmB,OAAO,KAAK;AAAA,IAC/C;AAAA,EACF,CAAC;AAAA,GAfU,gBAgBJ;AAIA;AAAA,EADN,EAAS,EAAE,MAAM,QAAQ,WAAW,MAAM,CAAC;AAAA,GAnBjC,gBAoBJ;;;AC/BT,eAAe,OAAO,6BAA6B,uBAAuB;;;ACA1E,eAAe,OAAO,0BAA0B,oBAAoB;;;ACApE,eAAe,OAAO,0BAA0B,oBAAoB;;;ACApE,eAAe,OAAO,+BAA+B,wBAAwB;;;ACA7E,eAAe,OAAO,iCAAiC,0BAA0B;;;ACAjF,eAAe,OAAO,6BAA6B,sBAAsB;;;ACAzE,eAAe,OAAO,qCAAqC,8BAA8B;;;ACAzF,eAAe,OAAO,qCAAqC,6BAA6B;;;ACAxF,eAAe,OAAO,iCAAiC,0BAA0B;;;ACAjF,eAAe,OAAO,2BAA2B,qBAAqB;;;ACAtE,eAAe,OAAO,2BAA2B,qBAAqB;;;ACAtE,eAAe,OAAO,iCAAiC,0BAA0B;;;ACAjF,eAAe,OAAO,yBAAyB,mBAAmB;;;ACAlE,eAAe,OAAO,yBAAyB,mBAAmB;;;ACAlE,eAAe,OAAO,yBAAyB,mBAAmB;;;ACO3D,IAAM,mCAAN,cAA+C,6BAA6B;AAAA,EAA5E;AAAA;AACL,SAAQ,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM5B,MAAM,mBAAoC;AACxC,WAAO,IAAI,QAAQ,aAAW;AAC5B,YAAM,YAAY,eAAe,KAAK,IAAI,CAAC;AAE3C,YAAM,iBAAiB,CAAC,UAAwB;AAC9C,cAAM,EAAE,KAAK,IAAI;AACjB,YACE,MAAM,WAAW,qBAChB,CAAC,MAAM,sBAAsB,MAAM,uBAAuB,KAAK,uBAChE,MAAM,WAAW,wBACjB,MAAM,cAAc,WACpB;AACA,iBAAO,oBAAoB,WAAW,cAAc;AACpD,kBAAQ,KAAK,OAAO;AAAA,QACtB;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,cAAc;AAEjD,WAAK,oBAAoB,cAAc,EAAE,UAAU,CAAC;AAGpD,iBAAW,MAAM;AACf,eAAO,oBAAoB,WAAW,cAAc;AACpD,gBAAQ,EAAE;AAAA,MACZ,GAAG,GAAI;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAGO,eAAe,YAA+B;AACnD,SAAK,UAAU;AAGf,SAAK,eAAe,KAAK,MAAM;AAO7B,WAAK,QAAQ,YAAY,WAAW,KAAK,CAAAC,OAAKA,GAAE,eAAe,KAAK,kBAAkB,EAAE;AAAA,IAE1F,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,iBAAgC;AAC3C,SAAK,oBAAoB;AAEzB,QAAI;AAEF,UAAI,KAAK,QAAQ;AACf,aAAK,gBAAgB;AACrB,aAAK,OAAO,OAAO;AAAA,MACrB;AAEA,WAAK,mBAAmB,CAAC;AAGzB,WAAK,aAAa;AAGlB,aAAO,IAAI,QAAc,aAAW;AAClC,cAAM,cAAc,MAAM;AACxB,eAAK,oBAAoB,0CAA0C,WAAW;AAC9E,kBAAQ;AAAA,QACV;AAEA,aAAK,iBAAiB,0CAA0C,WAAW;AAG3E,mBAAW,MAAM;AACf,eAAK,oBAAoB,0CAA0C,WAAW;AAC9E,kBAAQ;AAAA,QACV,GAAG,GAAI;AAAA,MACT,CAAC;AAAA,IACH,UAAE;AACA,WAAK,oBAAoB;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKS,uBAA6B;AAGpC,QAAI,CAAC,KAAK,mBAAmB;AAC3B,YAAM,qBAAqB;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiBC,IAAW,GAA0B;AAC1D,WAAO,IAAI,QAAQ,aAAW;AAC5B,YAAM,YAAY,SAAS,KAAK,IAAI,CAAC;AAErC,YAAM,iBAAiB,CAAC,UAAwB;AAC9C,cAAM,EAAE,KAAK,IAAI;AACjB,YACE,MAAM,WAAW,qBAChB,CAAC,MAAM,sBAAsB,MAAM,uBAAuB,KAAK,uBAChE,MAAM,WAAW,mBACjB,MAAM,cAAc,WACpB;AACA,iBAAO,oBAAoB,WAAW,cAAc;AACpD,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,cAAc;AAEjD,WAAK,oBAAoB,iBAAiB,EAAE,GAAAA,IAAG,GAAG,UAAU,CAAC;AAG7D,iBAAW,MAAM;AACf,eAAO,oBAAoB,WAAW,cAAc;AACpD,gBAAQ;AAAA,MACV,GAAG,GAAI;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBAAqB,UAAoC;AAC7D,WAAO,IAAI,QAAQ,aAAW;AAC5B,YAAM,YAAY,kBAAkB,KAAK,IAAI,CAAC;AAE9C,YAAM,iBAAiB,CAAC,UAAwB;AAC9C,cAAM,EAAE,KAAK,IAAI;AACjB,YACE,MAAM,WAAW,qBAChB,CAAC,MAAM,sBAAsB,MAAM,uBAAuB,KAAK,uBAChE,MAAM,WAAW,2BACjB,MAAM,cAAc,WACpB;AACA,iBAAO,oBAAoB,WAAW,cAAc;AACpD,kBAAQ,KAAK,OAAO;AAAA,QACtB;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,cAAc;AAEjD,WAAK,oBAAoB,mBAAmB,EAAE,UAAU,UAAU,CAAC;AAGnE,iBAAW,MAAM;AACf,eAAO,oBAAoB,WAAW,cAAc;AACpD,gBAAQ,KAAK;AAAA,MACf,GAAG,GAAI;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,2BAA2B,MAAgC;AAC/D,WAAO,IAAI,QAAQ,aAAW;AAC5B,YAAM,YAAY,cAAc,KAAK,IAAI,CAAC;AAE1C,YAAM,iBAAiB,CAAC,UAAwB;AAC9C,cAAM,EAAE,KAAK,IAAI;AACjB,YACE,MAAM,WAAW,qBAChB,CAAC,MAAM,sBAAsB,MAAM,uBAAuB,KAAK,uBAChE,MAAM,WAAW,uBACjB,MAAM,cAAc,WACpB;AACA,iBAAO,oBAAoB,WAAW,cAAc;AACpD,kBAAQ,KAAK,OAAO;AAAA,QACtB;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,cAAc;AAEjD,WAAK,oBAAoB,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAGpE,iBAAW,MAAM;AACf,eAAO,oBAAoB,WAAW,cAAc;AACpD,gBAAQ,KAAK;AAAA,MACf,GAAG,GAAI;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,sBAAsB,UAAkB,OAAiC;AAC7E,WAAO,IAAI,QAAQ,aAAW;AAC5B,YAAM,YAAY,aAAa,KAAK,IAAI,CAAC;AAEzC,YAAM,iBAAiB,CAAC,UAAwB;AAC9C,cAAM,EAAE,KAAK,IAAI;AACjB,YACE,MAAM,WAAW,qBAChB,CAAC,MAAM,sBAAsB,MAAM,uBAAuB,KAAK,uBAChE,MAAM,WAAW,sBACjB,MAAM,cAAc,WACpB;AACA,iBAAO,oBAAoB,WAAW,cAAc;AACpD,kBAAQ,KAAK,OAAO;AAAA,QACtB;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,cAAc;AAEjD,WAAK,oBAAoB,mBAAmB,EAAE,UAAU,OAAO,UAAU,CAAC;AAG1E,iBAAW,MAAM;AACf,eAAO,oBAAoB,WAAW,cAAc;AACpD,gBAAQ,KAAK;AAAA,MACf,GAAG,GAAI;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,4BAA4B,MAAc,OAAiC;AAC/E,WAAO,IAAI,QAAQ,aAAW;AAC5B,YAAM,YAAY,kBAAkB,KAAK,IAAI,CAAC;AAE9C,YAAM,iBAAiB,CAAC,UAAwB;AAC9C,cAAM,EAAE,KAAK,IAAI;AACjB,YACE,MAAM,WAAW,qBAChB,CAAC,MAAM,sBAAsB,MAAM,uBAAuB,KAAK,uBAChE,MAAM,WAAW,4BACjB,MAAM,cAAc,WACpB;AACA,iBAAO,oBAAoB,WAAW,cAAc;AACpD,kBAAQ,KAAK,OAAO;AAAA,QACtB;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,cAAc;AAEjD,WAAK,oBAAoB,yBAAyB,EAAE,MAAM,OAAO,UAAU,CAAC;AAG5E,iBAAW,MAAM;AACf,eAAO,oBAAoB,WAAW,cAAc;AACpD,gBAAQ,KAAK;AAAA,MACf,GAAG,GAAI;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,yBAAyB,UAAoC;AACjE,WAAO,IAAI,QAAQ,aAAW;AAC5B,YAAM,YAAY,sBAAsB,KAAK,IAAI,CAAC;AAElD,YAAM,iBAAiB,CAAC,UAAwB;AAC9C,cAAM,EAAE,KAAK,IAAI;AACjB,YACE,MAAM,WAAW,qBAChB,CAAC,MAAM,sBAAsB,MAAM,uBAAuB,KAAK,uBAChE,MAAM,WAAW,+BACjB,MAAM,cAAc,WACpB;AACA,iBAAO,oBAAoB,WAAW,cAAc;AACpD,kBAAQ,KAAK,OAAO;AAAA,QACtB;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,cAAc;AAEjD,WAAK,oBAAoB,uBAAuB,EAAE,UAAU,UAAU,CAAC;AAGvE,iBAAW,MAAM;AACf,eAAO,oBAAoB,WAAW,cAAc;AACpD,gBAAQ,KAAK;AAAA,MACf,GAAG,GAAI;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMS,wBAAgC;AAEvC,UAAM,kBAAkB,MAAM,sBAAsB;AAGpD,UAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoMrB,UAAM,iBAAiB,gBAAgB,YAAY,WAAW;AAG9D,UAAM,kBACJ,gBAAgB,UAAU,GAAG,cAAc,IAAI,eAAe,gBAAgB,UAAU,cAAc;AAExG,WAAO;AAAA,EACT;AACF;;;AChhBA,eAAe,OAAO,mCAAmC,4BAA4B;AACrF,eAAe,OAAO,wCAAwC,gCAAgC;;;ACD9F,eAAe,OAAO,mCAAmC,4BAA4B;AACrF,eAAe,OAAO,6BAA6B,sBAAsB;;;ACHzE,eAAe,OAAO,gCAAgC,yBAAyB;;;ACA/E,eAAe,OAAO,0BAA0B,oBAAoB;;;ACApE,eAAe,OAAO,8BAA8B,uBAAuB;;;ACA3E,eAAe,OAAO,0BAA0B,oBAAoB;;;ACApE,eAAe,OAAO,0BAA0B,oBAAoB;;;ACApE,eAAe,OAAO,WAAW,MAAM;;;ACAvC,eAAe,OAAO,eAAe,SAAS;;;ACA9C,eAAe,OAAO,gBAAgB,UAAU;;;ACAhD,eAAe,OAAO,sBAAsB,gBAAgB;;;ACA5D,eAAe,OAAO,eAAe,UAAU;;;ACA/C,eAAe,OAAO,qBAAqB,eAAe;;;ACA1D,eAAe,OAAO,cAAc,SAAS;;;ACA7C,eAAe,OAAO,gCAAgC,yBAAyB;;;ACA/E,eAAe,OAAO,qBAAqB,eAAe;","names":["e","x","v","i","c","i","c","e","iframe","i","o","x","m","generateMap","list","start","end","map","Map","i","set","repeat","directive","Directive","partInfo","super","type","PartType","CHILD","Error","items","keyFnOrTemplate","template","keyFn","keys","values","index","item","this","_getValuesAndKeys","containerPart","oldParts","getCommittedValue","newValues","newKeys","Array","isArray","_itemKeys","oldKeys","newParts","newKeyToIndexMap","oldKeyToIndexMap","oldHead","oldTail","length","newHead","newTail","setChildPartValue","insertPart","has","oldIndex","get","oldPart","newPart","removePart","setCommittedValue","noChange","i","p","o","c","e","i","s","e","s","e","i","hotspot","s","e","s","UnsafeHTMLDirective","Directive","partInfo","super","this","_value","nothing","type","PartType","CHILD","Error","constructor","directiveName","value","_templateResult","noChange","strings","raw","_$litType$","resultType","values","unsafeHTML","directive","o","i","e","v","x","m","o","i","r","v","e","v","i","i","important","importantFlag","styleMap","directive","Directive","partInfo","super","type","PartType","ATTRIBUTE","name","strings","length","Error","styleInfo","Object","keys","reduce","style","prop","value","includes","replace","toLowerCase","part","element","this","_previousStyleProperties","Set","render","delete","removeProperty","add","isImportant","endsWith","setProperty","slice","noChange","x","r","e","c","o","i","e","createRef","Ref","lastElementForContextAndCallback","WeakMap","ref","directive","AsyncDirective","_ref","nothing","part","refChanged","this","_updateRefValue","undefined","_lastElementForRef","_element","_context","options","host","element","isConnected","context","globalThis","lastElementForCallback","get","set","call","value","disconnected","reconnected","e","o","i","i","i","i","i","i","i","i","i","i","v","x"]}