@citolab/qti-components 7.27.2 → 7.27.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.
- package/cdn/index.global.js +1 -1
- package/cdn/index.js +216 -202
- package/dist/base.js +1 -1
- package/dist/{chunk-QUWFDFGZ.js → chunk-3XXXAWMZ.js} +18 -18
- package/dist/{chunk-TORB5UN2.js → chunk-A7HX4462.js} +291 -242
- package/dist/chunk-A7HX4462.js.map +1 -0
- package/dist/{chunk-KY3II5OX.js → chunk-CSYOTHK2.js} +220 -189
- package/dist/chunk-CSYOTHK2.js.map +1 -0
- package/dist/{chunk-G5ZUC3OT.js → chunk-CVB5ISWF.js} +23 -23
- package/dist/chunk-CVB5ISWF.js.map +1 -0
- package/dist/{chunk-TZMDZQFG.js → chunk-D6EHVZG2.js} +467 -217
- package/dist/chunk-D6EHVZG2.js.map +1 -0
- package/dist/{chunk-DG5TP35K.js → chunk-DGIXWHK3.js} +5 -5
- package/dist/{chunk-DG5TP35K.js.map → chunk-DGIXWHK3.js.map} +1 -1
- package/dist/{chunk-GG36UR7F.js → chunk-PHCCFYNE.js} +12 -12
- package/dist/{chunk-GG36UR7F.js.map → chunk-PHCCFYNE.js.map} +1 -1
- package/dist/{chunk-75ME6QG5.js → chunk-WMPG7ULB.js} +17 -17
- package/dist/elements.js +3 -3
- package/dist/index.js +8 -8
- package/dist/interactions.d.ts +8 -7
- package/dist/interactions.js +3 -3
- package/dist/item.js +3 -3
- package/dist/processing.js +2 -2
- package/dist/qti-components-jsx.d.ts +202 -202
- package/dist/test.js +5 -5
- package/package.json +11 -11
- package/dist/chunk-G5ZUC3OT.js.map +0 -1
- package/dist/chunk-KY3II5OX.js.map +0 -1
- package/dist/chunk-TORB5UN2.js.map +0 -1
- package/dist/chunk-TZMDZQFG.js.map +0 -1
- /package/dist/{chunk-QUWFDFGZ.js.map → chunk-3XXXAWMZ.js.map} +0 -0
- /package/dist/{chunk-75ME6QG5.js.map → chunk-WMPG7ULB.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../interactions/core/src/elements/qti-associable-hotspot/qti-associable-hotspot.ts","../../interactions/core/src/elements/qti-gap/qti-gap.ts","../../interactions/core/src/elements/qti-gap-img/qti-gap-img.ts","../../interactions/core/src/mixins/active-element/active-element.mixin.ts","../../interactions/core/src/elements/qti-gap-text/qti-gap-text.ts","../../interactions/core/src/elements/qti-hotspot-choice/qti-hotspot-choice.ts","../../interactions/core/src/elements/qti-hottext/qti-hottext.ts","../../interactions/core/src/elements/qti-inline-choice/qti-inline-choice.styles.ts","../../interactions/core/src/elements/qti-inline-choice/qti-inline-choice.ts","../../interactions/core/src/elements/qti-prompt/qti-prompt.ts","../../interactions/core/src/elements/qti-simple-associable-choice/qti-simple-associable-choice.ts","../../interactions/core/src/elements/qti-simple-choice/qti-simple-choice.styles.ts","../../interactions/core/src/elements/qti-simple-choice/qti-simple-choice.ts","../../../node_modules/.pnpm/observable-polyfill@0.0.29/node_modules/observable-polyfill/observable.js","../../interactions/core/src/mixins/drag-drop-observables/utils/collision.utils.ts","../../interactions/core/src/mixins/drag-drop-observables/utils/drag-drop.utils.ts","../../interactions/core/src/mixins/drag-drop-observables/drag-drop-core.mixin.ts","../../interactions/core/src/mixins/drag-drop-observables/utils/flip.utils.ts","../../interactions/core/src/mixins/drag-drop-observables/drag-drop-slotted.mixin.ts","../../interactions/core/src/mixins/drag-drop-observables/strategies/sorting.strategy.ts","../../interactions/core/src/mixins/drag-drop-observables/utils/sortable.utils.ts","../../interactions/core/src/mixins/drag-drop-observables/drag-drop-slotted-sortable.mixin.ts","../../interactions/associate-interaction/src/qti-associate-interaction.styles.ts","../../interactions/associate-interaction/src/qti-associate-interaction.ts","../../interactions/core/src/mixins/choices/choices.mixin.ts","../../interactions/core/src/mixins/vocabulary/vocabulary-mixin.ts","../../interactions/choice-interaction/src/qti-choice-interaction.styles.ts","../../interactions/choice-interaction/src/qti-choice-interaction.ts","../../interactions/custom-interaction/src/qti-custom-interaction.styles.ts","../../interactions/custom-interaction/src/qti-custom-interaction.ts","../../interactions/end-attempt-interaction/src/qti-end-attempt-interaction.styles.ts","../../interactions/end-attempt-interaction/src/qti-end-attempt-interaction.ts","../../interactions/extended-text-interaction/src/qti-extended-text-interaction.styles.ts","../../interactions/extended-text-interaction/src/qti-extended-text-interaction.ts","../../interactions/gap-match-interaction/src/qti-gap-match-interaction.styles.ts","../../interactions/gap-match-interaction/src/qti-gap-match-interaction.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/repeat.ts","../../interactions/core/src/internal/hotspots/hotspot.ts","../../interactions/graphic-associate-interaction/src/qti-graphic-associate-interaction.styles.ts","../../interactions/graphic-associate-interaction/src/qti-graphic-associate-interaction.ts","../../interactions/graphic-gap-match-interaction/src/qti-graphic-gap-match-interaction.styles.ts","../../interactions/graphic-gap-match-interaction/src/qti-graphic-gap-match-interaction.ts","../../interactions/graphic-order-interaction/src/qti-graphic-order-interaction.styles.ts","../../interactions/graphic-order-interaction/src/qti-graphic-order-interaction.ts","../../interactions/hotspot-interaction/src/qti-hotspot-interaction.styles.ts","../../interactions/hotspot-interaction/src/qti-hotspot-interaction.ts","../../interactions/hottext-interaction/src/qti-hottext-interaction.styles.ts","../../interactions/hottext-interaction/src/qti-hottext-interaction.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/unsafe-html.ts","../../interactions/inline-choice-interaction/src/qti-inline-choice-interaction.styles.ts","../../interactions/inline-choice-interaction/src/qti-inline-choice-interaction.ts","../../interactions/match-interaction/src/qti-match-interaction.styles.ts","../../interactions/match-interaction/src/qti-match-interaction.ts","../../interactions/media-interaction/src/qti-media-interaction.styles.ts","../../interactions/media-interaction/src/qti-media-interaction.ts","../../interactions/order-interaction/src/qti-order-interaction.styles.ts","../../interactions/order-interaction/src/qti-order-interaction.ts","../../interactions/portable-custom-interaction/src/qti-portable-custom-interaction.styles.ts","../../interactions/portable-custom-interaction/src/qti-portable-custom-interaction.ts","../../interactions/position-object-interaction/src/qti-position-object-interaction.styles.ts","../../interactions/position-object-interaction/src/qti-position-object-interaction.ts","../../interactions/position-object-interaction/src/qti-position-object-stage.styles.ts","../../interactions/position-object-interaction/src/qti-position-object-stage.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/style-map.ts","../../interactions/select-point-interaction/src/qti-select-point-interaction.styles.ts","../../interactions/select-point-interaction/src/qti-select-point-interaction.ts","../../interactions/slider-interaction/src/qti-slider-interaction.styles.ts","../../interactions/slider-interaction/src/qti-slider-interaction.ts","../../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/src/directives/ref.ts","../../interactions/text-entry-interaction/src/qti-text-entry-interaction.styles.ts","../../interactions/text-entry-interaction/src/qti-text-entry-interaction.ts","../../interactions/upload-interaction/src/qti-upload-interaction.styles.ts","../../interactions/upload-interaction/src/qti-upload-interaction.ts","../../interactions/core/src/elements/qti-associable-hotspot/register.ts","../../interactions/core/src/elements/qti-gap/register.ts","../../interactions/core/src/elements/qti-gap-img/register.ts","../../interactions/core/src/elements/qti-gap-text/register.ts","../../interactions/core/src/elements/qti-hotspot-choice/register.ts","../../interactions/core/src/elements/qti-hottext/register.ts","../../interactions/core/src/elements/qti-inline-choice/register.ts","../../interactions/core/src/elements/qti-prompt/register.ts","../../interactions/core/src/elements/qti-simple-associable-choice/register.ts","../../interactions/core/src/elements/qti-simple-choice/register.ts","../../interactions/associate-interaction/src/register.ts","../../interactions/choice-interaction/src/register.ts","../../interactions/custom-interaction/src/register.ts","../../interactions/end-attempt-interaction/src/register.ts","../../interactions/extended-text-interaction/src/register.ts","../../interactions/gap-match-interaction/src/register.ts","../../interactions/graphic-associate-interaction/src/register.ts","../../interactions/graphic-gap-match-interaction/src/register.ts","../../interactions/graphic-order-interaction/src/register.ts","../../interactions/hotspot-interaction/src/register.ts","../../interactions/hottext-interaction/src/register.ts","../../interactions/inline-choice-interaction/src/register.ts","../../interactions/match-interaction/src/register.ts","../../interactions/media-interaction/src/register.ts","../../interactions/order-interaction/src/register.ts","../../interactions/portable-custom-interaction/src/qti-portable-custom-test-interaction.ts","../../interactions/portable-custom-interaction/src/register.ts","../../interactions/position-object-interaction/src/register.ts","../../interactions/select-point-interaction/src/register.ts","../../interactions/slider-interaction/src/register.ts","../../interactions/text-entry-interaction/src/register.ts","../../interactions/upload-interaction/src/register.ts"],"sourcesContent":["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 } from 'lit';\n\nimport type { CSSResultGroup } from 'lit';\n\nconst styles: CSSResultGroup = css`\n :host {\n display: block;\n box-sizing: border-box;\n }\n\n slot {\n display: inline;\n }\n`;\n\nexport default styles;\n","import { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ActiveElementMixin } from '../../mixins/active-element/active-element.mixin.js';\nimport styles from './qti-inline-choice.styles.js';\n\nimport type { CSSResultGroup } from 'lit';\nimport type { PropertyValues } from 'lit';\nexport class QtiInlineChoice extends ActiveElementMixin(LitElement, 'qti-inline-choice') {\n static override styles: CSSResultGroup = styles;\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 #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","// getting a reference of some used global objects as globalThis is getting undefined when a iframe is removed\nconst { AbortController, AbortSignal, WeakMap, WeakRef, Window, reportError = console.log } = globalThis;\n\n// https://html.spec.whatwg.org/multipage/document-sequences.html#fully-active\n// A Document d is said to be fully active when d is the active document of\n// a navigable navigable, and either navigable is a top-level traversable or\n// navigable's container document is fully active.\nconst isDocumentFullyActive = (d) => d && d.defaultView !== null && d.defaultView.document === d && (d.defaultView.top === d.defaultView || isDocumentFullyActive(d.defaultView.parent.document));\n\n// check if we run in a browser\nconst isBrowserContext = () => !!Window && globalThis instanceof Window;\n\nconst unset = Symbol(\"unset\");\n\nconst [Observable, Subscriber] = (() => {\n function enumerate(obj, key, enumerable = true) {\n Object.defineProperty(obj, key, {\n ...Object.getOwnPropertyDescriptor(obj, key),\n enumerable,\n });\n }\n\n const pTry = \"try\" in Promise ? Promise.try.bind(Promise) : (fn, ...args) => new Promise((r) => r(fn(...args)));\n\n const pWithResolvers = 'withResolvers' in Promise ? Promise.withResolvers.bind(Promise) : () => {\n let resolve, reject;\n const promise = new Promise((res, rej) => ((resolve = res), (reject = rej)));\n return { promise, resolve, reject };\n };\n\n function getIteratorFromMethod(obj, method) {\n // 1. Let iterator be ? Call(method, obj).\n const iterator = method.call(obj);\n // 2. If iterator is not an Object, throw a TypeError exception.\n if (iterator === null || typeof iterator !== \"object\") throw new TypeError(\"Iterator is not an object\");\n // 3. Return ? GetIteratorDirect(iterator)\n return iterator;\n }\n\n const privateState = new WeakMap();\n\n const AsyncFromSyncIteratorPrototype = {\n next(...args) {\n // 1. Let O be the this value.\n const O = this;\n // 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.\n const state = privateState.get(O);\n if (!state?.syncIteratorRecord)\n throw new TypeError(\n \"AsyncFromSyncIteratorPrototype.next called on invalid object\"\n );\n // 4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].\n const { syncIteratorRecord } = state;\n return pTry(() => syncIteratorRecord.next(...args));\n },\n return(...args) {\n // 1. Let O be the this value.\n const O = this;\n // 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.\n const state = privateState.get(O);\n if (!state?.syncIteratorRecord)\n throw new TypeError(\n \"AsyncFromSyncIteratorPrototype.return called on invalid object\"\n );\n // 4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].\n const { syncIteratorRecord } = state;\n return pTry(() => {\n if (!syncIteratorRecord.return) return { value: undefined, done: true };\n return syncIteratorRecord.return(...args);\n });\n },\n throw(...args) {\n // 1. Let O be the this value.\n const O = this;\n // 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.\n const state = privateState.get(O);\n if (!state?.syncIteratorRecord)\n throw new TypeError(\n \"AsyncFromSyncIteratorPrototype.throw called on invalid object\"\n );\n // 4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].\n const { syncIteratorRecord } = state;\n return pTry(() => {\n if (!syncIteratorRecord.throw) {\n // a. NOTE: If syncIterator does not have a throw method, close it to give it a chance to clean up before we reject the capability.\n syncIteratorRecord.return();\n throw new TypeError(\"no throw method\");\n }\n return syncIteratorRecord.throw(...args);\n });\n },\n };\n\n function createAsyncFromSyncIterator(syncIteratorRecord) {\n // 1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).\n const asyncIterator = Object.create(AsyncFromSyncIteratorPrototype);\n // 2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.\n privateState.set(asyncIterator, { syncIteratorRecord });\n return asyncIterator;\n }\n\n function getIterator(obj, isAsync) {\n let method = undefined;\n // 1. if kind is ASYNC, then\n if (isAsync) {\n // 1.a. Let method be ? GetMethod(obj, %Symbol.asyncIterator%).\n method = obj[Symbol.asyncIterator];\n // 1.b. If method is undefined, then\n if (method == undefined) {\n // 1.b.i. Let method be ? GetMethod(obj, %Symbol.iterator%).\n method = obj[Symbol.iterator];\n // 1.b.ii. If method is undefined, throw a TypeError exception.\n if (method == undefined) throw new TypeError(\"Object is not async iterable\");\n // 1.b.iii. Let syncIteratorRecord be ? GetIteratorFromMethod(obj, syncMethod).\n const syncIteratorRecord = getIteratorFromMethod(obj, method);\n // 1.b.iv. Return ! CreateAsyncFromSyncIterator(syncIteratorRecord).\n return createAsyncFromSyncIterator(syncIteratorRecord);\n }\n // 2. Else,\n } else {\n // 2.a. Let method be ? GetMethod(obj, %Symbol.iterator%).\n method = obj[Symbol.iterator];\n }\n // 3. If method is undefined, throw a TypeError exception.\n if (method == undefined) throw new TypeError(\"Object is not iterable\");\n // 4. Return ? GetIteratorFromMethod(obj, method).\n return getIteratorFromMethod(obj, method);\n }\n\n const abortSignalAny = \"any\" in AbortSignal ? AbortSignal.any.bind(AbortSignal) : (signals) => {\n // create a signal that will abort when any of the signals aborts.\n const ac = new AbortController();\n // when any of the signals is already aborted, abort ac immediately and return its signal.\n for (const signal of signals) {\n if (signal.aborted) {\n ac.abort(signal.reason);\n return ac.signal;\n }\n }\n // otherwise, add an abort listener to each signal that will abort ac.\n for (const signal of signals) {\n signal.addEventListener(\"abort\", () => {\n ac.abort(signal.reason);\n }, { signal: ac.signal });\n }\n // return the signal.\n return ac.signal;\n };\n\n // wrapper for AbortSignal.any that removes null and undefined, for convenience.\n const anySignal = (signalArray) => abortSignalAny(signalArray.filter(Boolean));\n\n class InternalObserver {\n constructor({ next, error, complete } = {}) {\n privateState.set(this, { next, error, complete });\n }\n\n next(value) {\n const { next } = privateState.get(this) || {};\n if (next) next(value);\n }\n\n error(value) {\n const { error } = privateState.get(this) || {};\n if (error) error(value);\n else reportError(value);\n }\n\n complete() {\n const { complete } = privateState.get(this) || {};\n if (complete) complete();\n }\n }\n\n // https://wicg.github.io/observable/#close-a-subscription\n function closeASubscription(subscriber, reason) {\n const state = privateState.get(subscriber);\n \n // 1. If subscriber’s active is false, then return.\n if (!state?.active) return;\n\n // 2. Set subscriber’s active boolean to false.\n state.active = false;\n\n // 3. Signal abort subscriber’s subscription controller with reason, if it is given.\n state.subscriptionController.abort(reason);\n\n // 4. For each teardown of subscriber’s teardown callbacks sorted in reverse insertion order:\n for (const teardown of state.teardowns.reverse()) {\n // 4.1. If subscriber’s relevant global object is a Window object, and its associated Document is not fully active, then abort these steps.\n if (isBrowserContext() && !isDocumentFullyActive(document)) return;\n // 4.2. Invoke teardown.\n try {\n teardown();\n } catch (e) {\n reportError(e);\n }\n }\n }\n\n // https://wicg.github.io/observable/#observable-subscribe-to-an-observable\n function subscribeTo(observable, observer, options = {}) {\n // 1. If this’s relevant global object is a Window object, and its associated Document is not fully active, then return.\n if (isBrowserContext() && !isDocumentFullyActive(document)) return;\n\n // 2. Let internal observer be a new internal observer.\n let internalObserver;\n\n // 3. Process observer as follows:\n // 3.1. If observer is an ObservableSubscriptionCallback\n if (typeof observer == \"function\") {\n // 3.2. Set internal observer’s next steps to these steps that take an\n // any value:\n internalObserver = new InternalObserver({ next: observer });\n // 4. If observer is a SubscriptionObserver\n } else if (observer && !(observer instanceof InternalObserver)) {\n // 4.1. If observer’s next exists, then set internal observer’s next\n // steps to these steps that take an any value:\n // 4.2. If observer’s error exists, then set internal observer’s error\n // steps to these steps that take an any error:\n // 4.3. If observer’s complete exists, then set internal observer’s\n // complete steps to these steps:\n internalObserver = new InternalObserver(observer);\n } else {\n internalObserver = observer || new InternalObserver();\n }\n\n const observableState = privateState.get(observable);\n\n // 5. If this’s weak subscriber is not null and this’s weak subscriber’s active is true:\n const existingSubscriber = observableState.weakSubscriber?.deref();\n if (existingSubscriber?.active) {\n // 5.1. Let subscriber be this’s weak subscriber.\n const subscriber = existingSubscriber;\n const subscriberState = privateState.get(subscriber);\n // 5.2. Append internal observer to subscriber’s internal observers.\n subscriberState.observers.add(internalObserver);\n // 5.3. If options’s signal exists, then:\n if (options.signal) {\n // 5.3.1 If options’s signal is aborted, then remove internal observer from subscriber’s internal observers.\n if (options.signal.aborted) subscriberState.observers.delete(internalObserver);\n // 5.3.2 Otherwise, add the following abort algorithm to options’s signal:\n else options.signal.addEventListener(\"abort\", () => {\n const subscriberState = privateState.get(subscriber);\n // 5.3.2.1 If subscriber’s active is false, then abort these steps.\n if (!subscriberState?.active) return;\n // 5.3.2.2 Remove internal observer from subscriber’s internal observers.\n subscriberState.observers.delete(internalObserver);\n // 5.3.2.3 If subscriber’s internal observers is empty, then close subscriber with options’s signal’s abort reason.\n if (subscriberState.observers.size == 0) {\n closeASubscription(subscriber, options.signal.reason);\n }\n });\n }\n // 5.4. return\n return;\n }\n\n // 6. Let subscriber be a new Subscriber.\n // 7. Append internal observer to subscriber’s internal observers.\n const subscriber = new Subscriber(internalObserver);\n\n // 8. Set this’s weak subscriber to subscriber.\n observableState.weakSubscriber = new WeakRef(subscriber);\n\n // 9. If options’s signal exists, then:\n if (\"signal\" in options) {\n // 9.1. If options’s signal is aborted, then close subscriber given options’s signal abort reason.\n if (options.signal.aborted)\n closeASubscription(subscriber, options.signal.reason);\n // 9.2. Otherwise, add the following abort algorithm to options’s signal:\n else\n options.signal.addEventListener(\"abort\", () => {\n const subscriberState = privateState.get(subscriber);\n // 9.2.1. If subscriber’s active is false, then abort these steps.\n if (!subscriberState?.active) return;\n // 9.2.2. Remove internal observer from subscriber’s internal observers.\n subscriberState.observers.delete(internalObserver);\n // 9.2.3. If subscriber’s internal observers is empty, then close subscriber with options’s signal’s abort reason.\n if (subscriberState.observers.size == 0) {\n closeASubscription(subscriber, options.signal.reason);\n }\n });\n }\n\n // 7. If observable's subscribe callback is a SubscribeCallback, invoke it with subscriber.\n if (observableState.subscribeCallback) {\n // If an exception E was thrown, call subscriber’s error() method with E.\n try {\n observableState.subscribeCallback(subscriber);\n } catch (e) {\n subscriber.error(e);\n }\n }\n // 8. Otherwise, run the steps given by observable's subscribe callback, given subscriber.\n // (Not needed because internal subscribers use the same callback function)\n }\n\n // https://wicg.github.io/observable/#subscriber-api\n class Subscriber {\n get [Symbol.toStringTag]() {\n return \"Subscriber\";\n }\n\n constructor(internalObserver = null) {\n if (!(internalObserver instanceof InternalObserver)) {\n throw new TypeError(\"Illegal constructor\");\n }\n privateState.set(this, {\n active: true,\n observers: new Set([internalObserver]),\n teardowns: [],\n subscriptionController: new AbortController(),\n });\n }\n\n // https://wicg.github.io/observable/#dom-subscriber-next\n next(value) {\n if (!(this instanceof Subscriber))\n throw new TypeError(\"illegal invocation\");\n if (!arguments.length) throw new TypeError(\"too few arguments\");\n\n const state = privateState.get(this);\n\n // 1. If this's active is false, then return.\n if (!state?.active) return;\n\n // 2. If this’s relevant global object is a Window object, and its associated Document is not fully active, then return.\n if (isBrowserContext() && !isDocumentFullyActive(document)) return;\n\n // 3. Let internal observers copy be a copy of this’s internal observers.\n const internalObservers = new Set(state.observers);\n\n // 4. For each observer of this’s internal observers copy:\n for (const observer of internalObservers) {\n // 3.1. Run observer’s next steps given value.\n observer.next(value);\n }\n }\n\n // https://wicg.github.io/observable/#dom-subscriber-error\n error(error) {\n if (!(this instanceof Subscriber))\n throw new TypeError(\"illegal invocation\");\n\n if (!arguments.length) throw new TypeError(\"too few arguments\");\n\n const state = privateState.get(this);\n\n // 1. If this’s active is false, report an exception with error and this’s relevant global object, then return.\n if (!state?.active) {\n reportError(error);\n return;\n }\n\n // 2. If this’s relevant global object is a Window object, and its associated Document is not fully active, then return.\n if (isBrowserContext() && !isDocumentFullyActive(document)) return;\n\n // 3. Close this.\n closeASubscription(this, error);\n\n // 4. Let internal observers copy be a copy of this’s internal observers.\n const internalObservers = new Set(state.observers);\n\n // 5. For each observer of this’s internal observers copy:\n for (const observer of internalObservers) {\n // 5.1. Run observer’s error steps given error.\n observer.error(error);\n }\n }\n\n // https://wicg.github.io/observable/#dom-subscriber-complete\n complete() {\n if (!(this instanceof Subscriber))\n throw new TypeError(\"illegal invocation\");\n\n const state = privateState.get(this);\n\n // 1. If this's active is false, then return.\n if (!state?.active) return;\n\n // 2. If this’s relevant global object is a Window object, and its associated Document is not fully active, then return.\n if (isBrowserContext() && !isDocumentFullyActive(document)) return;\n\n // 3. Close this.\n closeASubscription(this);\n\n // 4. Let internal observers copy be a copy of this’s internal observers.\n const internalObservers = new Set(state.observers);\n\n // 5. For each observer of this’s internal observers copy:\n for (const observer of internalObservers) {\n // 5.1. Run observer’s complete steps.\n observer.complete();\n }\n }\n\n // https://wicg.github.io/observable/#dom-subscriber-addteardown\n addTeardown(teardown) {\n if (!(this instanceof Subscriber))\n throw new TypeError(\"illegal invocation\");\n\n if (typeof teardown != \"function\") {\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n }\n\n // 1. If this’s relevant global object is a Window object, and its associated Document is not fully active, then return.\n if (isBrowserContext() && !isDocumentFullyActive(document)) return;\n\n // 2. If this's active is true, then append teardown to this's teardown callbacks list.\n const state = privateState.get(this);\n if (state?.active)\n state.teardowns.push(teardown);\n // 3. Otherwise, invoke teardown.\n else teardown();\n }\n\n get active() {\n if (!(this instanceof Subscriber))\n throw new TypeError(\"illegal invocation\");\n\n return !!privateState.get(this)?.active;\n }\n\n get signal() {\n if (!(this instanceof Subscriber))\n throw new TypeError(\"illegal invocation\");\n\n if (!privateState.has(this)) {\n const controller = new AbortController();\n controller.abort();\n return controller.signal;\n }\n return privateState.get(this).subscriptionController.signal;\n }\n }\n\n enumerate(Subscriber.prototype, \"next\");\n enumerate(Subscriber.prototype, \"error\");\n enumerate(Subscriber.prototype, \"complete\");\n enumerate(Subscriber.prototype, \"addTeardown\");\n enumerate(Subscriber.prototype, \"active\");\n enumerate(Subscriber.prototype, \"signal\");\n\n // https://wicg.github.io/observable/#observable-api\n class Observable {\n get [Symbol.toStringTag]() {\n return \"Observable\";\n }\n\n // https://wicg.github.io/observable/#dom-observable-observable\n constructor(subscribeCallback) {\n if (!subscribeCallback) {\n throw new TypeError(\"1 argument required but 0 present\");\n }\n privateState.set(this, {\n weakSubscriber: null,\n subscribeCallback,\n });\n }\n\n // https://wicg.github.io/observable/#observable-from\n static from(value) {\n // 1. If Type(value) is not Object, throw a TypeError.\n if (value === null || typeof value !== \"object\") throw new TypeError(\"Observable.from only accepts objects\");\n\n // 2. From Observable: If value’s specific type is an Observable, then return value.\n if (value instanceof Observable) return value;\n\n // 3. Let asyncIteratorMethodRecord be GetMethod(value, %Symbol.asyncIterator%).\n const asyncIteratorMethodRecord = Symbol.asyncIterator in value && value[Symbol.asyncIterator];\n // 4. If asyncIteratorMethod’s is undefined or null, then jump to the step labeled From iterable.\n if (typeof asyncIteratorMethodRecord === \"function\") {\n let done = false;\n // 5. Let nextAlgorithm be the following steps, given a Subscriber subscriber and an Iterator Record iteratorRecord:\n function nextAlgorithm(subscriber, iteratorRecord) {\n // 5.1. If subscriber’s subscription controller’s signal is aborted, then return.\n if (subscriber.signal.aborted) return;\n // 5.2. Let nextPromise be a Promise-or-undefined, initially undefined.\n let nextPromise = undefined;\n try {\n // 5.3. Let nextCompletion be IteratorNext(iteratorRecord).\n let nextCompletion = iteratorRecord.next();\n // 5.5. Otherwise, if nextRecord is normal completion, then set nextPromise to a promise resolved with nextRecord’s [[Value]].\n nextPromise = Promise.resolve(nextCompletion);\n } catch (error) {\n // 5.4. If nextCompletion is a throw completion, then:\n // 5.4.1. Assert: iteratorRecord’s [[Done]] is true.\n // 5.4.2. Set nextPromise to a promise rejected with nextRecord’s [[Value]].\n nextPromise = Promise.reject(error);\n }\n // 5.6. React to nextPromise:\n nextPromise.then(\n // If nextPromise was fulfilled with value iteratorResult, then:\n (iteratorResult) => {\n // 5.6.1 If Type(iteratorResult) is not Object, then run subscriber’s error() method with a TypeError and abort these steps.\n if (iteratorResult === null || typeof iteratorResult !== \"object\") {\n subscriber.error(new TypeError(\"Not an IteratorResult.\"));\n return;\n }\n try {\n // 5.6.2 Let done be IteratorComplete(iteratorResult).\n ({ done } = iteratorResult);\n } catch (error) {\n // 5.6.3 If done is a throw completion, then run subscriber’s error() method with done’s [[Value]] and abort these steps.\n subscriber.error(error);\n return;\n }\n // 5.6.4. If done’s [[Value]] is true, then run subscriber’s complete() and abort these steps.\n if (done) {\n subscriber.complete();\n return;\n }\n let value;\n try {\n // 5.6.5. Let value be IteratorValue(iteratorResult).\n value = iteratorResult.value;\n } catch (error) {\n // 5.6.6. If value is a throw completion, then run subscriber’s error() method with value’s [[Value]] and abort these steps.\n subscriber.error(error);\n return;\n }\n // 5.6.7. Run subscriber’s next() given value’s [[Value]].\n subscriber.next(value);\n // 5.6.8. Run nextAlgorithm given subscriber and iteratorRecord.\n nextAlgorithm(subscriber, iteratorRecord);\n },\n // If nextPromise was rejected with reason r, then run subscriber’s error() method given r.\n (r) => {\n subscriber.error(r);\n }\n );\n }\n // 6. Return a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n return new Observable((subscriber) => {\n // 6.1. If subscriber’s subscription controller’s signal is aborted, then return.\n if (subscriber.signal.aborted) return;\n let iteratorRecordCompletion;\n try {\n // 6.2. Let iteratorRecordCompletion be GetIterator(value, async).\n iteratorRecordCompletion = getIterator(value, true);\n } catch (error) {\n // 6.3. If iteratorRecordCompletion is a throw completion, then run subscriber’s error() method with iteratorRecordCompletion’s [[Value]] and abort these steps.\n subscriber.error(error);\n return;\n }\n // 6.4. Let iteratorRecord be ! iteratorRecordCompletion.\n // 6.5. Assert: iteratorRecord is an Iterator Record.\n const iteratorRecord = iteratorRecordCompletion;\n // 6.6. If subscriber’s subscription controller’s signal is aborted, then return.\n if (subscriber.signal.aborted) return;\n // 6.7. Add the following abort algorithm to subscriber’s subscription controller’s signal:\n subscriber.signal.addEventListener(\"abort\", () => {\n // 6.7.1. Run AsyncIteratorClose(iteratorRecord, NormalCompletion(subscriber’s subscription controller’s abort reason)).\n if (typeof iteratorRecord.return !== \"function\" || done) return;\n const returnPromise = pTry(() => iteratorRecord.return(subscriber.signal.reason));\n returnPromise.then((result) => {\n if (result === null || typeof result !== \"object\") {\n throw new TypeError(\"Iterator .return() must return an Object\");\n }\n });\n });\n // 6.8. Run nextAlgorithm given subscriber and iteratorRecord.\n nextAlgorithm(subscriber, iteratorRecord);\n });\n }\n\n // 7. From iterable: Let iteratorMethod be ? GetMethod(value, %Symbol.iterator%).\n let iteratorMethod = Symbol.iterator in value && value[Symbol.iterator];\n // 8. If iteratorMethod is undefined, then jump to the step labeled From Promise.\n if (typeof iteratorMethod === \"function\") {\n // Otherwise, return a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n return new Observable((subscriber) => {\n // 8.1. If subscriber’s subscription controller’s signal is aborted, then return.\n if (subscriber.signal.aborted) return;\n let iteratorRecordCompletion;\n try {\n // 8.2. Let iteratorRecordCompletion be GetIterator(value, sync).\n iteratorRecordCompletion = getIterator(value, false);\n } catch (error) {\n // 8.3. If iteratorRecordCompletion is a throw completion, then run subscriber’s error() method, given iteratorRecordCompletion’s [[Value]], and abort these steps.\n subscriber.error(error);\n return;\n }\n let done = false;\n // 8.4. Let iteratorRecord be ! iteratorRecordCompletion.\n let iteratorRecord = iteratorRecordCompletion;\n // 8.5 If subscriber’s subscription controller’s signal is aborted, then return.\n if (subscriber.signal.aborted) return;\n // 8.6. Add the following abort algorithm to subscriber’s subscription controller’s signal:\n subscriber.signal.addEventListener(\"abort\", () => {\n // 8.6.1. Run IteratorClose(iteratorRecord, NormalCompletion(UNUSED)).\n if (typeof iteratorRecord.return !== \"function\" || done) return;\n const returnResult = iteratorRecord.return();\n if (returnResult === null || typeof returnResult !== \"object\") {\n throw new TypeError(\"Iterator .return() must return an Object\");\n }\n });\n // 8.7. While true:\n while (true) {\n try {\n // 8.7.1. Let next be IteratorStepValue(iteratorRecord).\n let next = iteratorRecord.next();\n ({ done } = next);\n // 8.7.3. Set next to ! to next.\n // 8.7.4. If next is done, then:\n if (done) {\n // 8.7.4.1. Assert: iteratorRecord’s [[Done]] is true.\n // 8.7.4.2. Run subscriber’s complete().\n subscriber.complete();\n // 8.7.4.3. return\n return;\n }\n // 8.7.5 Run subscriber’s next() given next.\n subscriber.next(next.value);\n // 8.7.6. If subscriber’s subscription controller’s signal is aborted, then break.\n if (subscriber.signal.aborted) break;\n } catch (error) {\n // 8.7.2. If next is a throw completion, then run subscriber’s error() method, given next’s [[Value]], and break.\n subscriber.error(error);\n break;\n }\n }\n });\n }\n\n // 9. From Promise: If IsPromise(value) is true, then:\n if (value instanceof Promise || typeof value.then === \"function\") {\n // 9.1. Return a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n return new Observable((subscriber) => {\n // 9.1.1. React to value:\n value.then(\n // 9.1.1.1. If value was fulfilled with value v, then:\n (v) => {\n // 9.1.1.1.1 Run subscriber’s next() method, given v.\n subscriber.next(v);\n // 9.1.1.1.2 Run subscriber’s complete() method.\n subscriber.complete();\n },\n // 9.1.1.2 If value was rejected with reason r, then run subscriber’s error() method, given r.\n (r) => {\n subscriber.error(r);\n }\n );\n });\n }\n\n // 10. Throw a TypeError.\n throw new TypeError(\"Could not convert value to Observable\");\n }\n\n // https://wicg.github.io/observable/#dom-observable-subscribe\n subscribe(observer = null, options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n // 1. Subscribe to this given observer and options.\n subscribeTo(this, observer, options);\n }\n\n // https://wicg.github.io/observable/#dom-observable-takeuntil\n takeUntil(value) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n\n // 2. Let notifier be the result of converting value to an Observable.\n let notifier = Observable.from(value);\n\n // 3. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n return new Observable((subscriber) => {\n // 3.1. Let notifierObserver be a new internal observer, initialized as follows:\n const notifierObserver = new InternalObserver({\n // 3.1.1. For the next callback, run subscriber’s complete() method.\n next() {\n subscriber.complete();\n },\n // 3.1.2. For the error callback, run subscriber’s complete() method.\n error() {\n subscriber.complete();\n },\n });\n\n // 3.2. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller's signal.\n let options = { signal: subscriber.signal };\n\n // 3.3. Subscribe to notifier given notifierObserver and options.\n subscribeTo(notifier, notifierObserver, options);\n\n // 3.4. If subscriber’s active is false, then return.\n if (!subscriber.active) return;\n\n // 3.5. Let sourceObserver be a new internal observer, initialized as follows:\n let sourceObserver = new InternalObserver({\n // 3.5.1. For the next callback, run subscriber’s next() method, given the passed in value.\n next(value) {\n subscriber.next(value);\n },\n // 3.5.2. For the error callback, run subscriber’s error() method, given the passed in error.\n error(value) {\n subscriber.error(value);\n },\n // 3.5.3. For the complete callback, run subscriber’s complete() method.\n complete() {\n subscriber.complete();\n },\n });\n\n // 3.6. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-map\n map(mapper) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof mapper !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n // 3. Return observable.\n return new Observable((subscriber) => {\n // 2.1. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 2.2. Let sourceObserver be a new internal observer, initialized as follows:\n let sourceObserver = new InternalObserver({\n next(value) {\n let mappedValue;\n // 1. Invoke mapper with the passed in value, and idx, and let mappedValue be the returned value.\n try {\n mappedValue = mapper(value, idx);\n } catch (e) {\n // 2. If an exception E was thrown, then run subscriber’s error() method, given E, and abort these steps.\n subscriber.error(e);\n return;\n }\n // 3. Increment idx.\n idx += 1;\n // 4. Run subscriber’s next() method, given mappedValue.\n subscriber.next(mappedValue);\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // Run subscriber’s complete() method.\n subscriber.complete();\n },\n });\n // 3. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller's signal.\n let options = { signal: subscriber.signal };\n // 4. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-inspect\n inspect(inspectorUnion = {}) {\n // 1: Let subscribe callback be a `VoidFunction`-or-null, initially null.\n let subscribeCallback = null;\n // 2: Let next callback be a `ObservableSubscriptionCallback`-or-null, initially null.\n let nextCallback = null;\n // 3: Let error callback be a `ObservableSubscriptionCallback`-or-null, initially null.\n let errorCallback = null;\n // 4: Let complete callback be a `VoidFunction`-or-null, initially null.\n let completeCallback = null;\n // 5: Let abort callback be a `ObservableInspectorAbortHandler`-or-null, initially null.\n let abortCallback = null;\n\n // 6: Process inspectorUnion as follows:\n if (typeof inspectorUnion === \"function\") {\n // If inspectorUnion is an `ObservableSubscriptionCallback`\n // 6.1: Set next callback to inspectorUnion.\n nextCallback = inspectorUnion;\n } else if (inspectorUnion && typeof inspectorUnion === \"object\") {\n // If inspectorUnion is an `ObservableInspector`\n // 6.1: If `subscribe` exists in inspectorUnion, then set subscribe callback to it.\n if (\"subscribe\" in inspectorUnion) subscribeCallback = inspectorUnion.subscribe;\n // 6.2: If `next` exists in inspectorUnion, then set next callback to it.\n if (\"next\" in inspectorUnion) nextCallback = inspectorUnion.next;\n // 6.3: If `error` exists in inspectorUnion, then set error callback to it.\n if (\"error\" in inspectorUnion) errorCallback = inspectorUnion.error;\n // 6.4: If `complete` exists in inspectorUnion, then set complete callback to it.\n if (\"complete\" in inspectorUnion) completeCallback = inspectorUnion.complete;\n // 6.5: If `abort` exists in inspectorUnion, then set abort callback to it.\n if (\"abort\" in inspectorUnion) abortCallback = inspectorUnion.abort;\n }\n\n // 7: Let sourceObservable be this.\n const sourceObservable = this;\n // 8: Let observable be a new `Observable` whose subscribe callback is an algorithm that takes a `Subscriber` subscriber and does the following:\n return new Observable((subscriber) => {\n // 8.1: If subscribe callback is not null, then invoke it.\n if (subscribeCallback !== null) {\n try {\n subscribeCallback();\n } catch (e) {\n // If an exception E was thrown, then run subscriber’s `error()` method, given E, and abort these steps.\n subscriber.error(e);\n return;\n }\n }\n\n // 8.2: If abort callback is not null, then add the following abort algorithm to subscriber’s subscription controller’s signal:\n const abortCallbackWrapped = () => {\n // 8.2.1: Invoke abort callback with subscriber’s subscription controller’s signal’s abort reason.\n try {\n if (abortCallback !== null) {\n abortCallback(subscriber.signal.reason);\n }\n } catch (e) {\n // If an exception E was thrown, then report the exception E.\n reportError(e);\n }\n };\n subscriber.signal.addEventListener(\"abort\", abortCallbackWrapped, { once: true });\n\n // 8.3: Let sourceObserver be a new internal observer, initialized as follows:\n const sourceObserver = new InternalObserver({\n next(value) {\n // next steps\n // 8.3.next.1: If next callback is not null, then invoke next callback with the passed in value.\n if (nextCallback !== null) {\n try {\n nextCallback(value);\n } catch (e) {\n // If an exception E was thrown, then:\n // 8.3.next.1.1: Remove abort callback from subscriber’s subscription controller’s signal.\n subscriber.signal.removeEventListener(\"abort\", abortCallbackWrapped);\n // 8.3.next.1.2: Run subscriber’s `error()` method, given E, and abort these steps.\n subscriber.error(e);\n return;\n }\n }\n // 8.3.next.2: Run subscriber’s `next()` method with the passed in value.\n subscriber.next(value);\n },\n error(error) {\n // error steps\n // 8.3.error.1: Remove abort callback from subscriber’s subscription controller’s signal.\n subscriber.signal.removeEventListener(\"abort\", abortCallbackWrapped);\n // 8.3.error.2: If error callback is not null, then invoke error callback given the passed in error.\n if (errorCallback !== null) {\n try {\n errorCallback(error);\n } catch (e) {\n // If an exception E was thrown, then run subscriber’s `error()` method, given E, and abort these steps.\n subscriber.error(e);\n return;\n }\n }\n // 8.3.error.3: Run subscriber’s `error()` method, given the passed in error.\n subscriber.error(error);\n },\n complete() {\n // complete steps\n // 8.3.complete.1: Remove abort callback from subscriber’s subscription controller’s signal.\n subscriber.signal.removeEventListener(\"abort\", abortCallbackWrapped);\n // 8.3.complete.2: If complete callback is not null, then invoke complete callback.\n if (completeCallback !== null) {\n try {\n completeCallback();\n } catch (e) {\n // If an exception E was thrown, then run subscriber’s `error()` method, given E, and abort these steps.\n subscriber.error(e);\n return;\n }\n }\n // 8.3.complete.3: Run subscriber’s `complete()` method.\n subscriber.complete();\n },\n });\n\n // 8.4: Let options be a new `SubscribeOptions` whose `signal` is subscriber’s subscription controller’s signal.\n const options = { signal: subscriber.signal };\n // 8.5: Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-filter\n filter(predicate) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof predicate !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n // 3. Return observable.\n return new Observable((subscriber) => {\n // 2.1. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 2.2. Let sourceObserver be a new internal observer, initialized as follows:\n let sourceObserver = new InternalObserver({\n next(value) {\n let matches = false;\n // 1. Invoke mapper with the passed in value, and idx, and let mappedValue be the returned value.\n try {\n matches = predicate(value, idx);\n } catch (e) {\n // 2. If an exception E was thrown, then run subscriber’s error() method, given E, and abort these steps.\n subscriber.error(e);\n return;\n }\n // 3. Set idx to idx + 1.\n idx += 1;\n // 4. If matches is true, then run subscriber’s next() method, given value.\n if (matches) {\n subscriber.next(value);\n }\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // Run subscriber’s complete() method.\n subscriber.complete();\n },\n });\n // 3. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller's signal.\n let options = { signal: subscriber.signal };\n // 4. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-take\n take(amount) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n // 3. Return observable.\n return new Observable((subscriber) => {\n // 2.1. Let remaining be amount.\n let remaining = amount;\n // 2.2. If remaining is 0, then run subscriber’s complete() method and abort these steps.\n if (remaining == 0) return subscriber.complete();\n // 2.3. Let sourceObserver be a new internal observer, initialized as follows:\n let sourceObserver = new InternalObserver({\n next(value) {\n // 1. Run subscriber’s next() method with the passed in value.\n subscriber.next(value);\n // 2. Decrement remaining.\n remaining -= 1;\n // 3. If remaining is 0, then run subscriber’s complete() method.\n if (remaining == 0) subscriber.complete();\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // Run subscriber’s complete() method.\n subscriber.complete();\n },\n });\n // 3. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller's signal.\n let options = { signal: subscriber.signal };\n // 4. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-drop\n drop(amount) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n // 3. Return observable.\n return new Observable((subscriber) => {\n // 2.1. Let remaining be amount.\n let remaining = amount;\n // 2.3. Let sourceObserver be a new internal observer, initialized as follows:\n let sourceObserver = new InternalObserver({\n next(value) {\n // 1. If remaining is > 0, then decrement remaining and abort these steps.\n if (remaining > 0) return (remaining -= 1);\n // 2. Assert: remaining is 0.\n if (remaining != 0) return;\n // 3. Run subscriber’s next() method with the passed in value.\n subscriber.next(value);\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // Run subscriber’s complete() method.\n subscriber.complete();\n },\n });\n // 3. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller's signal.\n let options = { signal: subscriber.signal };\n // 4. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-flatmap\n flatMap(mapper) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof mapper !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n // 3. Return observable.\n return new Observable((subscriber) => {\n // 2.1. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 2.2. Let outerSubscriptionHasCompleted to a boolean, initially false.\n let outerSubscriptionHasCompleted = false;\n // 2.3. Let queue be a new list of any values, initially empty.\n let queue = [];\n\n // https://wicg.github.io/observable/#flatmap-process-next-value-steps\n // The flatmap process next value steps, given an any value, a\n // Subscriber subscriber, a Mapper mapper, and references to all\n // of the following: a list of any values queue, a boolean\n // activeInnerSubscription, a boolean outerSubscriptionHasCompleted,\n // and an unsigned long long idx:\n function flatmapProcessNextValueSteps(value) {\n // 1. Let mappedResult be the result of invoking mapper with value, idx and \"rethrow\".\n let mappedResult;\n try {\n mappedResult = mapper(value, idx);\n } catch (e) {\n return subscriber.error(e);\n }\n // 2. Set idx to idx + 1.\n idx += 1;\n // 3. Let innerObservable be the result of calling from() with mappedResult.\n let innerObservable;\n try {\n innerObservable = Observable.from(mappedResult);\n } catch (e) {\n return subscriber.error(e);\n }\n // 4. Let innerObserver be a new internal observer, initialized as follows:\n let innerObserver = new InternalObserver({\n next(value) {\n // Run subscriber’s next() method, given the passed in value.\n subscriber.next(value);\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // 1. If queue is not empty, then:\n if (queue.length) {\n // 1.1. Let nextValue be the first item in queue; remove remove this item from queue.\n let nextValue = queue.shift();\n // 1.2. Run flatmap process next value steps given nextValue, subscriber, mapper, and references to queue and activeInnerSubscription.\n flatmapProcessNextValueSteps(nextValue);\n // 2. Otherwise:\n } else {\n // 2.1. Set activeInnerSubscription to false.\n activeInnerSubscription = false;\n // 2.2. If outerSubscriptionHasCompleted is true, run subscriber’s complete() method.\n if (outerSubscriptionHasCompleted) subscriber.complete();\n }\n },\n });\n // 5. Let innerOptions be a new SubscribeOptions whose signal is subscriber’s subscription controller's signal.\n let innerOptions = { signal: subscriber.signal };\n // 6. Subscribe to innerObservable given innerObserver and innerOptions.\n subscribeTo(innerObservable, innerObserver, innerOptions);\n }\n\n // 2.4. Let activeInnerSubscription be a boolean, initially false.\n let activeInnerSubscription = false;\n // 2.5. Let sourceObserver be a new internal observer, initialized as follows:\n let sourceObserver = new InternalObserver({\n next(value) {\n // 1. If activeInnerSubscription is true, then:\n if (activeInnerSubscription) {\n // 1.1. Append value to queue.\n queue.push(value);\n // 2. Otherwise:\n } else {\n // 2.1. Set activeInnerSubscription to true.\n activeInnerSubscription = true;\n // 2.2. Run the flatmap process next value steps with value,\n // subscriber, mapper, and references to all of the following:\n // queue, activeInnerSubscription, outerSubscriptionHasCompleted,\n // and idx.\n flatmapProcessNextValueSteps(value);\n }\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // 1. Set outerSubscriptionHasCompleted to true.\n outerSubscriptionHasCompleted = true;\n // 2. If activeInnerSubscription is false and queue is empty, run subscriber’s complete() method.\n if (!activeInnerSubscription && !queue.length) {\n subscriber.complete();\n }\n },\n });\n // 2.6. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller’s signal.\n const options = { signal: subscriber.signal };\n // 2.7. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-switchmap\n switchMap(mapper) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof mapper !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n // 3. Return observable.\n return new Observable((subscriber) => {\n // 2.1. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 2.2. Let outerSubscriptionHasCompleted to a boolean, initially false.\n let outerSubscriptionHasCompleted = false;\n // 2.3. Let activeInnerAbortController be an AbortController-or-null, initially null.\n let activeInnerAbortController = null;\n\n function switchmapProcessNextValueSteps(value) {\n // https://wicg.github.io/observable/#flatmap-process-next-value-steps\n // The flatmap process next value steps, given an any value, a\n // Subscriber subscriber, a Mapper mapper, and references to all\n // of the following: a list of any values queue, a boolean\n // activeInnerSubscription, a boolean outerSubscriptionHasCompleted,\n // and an unsigned long long idx:\n //\n // 1. Let mappedResult be the result of invoking mapper with value\n // and idx.\n let mappedResult;\n try {\n mappedResult = mapper(value, idx);\n } catch (e) {\n return subscriber.error(e);\n }\n // 2. Set idx to idx + 1.\n idx += 1;\n // 3. Let innerObservable be the result of calling from() with mappedResult.\n let innerObservable;\n try {\n innerObservable = Observable.from(mappedResult);\n } catch (e) {\n return subscriber.error(e);\n }\n // 4. Let innerObserver be a new internal observer, initialized as follows:\n let innerObserver = new InternalObserver({\n next(value) {\n // Run subscriber’s next() method, given the passed in value.\n subscriber.next(value);\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete(value) {\n // 1. If outerSubscriptionHasCompleted is true, run subscriber’s complete() method.\n if (outerSubscriptionHasCompleted) subscriber.complete();\n // 2. Otherwise, set activeInnerAbortController to null.\n else activeInnerAbortController = null;\n },\n });\n // 5. Let innerOptions be a new SubscribeOptions whose signal is the\n // result of creating a dependent abort signal from the list\n // «activeInnerAbortController’s signal, subscriber’s subscription\n // controller's signal», using AbortSignal, and the current realm.\n const innerOptions = { signal: anySignal([activeInnerAbortController.signal, subscriber.signal]) };\n // 6. Subscribe to innerObservable given innerObserver and innerOptions.\n subscribeTo(innerObservable, innerObserver, innerOptions);\n }\n\n // 2.4. Let activeInnerSubscription be a boolean, initially false.\n // 2.5. Let sourceObserver be a new internal observer, initialized as follows:\n let sourceObserver = new InternalObserver({\n next(value) {\n // 1. If activeInnerAbortController is not null, then signal abort activeInnerAbortController.\n if (activeInnerAbortController) {\n activeInnerAbortController.abort();\n }\n // 2. Set activeInnerAbortController to a new AbortController.\n activeInnerAbortController = new AbortController();\n // 3. Run the switchmap process next value steps with value,\n // subscriber, mapper, and references to all of the\n // following: activeInnerAbortController,\n // outerSubscriptionHasCompleted, and idx.\n switchmapProcessNextValueSteps(value);\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // 1. Set outerSubscriptionHasCompleted to true.\n outerSubscriptionHasCompleted = true;\n // 2. If activeInnerAbortController is null, run subscriber’s complete() method.\n if (!activeInnerAbortController) subscriber.complete();\n },\n });\n // 3. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller's signal.\n let options = { signal: subscriber.signal };\n // 4. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-catch\n catch(callback) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof callback !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let sourceObservable be this.\n const sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n const observable = new Observable((subscriber) => {\n // 2.1 Let sourceObserver be a new internal observer, initialized as follows:\n const sourceObserver = new InternalObserver({\n next(value) {\n // 2.1.next Run subscriber’s next() method, given the passed in value.\n subscriber.next(value);\n },\n error(value) {\n // 2.1.error.1 Invoke callback with «the passed in error» and \"rethrow\". Let result be the returned value.\n // If an exception E was thrown, then run subscriber’s error() with E, and abort these steps.\n let result;\n try {\n result = callback(value);\n } catch (error) {\n subscriber.error(error);\n return;\n }\n // 2.1.error.2 Let innerObservable be the result of calling from() with result.\n // If an exception E was thrown, then run subscriber’s error() method, given E, and abort these steps.\n let innerObservable;\n try {\n innerObservable = Observable.from(result);\n } catch (error) {\n subscriber.error(error);\n return;\n }\n // 2.1.error.3 Let innerObserver be a new internal observer, initialized as follows:\n const innerObserver = new InternalObserver({\n next(value) {\n // Run subscriber’s next() method, given the passed in value.\n subscriber.next(value);\n },\n error(error) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(error);\n },\n complete() {\n // Run subscriber’s complete() method.\n subscriber.complete();\n },\n });\n // 2.1.error.4 Let innerOptions be a new SubscribeOptions whose signal is subscriber’s subscription controller’s signal.\n const innerOptions = { signal: subscriber.signal };\n // 2.1.error.5 Subscribe to innerObservable given innerObserver and innerOptions.\n subscribeTo(innerObservable, innerObserver, innerOptions);\n },\n complete() {\n // 2.1.complete Run subscriber’s complete() method.\n subscriber.complete();\n },\n });\n // 2.2. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller’s signal.\n const options = { signal: subscriber.signal };\n // 2.3. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n // 3. Return observable.\n return observable;\n }\n\n // https://wicg.github.io/observable/#dom-observable-finally\n finally(callback) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof callback !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let sourceObservable be this.\n let sourceObservable = this;\n // 2. Let observable be a new Observable whose subscribe callback is an algorithm that takes a Subscriber subscriber and does the following:\n // 3. Return observable.\n return new Observable((subscriber) => {\n // 2.1. Run subscriber’s addTeardown() method with callback.\n subscriber.addTeardown(callback);\n // 2.2. Let sourceObserver be a new internal observer, initialized as follows:\n const sourceObserver = new InternalObserver({\n next(value) {\n // Run subscriber’s next() method, given the passed in value.\n subscriber.next(value);\n },\n error(value) {\n // Run subscriber’s error() method, given the passed in error.\n subscriber.error(value);\n },\n complete() {\n // Run subscriber’s complete() method.\n subscriber.complete();\n },\n });\n // 3. Let options be a new SubscribeOptions whose signal is subscriber’s subscription controller’s signal.\n let options = { signal: subscriber.signal };\n // 4. Subscribe to sourceObservable given sourceObserver and options.\n subscribeTo(sourceObservable, sourceObserver, options);\n });\n }\n\n // https://wicg.github.io/observable/#dom-observable-toarray\n toArray(options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. If options’s signal is not null:\n if (options.signal) {\n // 2.1. If options’s signal is aborted, then:\n if (options.signal.aborted) {\n // 2.1.1. Reject p with options’s signal's abort reason.\n // 2.1.2. Return p.\n return Promise.reject(options.signal.reason);\n }\n // 2.2. Add the following abort algorithm to options’s signal:\n options.signal.addEventListener(\"abort\", () => {\n // 2.2.1. Reject p with options’s signal's abort reason.\n reject(options.signal.reason);\n });\n }\n // 3. Let values be a new list.\n let values = [];\n // 4. Let observer be a new internal observer, initialized as follows:\n let observer = new InternalObserver({\n next(value) {\n // Append the passed in value to values.\n values.push(value);\n },\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n complete() {\n // Resolve p with values.\n resolve(values);\n },\n });\n // 5. Subscribe to this given observer and options.\n subscribeTo(this, observer, options);\n // 6. Return p.\n return p;\n }\n\n // https://wicg.github.io/observable/#dom-observable-foreach\n forEach(callback, options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof callback !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. Let visitor callback controller be a new AbortController.\n let visitorCallbackController = new AbortController();\n // 3. Let internal options be a new SubscribeOptions whose signal is the\n // result of creating a dependent abort signal from the list «visitor\n // callback controller’s signal, options’s signal if non-null», using\n // AbortSignal, and the current realm.\n const internalOptions = { signal: anySignal([visitorCallbackController.signal, options.signal]) };\n // 4. If internal options’s signal is aborted, then:\n if (internalOptions.signal.aborted) {\n // 4.1. Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n // 4.2. Return p.\n return p;\n }\n // 5. Add the following abort algorithm to internal options’s signal:\n internalOptions.signal.addEventListener(\"abort\", () => {\n // Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n });\n\n // 6. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 7. Let observer be a new internal observer, initialized as follows:\n let observer = new InternalObserver({\n next(value) {\n // 1. Invoke callback with the passed in value, and idx.\n try {\n callback(value, idx);\n } catch (e) {\n // If an exception E was thrown, then reject p with E, and signal abort visitor callback controller with E.\n reject(e);\n visitorCallbackController.abort(e);\n }\n // 2. Increment idx.\n idx += 1;\n },\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n complete() {\n // Resolve p with undefined.\n resolve();\n },\n });\n // 8. Subscribe to this given observer and internal options.\n subscribeTo(this, observer, internalOptions);\n // 9. Return p.\n return p;\n }\n\n // https://wicg.github.io/observable/#dom-observable-every\n every(predicate, options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof predicate !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. Let controller be a new AbortController.\n let controller = new AbortController();\n // 3. Let internal options be a new SubscribeOptions whose signal is the\n // result of creating a dependent abort signal from the list «controller’s\n // signal, options’s signal if non-null», using AbortSignal, and the\n // current realm.\n const internalOptions = { signal: anySignal([controller.signal, options.signal]) };\n // 4. If internal options’s signal is aborted, then:\n if (internalOptions.signal.aborted) {\n // 4.1. Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n // 4.2. Return p.\n return p;\n }\n // 5. Add the following abort algorithm to internal options’s signal:\n internalOptions.signal.addEventListener(\"abort\", () => {\n // Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n });\n\n // 6. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 7. Let observer be a new internal observer, initialized as follows:\n let observer = new InternalObserver({\n next(value) {\n let passed = false;\n // 1. Invoke predicate with the passed in value, and idx.\n try {\n passed = predicate(value, idx);\n } catch (e) {\n // If an exception E was thrown, then reject p with E, and signal abort visitor callback controller with E.\n reject(e);\n controller.abort(e);\n }\n // 2. Set idx to idx + 1.\n idx += 1;\n // 3. If passed is false, then resolve p with false, and signal abort controller.\n if (!passed) {\n resolve(false);\n controller.abort();\n }\n },\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n complete() {\n // Resolve p with true.\n resolve(true);\n },\n });\n // 8. Subscribe to this given observer and internal options.\n subscribeTo(this, observer, internalOptions);\n // 9. Return p.\n return p;\n }\n\n // https://wicg.github.io/observable/#dom-observable-first\n first(options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. Let controller be a new AbortController.\n let controller = new AbortController();\n // 3. Let internal options be a new SubscribeOptions whose signal is the\n // result of creating a dependent abort signal from the list «controller’s\n // signal, options’s signal if non-null», using AbortSignal, and the\n // current realm.\n const internalOptions = { signal: anySignal([controller.signal, options.signal]) };\n // 4. If internal options’s signal is aborted, then:\n if (internalOptions.signal.aborted) {\n // 4.1. Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n // 4.2. Return p.\n return p;\n }\n // 5. Add the following abort algorithm to internal options’s signal:\n internalOptions.signal.addEventListener(\"abort\", () => {\n // Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n });\n // 6. Let observer be a new internal observer, initialized as follows:\n let observer = new InternalObserver({\n next(value) {\n // 1. Resolve p with the passed in value.\n resolve(value);\n // 2. Signal abort controller.\n controller.abort();\n },\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n complete() {\n // Reject p with a new RangeError.\n // Note: This is only reached when the source Observable completes before it emits a single value.\n reject(new RangeError('No values in Observable'));\n },\n });\n // 7. Subscribe to this given internal observer and internal options.\n subscribeTo(this, observer, internalOptions);\n // 8. Return p.\n return p;\n }\n\n // https://wicg.github.io/observable/#dom-observable-last\n last(options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. If options’s signal is not null:\n if (options.signal) {\n // 2.1. If options’s signal is aborted, then:\n if (options.signal.aborted) {\n // 2.1.1 Reject p with options’s signal's abort reason.\n reject(options.signal.reason);\n // 2.1.2 Return p.\n return p;\n }\n // 2.2. Add the following abort algorithm to options’s signal:\n options.signal.addEventListener(\"abort\", () => {\n // Reject p with internal options’s signal's abort reason.\n reject(options.signal.reason);\n });\n }\n // 3. Let lastValue be an any-or-null, initially null.\n let lastValue = null;\n // 4. Let hasLastValue be a boolean, initially false.\n let hasLastValue = false;\n // 5. Let observer be a new internal observer, initialized as follows:\n let observer = new InternalObserver({\n next(value) {\n // 1. Set hasLastValue to true.\n hasLastValue = true;\n // 2. Set lastValue to the passed in value.\n lastValue = value;\n },\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n complete() {\n // 1. If hasLastValue is true, resolve p with lastValue.\n if (hasLastValue) resolve(lastValue);\n // 2. Otherwise, reject p with a new RangeError.\n else reject(new RangeError('No values in Observable'));\n },\n });\n // 5. Subscribe to this given observer and options.\n subscribeTo(this, observer, options);\n // 6. Return p.\n return p;\n }\n\n // https://wicg.github.io/observable/#dom-observable-find\n find(predicate, options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof predicate !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. Let controller be a new AbortController.\n let controller = new AbortController();\n // 3. Let internal options be a new SubscribeOptions whose signal is the\n // result of creating a dependent abort signal from the list «controller’s\n // signal, options’s signal if non-null», using AbortSignal, and the\n // current realm.\n const internalOptions = { signal: anySignal([controller.signal, options.signal]) };\n // 4. If internal options’s signal is aborted, then:\n if (internalOptions.signal.aborted) {\n // 4.1. Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n // 4.2. Return p.\n return p;\n }\n // 5. Add the following abort algorithm to internal options’s signal:\n internalOptions.signal.addEventListener(\"abort\", () => {\n // Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n });\n\n // 6. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 7. Let observer be a new internal observer, initialized as follows:\n let observer = new InternalObserver({\n next(value) {\n let passed = false;\n // 1. Invoke predicate with the passed in value, and idx.\n try {\n passed = predicate(value, idx);\n } catch (e) {\n // If an exception E was thrown, then reject p with E, and signal abort visitor callback controller with E.\n reject(e);\n controller.abort(e);\n }\n // 2. Set idx to idx + 1.\n idx += 1;\n // 3. If passed is true, then resolve p with value, and signal abort controller.\n if (passed) {\n resolve(value);\n controller.abort();\n }\n },\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n complete() {\n // Resolve p with undefined.\n resolve();\n },\n });\n // 8. Subscribe to this given observer and internal options.\n subscribeTo(this, observer, internalOptions);\n // 9. Return p.\n return p;\n }\n\n // https://wicg.github.io/observable/#dom-observable-some\n some(predicate, options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof predicate !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. Let controller be a new AbortController.\n let controller = new AbortController();\n // 3. Let internal options be a new SubscribeOptions whose signal is the\n // result of creating a dependent abort signal from the list «controller’s\n // signal, options’s signal if non-null», using AbortSignal, and the\n // current realm.\n const internalOptions = { signal: anySignal([controller.signal, options.signal]) };\n // 4. If internal options’s signal is aborted, then:\n if (internalOptions.signal.aborted) {\n // 4.1. Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n // 4.2. Return p.\n return p;\n }\n // 5. Add the following abort algorithm to internal options’s signal:\n internalOptions.signal.addEventListener(\"abort\", () => {\n // Reject p with internal options’s signal's abort reason.\n reject(internalOptions.signal.reason);\n });\n\n // 6. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 7. Let observer be a new internal observer, initialized as follows:\n let observer = new InternalObserver({\n next(value) {\n let passed = false;\n // 1. Invoke predicate with the passed in value, and idx.\n try {\n passed = predicate(value, idx);\n } catch (e) {\n // If an exception E was thrown, then reject p with E, and signal abort controller with E.\n reject(e);\n controller.abort(e);\n }\n // 2. Set idx to idx + 1.\n idx += 1;\n // 3. If passed is true, then resolve p with true, and signal abort controller.\n if (passed) {\n resolve(true);\n controller.abort();\n }\n },\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n complete() {\n // Resolve p with false.\n resolve(false);\n },\n });\n // 8. Subscribe to this given observer and internal options.\n subscribeTo(this, observer, internalOptions);\n // 9. Return p.\n return p;\n }\n\n // https://wicg.github.io/observable/#dom-observable-reduce\n reduce(reducer, initialValue, options = {}) {\n if (!(this instanceof Observable))\n throw new TypeError(\"illegal invocation\");\n if (typeof reducer !== \"function\")\n throw new TypeError(`Parameter 1 is not of type 'Function'`);\n // 1. Let p a new promise.\n let { promise: p, resolve, reject } = pWithResolvers();\n // 2. Let controller be a new AbortController.\n const controller = new AbortController();\n // 3. Let internal options be a new SubscribeOptions whose signal is the\n // result of creating a dependent abort signal from the list «controller’s\n // signal, options’s signal if non-null», using AbortSignal, and the\n // current realm.\n const internalOptions = { signal: anySignal([controller.signal, options.signal]) };\n // 4. If internal options’s signal is aborted, then:\n if (internalOptions.signal.aborted) {\n // 4.1 Reject p with internal options’s signal’s abort reason.\n reject(internalOptions.signal.reason);\n // 4.2 Return p.\n return p;\n }\n // 5. Add the following abort algorithm to internal options’s signal:\n internalOptions.signal.addEventListener(\"abort\", () => {\n // 5.1 Reject p with internal options’s signal’s abort reason.\n reject(internalOptions.signal.reason);\n }, { once: true });\n // 6. Let idx be an unsigned long long, initially 0.\n let idx = 0;\n // 7. Let accumulator be initialValue if it is given, and uninitialized otherwise.\n let accumulator = arguments.length > 1 ? initialValue : unset;\n // 8. Let observer be a new internal observer, initialized as follows:\n const observer = new InternalObserver({\n // next steps\n next(value) {\n // 8.1 If accumulator is uninitialized (meaning no initialValue was passed in), then set accumulator to the passed in value, set idx to idx + 1, and abort these steps.\n if (accumulator === unset) {\n accumulator = value;\n idx++;\n return;\n }\n try {\n // 8.2 Invoke reducer with «accumulator as accumulator, the passed in value as currentValue, idx as index» and \"rethrow\". Let result be the returned value.\n const result = reducer(accumulator, value, idx);\n // 8.3 Set idx to idx + 1.\n idx++;\n // 8.4 Set accumulator to result.\n accumulator = result;\n } catch (e) {\n // 8.2-error If an exception E was thrown, then reject p with E, and signal abort controller with E.\n reject(e);\n controller.abort(e);\n return;\n }\n },\n // error steps\n error(error) {\n // Reject p with the passed in error.\n reject(error);\n },\n // complete steps\n complete() {\n // 1. If accumulator is not \"unset\", then resolve p with accumulator.\n // Otherwise, reject p with a TypeError.\n if (accumulator !== unset) {\n resolve(accumulator);\n } else {\n reject(new TypeError('no initial value provided and no values emitted'));\n }\n },\n });\n // 9. Subscribe to this given observer and internal options.\n subscribeTo(this, observer, internalOptions);\n // 10. Return p.\n return p;\n }\n }\n\n enumerate(Observable.prototype, \"subscribe\");\n\n return [Observable, Subscriber];\n})();\n\nfunction isSupported() {\n return typeof globalThis.Observable === \"function\";\n}\n\nfunction isPolyfilled() {\n return globalThis.Observable === Observable;\n}\n\nfunction apply() {\n Object.defineProperties(globalThis, {\n Observable: {\n value: Observable,\n configurable: true,\n writable: true,\n },\n Subscriber: {\n value: Subscriber,\n configurable: true,\n writable: true,\n },\n });\n\n EventTarget.prototype.when = function (type, options = {}) {\n // Step 1: If this’s relevant global object is a Window object, and its associated Document is not fully active, then return.\n if (isBrowserContext() && !isDocumentFullyActive(document)) return;\n\n // Step 2: Let event target be this.\n const eventTarget = this;\n\n // Step 3: Let observable be a new Observable, initialized with a subscribe callback.\n return new Observable((subscriber) => {\n // Step 3.1: If event target is null, abort these steps.\n if (!eventTarget) return;\n\n // Step 3.2: If subscriber’s subscription controller’s signal is aborted, then return.\n if (subscriber.signal.aborted) return;\n\n // Step 3.3: Add an event listener with the following configuration:\n // - type: type (passed as argument)\n // - callback: A new Web IDL EventListener instance that invokes subscriber.next(event)\n // - capture: options.capture (default false)\n // - passive: options.passive (default undefined)\n // - once: false (explicitly set per spec)\n // - signal: subscriber.signal (for aborting the subscription)\n const listener = (event) => {\n // Observable event listener invoke algorithm: Run subscriber’s next() method with event.\n subscriber.next(event);\n };\n\n eventTarget.addEventListener(type, listener, {\n capture: options.capture || false,\n passive: options.passive,\n once: false, // Explicitly false as required by spec\n signal: subscriber.signal,\n });\n });\n };\n}\n\nexport { Observable, Subscriber, isPolyfilled, isSupported, apply };\n","/**\n * Collision detection algorithms for drag and drop interactions\n * Based on dnd-kit collision detection strategies\n */\n\nexport type CollisionDetectionAlgorithm =\n | 'pointerWithin'\n | 'rectangleIntersection'\n | 'closestCenter'\n | 'closestCorners'\n | 'closestCornersWithInventoryPriority';\n\nexport interface CollisionDetectionOptions {\n algorithm: CollisionDetectionAlgorithm;\n}\n\nexport interface CollisionDetectionStrategy {\n (\n dropzones: HTMLElement[],\n clientX: number,\n clientY: number,\n dragElement?: HTMLElement | null,\n dragContainers?: HTMLElement[]\n ): HTMLElement | null;\n}\n\n/**\n * Pointer Within Algorithm\n * Only registers collision when the pointer is contained within the bounding rectangle\n * of the droppable container. Best for high-precision interfaces.\n */\nexport function pointerWithinCollision(dropzones: HTMLElement[], clientX: number, clientY: number): HTMLElement | null {\n const activeZones = dropzones.filter(zone => !zone.hasAttribute('disabled'));\n\n for (const zone of activeZones) {\n const rect = zone.getBoundingClientRect();\n if (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) {\n return zone;\n }\n }\n\n return null;\n}\n\n/**\n * Rectangle Intersection Algorithm\n * Ensures there is no gap between any of the 4 sides of the rectangles.\n * A draggable is considered over a droppable only when their bounding boxes physically intersect.\n */\nexport function rectangleIntersectionCollision(\n dropzones: HTMLElement[],\n _clientX: number,\n _clientY: number,\n dragElement?: HTMLElement | null\n): HTMLElement | null {\n if (!dragElement) return null;\n\n const activeZones = dropzones.filter(zone => !zone.hasAttribute('disabled'));\n const dragRect = dragElement.getBoundingClientRect();\n\n for (const zone of activeZones) {\n const dropRect = zone.getBoundingClientRect();\n\n // Check if rectangles intersect\n const intersects = !(\n dragRect.right < dropRect.left ||\n dragRect.left > dropRect.right ||\n dragRect.bottom < dropRect.top ||\n dragRect.top > dropRect.bottom\n );\n\n if (intersects) {\n return zone;\n }\n }\n\n return null;\n}\n\n/**\n * Closest Center Algorithm\n * Identifies the droppable container whose center is closest to the center\n * of the bounding rectangle of the active draggable item.\n * Recommended for sortable lists.\n */\nexport function closestCenterCollision(\n dropzones: HTMLElement[],\n clientX: number,\n clientY: number,\n dragElement?: HTMLElement | null\n): HTMLElement | null {\n const activeZones = dropzones.filter(zone => !zone.hasAttribute('disabled'));\n if (activeZones.length === 0) return null;\n\n // Calculate drag center (use pointer or element center)\n let dragCenterX: number;\n let dragCenterY: number;\n\n if (dragElement) {\n const dragRect = dragElement.getBoundingClientRect();\n dragCenterX = dragRect.left + dragRect.width / 2;\n dragCenterY = dragRect.top + dragRect.height / 2;\n } else {\n dragCenterX = clientX;\n dragCenterY = clientY;\n }\n\n let closestZone: HTMLElement | null = null;\n let minDistance = Infinity;\n\n for (const zone of activeZones) {\n const rect = zone.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n const distance = Math.sqrt(Math.pow(dragCenterX - centerX, 2) + Math.pow(dragCenterY - centerY, 2));\n\n if (distance < minDistance) {\n minDistance = distance;\n closestZone = zone;\n }\n }\n\n return closestZone;\n}\n\n/**\n * Closest Corners Algorithm\n * Measures the distance between all four corners of the active draggable item\n * and the four corners of each droppable container.\n * Preferred for Kanban boards and interfaces with stacked droppable containers.\n *\n * Uses average corner distance rather than minimum to reduce flickering.\n */\nexport function closestCornersCollision(\n dropzones: HTMLElement[],\n clientX: number,\n clientY: number,\n dragElement?: HTMLElement | null\n): HTMLElement | null {\n const activeZones = dropzones.filter(zone => !zone.hasAttribute('disabled'));\n if (activeZones.length === 0) return null;\n\n // Get drag corners (use pointer or element corners)\n let dragCorners: { x: number; y: number }[];\n\n if (dragElement) {\n const dragRect = dragElement.getBoundingClientRect();\n dragCorners = [\n { x: dragRect.left, y: dragRect.top },\n { x: dragRect.right, y: dragRect.top },\n { x: dragRect.left, y: dragRect.bottom },\n { x: dragRect.right, y: dragRect.bottom }\n ];\n } else {\n // If no drag element, use pointer as all corners\n dragCorners = [\n { x: clientX, y: clientY },\n { x: clientX, y: clientY },\n { x: clientX, y: clientY },\n { x: clientX, y: clientY }\n ];\n }\n\n let closestZone: HTMLElement | null = null;\n let minAverageDistance = Infinity;\n\n for (const zone of activeZones) {\n const rect = zone.getBoundingClientRect();\n const dropCorners = [\n { x: rect.left, y: rect.top },\n { x: rect.right, y: rect.top },\n { x: rect.left, y: rect.bottom },\n { x: rect.right, y: rect.bottom }\n ];\n\n // Calculate average distance between all corner pairs\n let totalDistance = 0;\n let pairCount = 0;\n\n for (const dragCorner of dragCorners) {\n for (const dropCorner of dropCorners) {\n const distance = Math.sqrt(Math.pow(dragCorner.x - dropCorner.x, 2) + Math.pow(dragCorner.y - dropCorner.y, 2));\n totalDistance += distance;\n pairCount++;\n }\n }\n\n const averageDistance = totalDistance / pairCount;\n\n // Use average distance to reduce sensitivity and flickering\n if (averageDistance < minAverageDistance) {\n minAverageDistance = averageDistance;\n closestZone = zone;\n }\n }\n\n return closestZone;\n}\n\n/**\n * Closest Corners with Inventory Priority Algorithm\n * Similar to closestCorners but gives priority to drag containers (inventory slots).\n * When a draggable is within reasonable range of a drag container, it will prefer\n * the drag container over other dropzones. This makes it easier to return items\n * to the inventory without having to drag them far away from other drop zones.\n *\n * Uses a threshold-based approach:\n * - If drag container distance is within a threshold multiplier, prefer it\n * - Otherwise, use standard closest corners logic\n */\nexport function closestCornersWithInventoryPriorityCollision(\n dropzones: HTMLElement[],\n clientX: number,\n clientY: number,\n dragElement?: HTMLElement | null,\n dragContainers?: HTMLElement[]\n): HTMLElement | null {\n // Separate drag containers from regular droppables BEFORE filtering by disabled\n // Drag containers (inventory) should always be available for dropping\n // Use the provided dragContainers array if available, otherwise fall back to detecting by attributes\n const identifiedDragContainers =\n dragContainers && dragContainers.length > 0\n ? dropzones.filter(zone => dragContainers.includes(zone))\n : dropzones.filter(\n zone => zone.tagName === 'SLOT' && zone.hasAttribute('part') && zone.getAttribute('part')?.includes('drags')\n );\n const allRegularDroppables = dropzones.filter(zone => !identifiedDragContainers.includes(zone));\n\n // Keep disabled droppables in collision resolution.\n // They remain non-droppable via allowDrop(), but this lets drag-end detect\n // \"attempted drop on disabled target\" and trigger proper invalid/max messaging.\n const regularDroppables = allRegularDroppables;\n\n if (identifiedDragContainers.length === 0 && regularDroppables.length === 0) return null;\n\n // Get drag corners (use pointer or element corners)\n let dragCorners: { x: number; y: number }[];\n\n if (dragElement) {\n const dragRect = dragElement.getBoundingClientRect();\n dragCorners = [\n { x: dragRect.left, y: dragRect.top },\n { x: dragRect.right, y: dragRect.top },\n { x: dragRect.left, y: dragRect.bottom },\n { x: dragRect.right, y: dragRect.bottom }\n ];\n } else {\n // If no drag element, use pointer as all corners\n dragCorners = [\n { x: clientX, y: clientY },\n { x: clientX, y: clientY },\n { x: clientX, y: clientY },\n { x: clientX, y: clientY }\n ];\n }\n\n const calculateAverageDistance = (zone: HTMLElement): number => {\n const rect = zone.getBoundingClientRect();\n const dropCorners = [\n { x: rect.left, y: rect.top },\n { x: rect.right, y: rect.top },\n { x: rect.left, y: rect.bottom },\n { x: rect.right, y: rect.bottom }\n ];\n\n let totalDistance = 0;\n let pairCount = 0;\n\n for (const dragCorner of dragCorners) {\n for (const dropCorner of dropCorners) {\n const distance = Math.sqrt(Math.pow(dragCorner.x - dropCorner.x, 2) + Math.pow(dragCorner.y - dropCorner.y, 2));\n totalDistance += distance;\n pairCount++;\n }\n }\n\n return totalDistance / pairCount;\n };\n\n // Find closest drag container\n let closestDragContainer: HTMLElement | null = null;\n let minDragContainerDistance = Infinity;\n\n for (const container of identifiedDragContainers) {\n const distance = calculateAverageDistance(container);\n if (distance < minDragContainerDistance) {\n minDragContainerDistance = distance;\n closestDragContainer = container;\n }\n }\n\n // Find closest regular droppable\n let closestDroppable: HTMLElement | null = null;\n let minDroppableDistance = Infinity;\n\n for (const droppable of regularDroppables) {\n const distance = calculateAverageDistance(droppable);\n if (distance < minDroppableDistance) {\n minDroppableDistance = distance;\n closestDroppable = droppable;\n }\n }\n\n // FIRST: Check if pointer/drag is actually INSIDE any drag container\n // If the user is hovering directly over inventory, give it absolute priority\n if (closestDragContainer && dragElement) {\n const dragRect = dragElement.getBoundingClientRect();\n const containerRect = closestDragContainer.getBoundingClientRect();\n\n // Check if drag element's center is inside the container\n const dragCenterX = dragRect.left + dragRect.width / 2;\n const dragCenterY = dragRect.top + dragRect.height / 2;\n\n const isInsideContainer =\n dragCenterX >= containerRect.left &&\n dragCenterX <= containerRect.right &&\n dragCenterY >= containerRect.top &&\n dragCenterY <= containerRect.bottom;\n\n if (isInsideContainer) {\n return closestDragContainer;\n }\n }\n\n // SECOND: Use distance-based priority with threshold.\n // For drags that originate from a dropzone, avoid over-prioritizing inventory:\n // users typically expect the item to remain in/return to a dropzone unless they\n // explicitly drag into the inventory container.\n const dragOrigin = dragElement?.getAttribute('data-drag-origin');\n const inventoryPriorityThreshold = dragOrigin === 'droppable' ? 0.85 : 1.5;\n\n if (closestDragContainer && closestDroppable) {\n // If drag container is close enough, prefer it\n if (minDragContainerDistance <= minDroppableDistance * inventoryPriorityThreshold) {\n return closestDragContainer;\n }\n return closestDroppable;\n }\n\n // Return whichever is available\n const result = closestDragContainer || closestDroppable;\n return result;\n}\n\n/**\n * Get the collision detection strategy based on the algorithm name\n */\nexport function getCollisionDetectionStrategy(algorithm: CollisionDetectionAlgorithm): CollisionDetectionStrategy {\n switch (algorithm) {\n case 'pointerWithin':\n return pointerWithinCollision;\n case 'rectangleIntersection':\n return rectangleIntersectionCollision;\n case 'closestCenter':\n return closestCenterCollision;\n case 'closestCorners':\n return closestCornersCollision;\n case 'closestCornersWithInventoryPriority':\n return closestCornersWithInventoryPriorityCollision;\n default:\n return pointerWithinCollision;\n }\n}\n\n/**\n * Main collision detection function that delegates to the appropriate strategy\n */\nexport function detectCollision(\n dropzones: HTMLElement[],\n clientX: number,\n clientY: number,\n dragElement?: HTMLElement | null,\n algorithm: CollisionDetectionAlgorithm = 'pointerWithin',\n dragContainers?: HTMLElement[]\n): HTMLElement | null {\n const strategy = getCollisionDetectionStrategy(algorithm);\n return strategy(dropzones, clientX, clientY, dragElement, dragContainers);\n}\n","export function findDraggableTarget(event: Event, draggablesSelector: string): HTMLElement | null {\n const composedPath = event.composedPath ? event.composedPath() : [event.target];\n\n for (const element of composedPath) {\n if (element instanceof HTMLElement && element.tagName !== 'SLOT') {\n if (element.matches(draggablesSelector) || element.hasAttribute('qti-draggable')) {\n return element;\n }\n\n const closest = element.closest(draggablesSelector) || element.closest('[qti-draggable=\"true\"]');\n if (closest) {\n return closest as HTMLElement;\n }\n }\n }\n\n return null;\n}\n\n// Re-export collision detection types and functions for convenience\nexport type { CollisionDetectionAlgorithm } from './collision.utils';\nexport {\n detectCollision,\n getCollisionDetectionStrategy,\n pointerWithinCollision,\n rectangleIntersectionCollision,\n closestCenterCollision,\n closestCornersCollision\n} from './collision.utils';\n\nexport function findInventoryItems(dragContainers: HTMLElement[], identifier: string): HTMLElement[] {\n const items: HTMLElement[] = [];\n\n dragContainers.forEach(container => {\n let matches: Element[] = [];\n\n if (container.tagName.toLowerCase() === 'slot') {\n const slotElement = container as HTMLSlotElement;\n const assignedElements = slotElement.assignedElements({ flatten: true });\n\n matches = assignedElements.filter(el => el.getAttribute('identifier') === identifier);\n } else {\n matches = Array.from(container.querySelectorAll(`[identifier=\"${identifier}\"]`));\n }\n\n items.push(...(matches as HTMLElement[]));\n });\n\n return items;\n}\n\nexport function getMatchMaxValue(draggables: HTMLElement[], identifier: string): number {\n const element = draggables.find(el => el.getAttribute('identifier') === identifier);\n if (!element) return 1;\n\n const matchMax = element.getAttribute('match-max');\n return matchMax ? parseInt(matchMax, 10) || 0 : 1;\n}\n\nexport function isDroppableAtCapacity(droppable: HTMLElement, draggablesSelector: string): boolean {\n const parsedMatchMax = parseInt(droppable.getAttribute('match-max') || '1', 10);\n const matchMax = Number.isNaN(parsedMatchMax) ? 1 : parsedMatchMax;\n if (matchMax === 0) return false;\n\n const selectorMatches = droppable.querySelectorAll(draggablesSelector);\n const attributeMatches = droppable.querySelectorAll('[qti-draggable=\"true\"]');\n const current = Math.max(selectorMatches.length, attributeMatches.length);\n\n return current >= matchMax;\n}\n\nexport function countTotalAssociations(droppables: HTMLElement[], draggablesSelector: string): number {\n return droppables.reduce((total, droppable) => {\n const selectorMatches = droppable.querySelectorAll(draggablesSelector).length;\n const attributeMatches = droppable.querySelectorAll('[qti-draggable=\"true\"]').length;\n return total + Math.max(selectorMatches, attributeMatches);\n }, 0);\n}\n\nexport function collectResponseData(droppables: HTMLElement[], draggablesSelector: string): string[] {\n return droppables\n .map(droppable => {\n const draggablesInDroppable = Array.from(droppable.querySelectorAll<HTMLElement>(draggablesSelector));\n const identifiers = draggablesInDroppable\n .map(element => element.getAttribute('identifier'))\n .filter((identifier): identifier is string => Boolean(identifier));\n const droppableIdentifier = droppable.getAttribute('identifier');\n return identifiers.map(id => `${id} ${droppableIdentifier}`);\n })\n .flat();\n}\n\nexport function applyDropzoneAutoSizing(\n draggables: HTMLElement[],\n droppables: HTMLElement[],\n dragContainers: HTMLElement[],\n hostWindow: Window | null = typeof window !== 'undefined' ? window : null\n): void {\n if (!draggables.length || !droppables.length || !hostWindow) return;\n\n let maxDraggableHeight = 0;\n let maxDraggableWidth = 0;\n\n draggables.forEach(draggable => {\n const rect = draggable.getBoundingClientRect();\n maxDraggableHeight = Math.max(maxDraggableHeight, rect.height);\n maxDraggableWidth = Math.max(maxDraggableWidth, rect.width);\n });\n\n const dropContainer: HTMLElement | null = droppables[0].parentElement;\n\n const isGridLayout = droppables[0].tagName === 'QTI-SIMPLE-ASSOCIABLE-CHOICE';\n const isGapElement = droppables[0].tagName === 'QTI-GAP';\n\n if (isGridLayout && dropContainer) {\n let maxWidth: number;\n\n if (dropContainer.clientWidth > 0) {\n const styles = hostWindow.getComputedStyle(dropContainer);\n const paddingLeft = parseFloat(styles.paddingLeft);\n const paddingRight = parseFloat(styles.paddingRight);\n maxWidth = dropContainer.clientWidth - paddingLeft - paddingRight;\n } else {\n maxWidth = Math.min(hostWindow.innerWidth * 0.8, 600);\n }\n\n dropContainer.style.gridTemplateColumns = `repeat(auto-fit, minmax(calc(min(${maxWidth}px, ${maxDraggableWidth}px + 2 * var(--qti-dropzone-padding, 0.5rem))), 1fr))`;\n }\n\n droppables.forEach(droppable => {\n droppable.style.minHeight = `${maxDraggableHeight}px`;\n\n if (isGridLayout || isGapElement) {\n droppable.style.minWidth = `${maxDraggableWidth}px`;\n }\n\n const dropSlot: HTMLElement | null = droppable.shadowRoot?.querySelector('slot[part=\"dropslot\"]');\n if (dropSlot) {\n dropSlot.style.minHeight = `${maxDraggableHeight}px`;\n }\n });\n\n dragContainers.forEach(dragContainer => {\n dragContainer.style.minHeight = `${maxDraggableHeight}px`;\n });\n}\n","import { isSupported, apply } from 'observable-polyfill/fn';\n\nimport { detectCollision, findDraggableTarget } from './utils/drag-drop.utils';\n\nimport type { Interaction } from '@qti-components/base';\nimport type { CollisionDetectionAlgorithm } from './utils/drag-drop.utils';\n\nif (!isSupported()) apply();\n\n// Global setup for iOS Safari touch events\nconst patchedWindows = new WeakSet<Window>();\n\nfunction patchWindow(window?: Window | null) {\n if (!window || patchedWindows.has(window)) {\n return;\n }\n // This noop touchmove listener with passive: false allows preventDefault() calls\n // to work properly in dynamically added touchmove handlers (iOS Safari fix)\n window.addEventListener('touchmove', () => {}, { capture: false, passive: false });\n patchedWindows.add(window);\n}\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\nexport type DragDropCore = Interaction & {\n trackedDraggables: HTMLElement[];\n trackedDroppables: HTMLElement[];\n trackedDragContainers: HTMLElement[];\n allDropzones: HTMLElement[];\n dragState: DragState;\n collisionDetectionAlgorithm: CollisionDetectionAlgorithm;\n get response(): string | string[] | null;\n set response(value: string | string[] | null);\n saveResponse(value?: string | string[]): void;\n validate(): boolean;\n reportValidity(): boolean;\n cacheInteractiveElements(): void;\n resetDragState(): void;\n afterCache(): void;\n allowDrop(draggable: HTMLElement, droppable: HTMLElement): boolean;\n handleDrop(draggable: HTMLElement, droppable: HTMLElement): void;\n handleInvalidDrop(dragSource: HTMLElement | null): void;\n initiateDrag(\n dragElement: HTMLElement,\n startX: number,\n startY: number,\n inputType: 'mouse' | 'touch',\n eventSource?: 'pointer' | 'mouse' | 'touch',\n pointerId?: number,\n startedFromTrustedEvent?: boolean\n ): void;\n createDragClone(element: HTMLElement, rect: DOMRect): HTMLElement;\n updateClonePosition(clientX: number, clientY: number): void;\n activateAllDroppables(): void;\n setupMoveObservables(inputType: 'mouse' | 'touch', eventSource?: 'pointer' | 'mouse' | 'touch'): void;\n};\n\ninterface DragState {\n dragging: boolean;\n dragSource: HTMLElement | null;\n dragClone: HTMLElement | null;\n startOffset: { x: number; y: number };\n currentTarget: HTMLElement | null;\n sourceDroppable: HTMLElement | null;\n inputType: 'mouse' | 'touch' | null;\n pointerId?: number;\n startedFromTrustedEvent?: boolean;\n initialCoordinates?: { x: number; y: number };\n activationTimeout?: number;\n touchCleanup?: () => void;\n lastTargetChangeTime?: number;\n}\n\ntype DragEventSource = 'pointer' | 'mouse' | 'touch';\n\nexport const DragDropCoreMixin = <T extends Constructor<Interaction>>(\n superClass: T,\n draggablesSelector: string,\n droppablesSelector: string,\n dragContainersSelector = 'slot[part=\"drags\"]',\n defaultCollisionAlgorithm: CollisionDetectionAlgorithm = 'pointerWithin'\n) => {\n abstract class DragDropCoreElement extends superClass {\n protected trackedDraggables: HTMLElement[] = [];\n protected trackedDroppables: HTMLElement[] = [];\n protected trackedDragContainers: HTMLElement[] = [];\n protected allDropzones: HTMLElement[] = [];\n\n /**\n * The collision detection algorithm to use for drag and drop\n * Can be overridden by subclasses or configured per interaction type\n */\n public collisionDetectionAlgorithm: CollisionDetectionAlgorithm = defaultCollisionAlgorithm;\n\n protected dragState: DragState = {\n dragging: false,\n dragSource: null,\n dragClone: null,\n startOffset: { x: 0, y: 0 },\n currentTarget: null,\n sourceDroppable: null,\n inputType: null\n };\n\n private subscriptions: Array<{ unsubscribe: () => void }> = [];\n private dragSubscriptions: Array<{ unsubscribe: () => void }> = [];\n private lastPointerDownAt = 0;\n private lastTouchStartAt = 0;\n\n abstract saveResponse(value?: string | string[]): void;\n\n override connectedCallback(): void {\n super.connectedCallback();\n patchWindow(this.ownerDocument?.defaultView);\n this.setupDragDrop();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.cleanup();\n }\n\n protected async setupDragDrop(): Promise<void> {\n await this.updateComplete;\n\n this.cacheInteractiveElements();\n this.afterCache();\n this.setupDragObservables();\n }\n\n public afterCache(): void {\n // Extension hook\n }\n\n public cacheInteractiveElements(): void {\n const collect = (selector: string, scope: ParentNode | ShadowRoot | null | undefined) =>\n Array.from(scope?.querySelectorAll<HTMLElement>(selector) ?? []);\n\n const lightDraggables = collect(draggablesSelector, this);\n const shadowDraggables = collect(draggablesSelector, this.shadowRoot);\n\n const lightClones = collect('[qti-draggable=\"true\"]:not([data-drag-clone])', this);\n const shadowClones = collect('[qti-draggable=\"true\"]:not([data-drag-clone])', this.shadowRoot);\n\n this.trackedDraggables = Array.from(\n new Set([...lightDraggables, ...shadowDraggables, ...lightClones, ...shadowClones])\n );\n\n const lightDroppables = collect(droppablesSelector, this);\n const shadowDroppables = collect(droppablesSelector, this.shadowRoot);\n this.trackedDroppables = Array.from(new Set([...lightDroppables, ...shadowDroppables]));\n\n const lightDragContainers = collect(dragContainersSelector, this);\n const shadowDragContainers = collect(dragContainersSelector, this.shadowRoot);\n\n this.trackedDragContainers = Array.from(new Set([...lightDragContainers, ...shadowDragContainers]));\n\n this.allDropzones = [...this.trackedDroppables, ...this.trackedDragContainers];\n\n this.trackedDraggables.forEach(draggable => {\n draggable.style.cursor = 'grab';\n draggable.style.userSelect = 'none';\n draggable.style.touchAction = 'none'; // Prevent ALL default touch behaviors\n draggable.style.webkitUserSelect = 'none'; // Safari compatibility\n (draggable.style as any).webkitTouchCallout = 'none'; // Prevent iOS callout\n draggable.setAttribute('qti-draggable', 'true');\n draggable.setAttribute('tabindex', '0');\n });\n }\n\n protected setupDragObservables(): void {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot) {\n console.error('❌ [Observable DnD] No shadow root found!');\n return;\n }\n\n const pointerDragSub = (shadowRoot as any)\n .when('pointerdown')\n .filter((e: PointerEvent) => {\n // Ignore synthetic pointerdown events generated by test helpers.\n // Storybook drag helpers dispatch synthetic mouse events, and browsers may\n // synthesize pointer compatibility events from them. Handling both pointer\n // and mouse streams can create duplicate drag starts and stale ghost clones.\n if (!e.isTrusted) {\n return false;\n }\n const target = findDraggableTarget(e, draggablesSelector);\n const hostDisabled = (this as any).disabled || (this as any).readonly;\n const targetDisabled = target?.hasAttribute('disabled') || target?.getAttribute('aria-disabled') === 'true';\n const touchHandledRecently = Date.now() - this.lastTouchStartAt < 50;\n return target && e.isPrimary !== false && e.button === 0 && !hostDisabled && !targetDisabled && !touchHandledRecently;\n })\n .subscribe((downEvent: PointerEvent) => {\n this.lastPointerDownAt = Date.now();\n const dragTarget = findDraggableTarget(downEvent, draggablesSelector);\n if (!dragTarget) {\n console.warn('⚠️ [Observable DnD] No draggable target found');\n return;\n }\n\n if (downEvent.pointerType === 'touch') {\n downEvent.preventDefault();\n downEvent.stopPropagation();\n }\n\n // Keep a small activation delay for real user input, but avoid delay/cancellation\n // machinery for synthetic events (storybook/play) to reduce flaky cross-input races.\n const delay = downEvent.isTrusted ? (downEvent.pointerType === 'touch' ? 100 : 10) : 0;\n if (this.dragState.activationTimeout) {\n clearTimeout(this.dragState.activationTimeout);\n }\n\n if (delay === 0) {\n if (!this.dragState.dragging) {\n this.initiateDrag(\n dragTarget,\n downEvent.clientX,\n downEvent.clientY,\n downEvent.pointerType as 'mouse' | 'touch',\n 'pointer',\n downEvent.pointerId,\n downEvent.isTrusted\n );\n }\n return;\n }\n\n const cancelPendingActivation = () => {\n if (this.dragState.activationTimeout) {\n clearTimeout(this.dragState.activationTimeout);\n this.dragState.activationTimeout = undefined;\n }\n document.removeEventListener('pointerup', cancelPendingActivation, true);\n document.removeEventListener('pointercancel', cancelPendingActivation, true);\n };\n\n document.addEventListener('pointerup', cancelPendingActivation, { once: true, capture: true });\n document.addEventListener('pointercancel', cancelPendingActivation, { once: true, capture: true });\n\n this.dragState.activationTimeout = window.setTimeout(() => {\n this.dragState.activationTimeout = undefined;\n document.removeEventListener('pointerup', cancelPendingActivation, true);\n document.removeEventListener('pointercancel', cancelPendingActivation, true);\n if (!this.dragState.dragging) {\n this.initiateDrag(\n dragTarget,\n downEvent.clientX,\n downEvent.clientY,\n downEvent.pointerType as 'mouse' | 'touch',\n 'pointer',\n downEvent.pointerId,\n downEvent.isTrusted\n );\n }\n }, delay);\n });\n\n const mouseDragSub = (shadowRoot as any)\n .when('mousedown')\n .filter((e: MouseEvent) => {\n const target = findDraggableTarget(e, draggablesSelector);\n const hostDisabled = (this as any).disabled || (this as any).readonly;\n const targetDisabled = target?.hasAttribute('disabled') || target?.getAttribute('aria-disabled') === 'true';\n const isLeftButton = e.button === 0;\n const pointerHandledRecently = Date.now() - this.lastPointerDownAt < 50;\n return target && isLeftButton && !hostDisabled && !targetDisabled && !pointerHandledRecently;\n })\n .subscribe((downEvent: MouseEvent) => {\n const dragTarget = findDraggableTarget(downEvent, draggablesSelector);\n if (!dragTarget || this.dragState.dragging) {\n return;\n }\n\n downEvent.preventDefault();\n\n this.initiateDrag(dragTarget, downEvent.clientX, downEvent.clientY, 'mouse', 'mouse', undefined, downEvent.isTrusted);\n });\n\n const touchDragSub = (shadowRoot as any)\n .when('touchstart')\n .filter((e: TouchEvent) => {\n const target = findDraggableTarget(e, draggablesSelector);\n const hostDisabled = (this as any).disabled || (this as any).readonly;\n const targetDisabled = target?.hasAttribute('disabled') || target?.getAttribute('aria-disabled') === 'true';\n const hasTouchPoint = Boolean(e.touches?.[0] || e.changedTouches?.[0]);\n const pointerHandledRecently = Date.now() - this.lastPointerDownAt < 50;\n return target && hasTouchPoint && !hostDisabled && !targetDisabled && !pointerHandledRecently;\n })\n .subscribe((startEvent: TouchEvent) => {\n const dragTarget = findDraggableTarget(startEvent, draggablesSelector);\n const touch = startEvent.touches?.[0] || startEvent.changedTouches?.[0];\n if (!dragTarget || !touch || this.dragState.dragging) {\n return;\n }\n\n this.lastTouchStartAt = Date.now();\n startEvent.preventDefault();\n startEvent.stopPropagation();\n this.initiateDrag(dragTarget, touch.clientX, touch.clientY, 'touch', 'touch', undefined, startEvent.isTrusted);\n });\n\n let keyboardState = {\n dragging: false,\n dragElement: null as HTMLElement | null,\n dragIndex: 0,\n dropIndex: 0,\n dropElement: null as HTMLElement | null\n };\n\n const keyboardStream = (shadowRoot as any).when('keydown').subscribe((e: KeyboardEvent) => {\n const draggables = this.trackedDraggables.filter(d => d.style.opacity !== '0');\n const dropTargets = [...this.trackedDroppables, ...this.trackedDragContainers];\n\n // Start drag\n if (!keyboardState.dragging) {\n const target = findDraggableTarget(e, draggablesSelector);\n const hostDisabled = (this as any).disabled || (this as any).readonly;\n const targetDisabled = target?.hasAttribute('disabled') || target?.getAttribute('aria-disabled') === 'true';\n\n if (target && ['Space', 'Enter'].includes(e.code) && !hostDisabled && !targetDisabled) {\n e.preventDefault();\n target.setAttribute('data-keyboard-dragging', 'true');\n keyboardState = {\n dragging: true,\n dragElement: target,\n dragIndex: draggables.indexOf(target),\n dropIndex: 0,\n dropElement: dropTargets[0]\n };\n }\n } else {\n // Navigation and drop/cancel\n switch (e.code) {\n case 'ArrowRight':\n case 'ArrowDown': {\n e.preventDefault();\n const nextDropIndex = (keyboardState.dropIndex + 1) % dropTargets.length;\n keyboardState = { ...keyboardState, dropIndex: nextDropIndex, dropElement: dropTargets[nextDropIndex] };\n break;\n }\n case 'ArrowLeft':\n case 'ArrowUp': {\n e.preventDefault();\n const prevDropIndex = (keyboardState.dropIndex - 1 + dropTargets.length) % dropTargets.length;\n keyboardState = { ...keyboardState, dropIndex: prevDropIndex, dropElement: dropTargets[prevDropIndex] };\n break;\n }\n case 'Space':\n case 'Enter':\n case 'Tab': {\n e.preventDefault();\n if (keyboardState.dragElement && keyboardState.dropElement) {\n const canDrop =\n this.allowDrop(keyboardState.dragElement, keyboardState.dropElement) ||\n this.trackedDragContainers.includes(keyboardState.dropElement);\n\n if (canDrop) {\n this.handleDrop(keyboardState.dragElement, keyboardState.dropElement);\n } else {\n this.handleInvalidDrop(keyboardState.dragElement);\n }\n }\n this.trackedDraggables.forEach(d => d.removeAttribute('data-keyboard-dragging'));\n this.saveResponse();\n keyboardState = {\n dragging: false,\n dragElement: null,\n dragIndex: 0,\n dropIndex: 0,\n dropElement: null\n };\n break;\n }\n case 'Escape': {\n e.preventDefault();\n this.trackedDraggables.forEach(d => d.removeAttribute('data-keyboard-dragging'));\n keyboardState = {\n dragging: false,\n dragElement: null,\n dragIndex: 0,\n dropIndex: 0,\n dropElement: null\n };\n break;\n }\n }\n }\n\n this.allDropzones.forEach(zone => zone.removeAttribute('hover'));\n if (keyboardState.dragging && keyboardState.dropElement) {\n keyboardState.dropElement.setAttribute('hover', '');\n if (\n keyboardState.dropElement.hasAttribute('tabindex') &&\n keyboardState.dropElement.getAttribute('tabindex') !== '-1'\n ) {\n keyboardState.dropElement.focus();\n }\n }\n });\n\n this.subscriptions.push(pointerDragSub, mouseDragSub, touchDragSub, keyboardStream);\n }\n\n protected initiateDrag(\n dragElement: HTMLElement,\n startX: number,\n startY: number,\n inputType: 'mouse' | 'touch',\n eventSource: DragEventSource = 'pointer',\n pointerId?: number,\n startedFromTrustedEvent?: boolean\n ): void {\n if (this.dragState.dragging) {\n console.warn('⚠️ [Observable DnD] Already dragging, ignoring initiateDrag');\n return;\n }\n if (dragElement.hasAttribute('data-drag-clone')) {\n console.warn('⚠️ [Observable DnD] Attempted to drag visual clone, ignoring');\n return;\n }\n\n const isCloneInDroppable = this.trackedDroppables.some(d => d.contains(dragElement));\n const sourceDroppable = this.trackedDroppables.find(d => d.contains(dragElement)) || null;\n const rect = dragElement.getBoundingClientRect();\n\n this.dragState = {\n dragging: true,\n dragSource: dragElement,\n dragClone: this.createDragClone(dragElement, rect),\n startOffset: {\n x: startX - rect.left,\n y: startY - rect.top\n },\n currentTarget: null,\n sourceDroppable: sourceDroppable,\n inputType: inputType,\n pointerId,\n startedFromTrustedEvent,\n initialCoordinates: { x: startX, y: startY }\n };\n\n if (isCloneInDroppable) {\n this.dragState.dragClone?.setAttribute('data-drag-origin', 'droppable');\n dragElement.remove();\n this.cacheInteractiveElements();\n\n // Mark the source droppable so it won't be disabled during drag\n if (sourceDroppable) {\n sourceDroppable.setAttribute('data-drag-source', 'true');\n }\n } else {\n this.dragState.dragClone?.setAttribute('data-drag-origin', 'inventory');\n dragElement.style.opacity = '0';\n dragElement.style.pointerEvents = 'none';\n }\n\n this.updateClonePosition(startX, startY);\n this.activateAllDroppables();\n this.setupMoveObservables(inputType, eventSource);\n }\n\n protected setupMoveObservables(inputType: 'mouse' | 'touch', eventSource: DragEventSource = 'pointer'): void {\n if (inputType === 'touch') {\n if (eventSource === 'pointer') {\n try {\n const captureTarget = this.dragState.dragSource;\n const activePointerId = this.dragState.pointerId;\n if (captureTarget && activePointerId !== undefined && captureTarget.setPointerCapture) {\n captureTarget.setPointerCapture(activePointerId);\n }\n } catch (e) {\n // Ignore if pointer capture is unavailable for this event source.\n }\n }\n\n const preventAllTouch = (e: TouchEvent) => {\n if (e.cancelable) {\n e.preventDefault();\n // Keep propagation for synthetic touch fallback so document-level\n // observable listeners still receive touchmove/touchend.\n if (eventSource === 'pointer') {\n e.stopPropagation();\n }\n }\n };\n\n document.addEventListener('touchmove', preventAllTouch, { passive: false, capture: true });\n document.addEventListener('touchstart', preventAllTouch, { passive: false, capture: true });\n document.addEventListener('touchend', preventAllTouch, { passive: false, capture: true });\n document.addEventListener('gesturestart', preventAllTouch, { passive: false });\n document.addEventListener('gesturechange', preventAllTouch, { passive: false });\n document.addEventListener('gestureend', preventAllTouch, { passive: false });\n\n const cleanup = () => {\n document.removeEventListener('touchmove', preventAllTouch, { capture: true });\n document.removeEventListener('touchstart', preventAllTouch, { capture: true });\n document.removeEventListener('touchend', preventAllTouch, { capture: true });\n document.removeEventListener('gesturestart', preventAllTouch);\n document.removeEventListener('gesturechange', preventAllTouch);\n document.removeEventListener('gestureend', preventAllTouch);\n if (eventSource === 'pointer') {\n try {\n const captureTarget = this.dragState.dragSource;\n const activePointerId = this.dragState.pointerId;\n if (captureTarget && activePointerId !== undefined && captureTarget.releasePointerCapture) {\n captureTarget.releasePointerCapture(activePointerId);\n }\n } catch (e) {\n // Ignore errors if capture was already released\n }\n }\n };\n\n this.dragState.touchCleanup = cleanup;\n }\n\n const moveEventName = eventSource === 'mouse' ? 'mousemove' : eventSource === 'touch' ? 'touchmove' : 'pointermove';\n const upEventName = eventSource === 'mouse' ? 'mouseup' : eventSource === 'touch' ? 'touchend' : 'pointerup';\n const trustMatchesCurrentDrag = (evt: Event) => {\n const expected = this.dragState.startedFromTrustedEvent;\n return expected === undefined || evt.isTrusted === expected;\n };\n\n const moveSub = (document as any)\n .when(moveEventName)\n .takeUntil((document as any).when(upEventName))\n .subscribe({\n next: (e: MouseEvent | PointerEvent | TouchEvent) => {\n if (!trustMatchesCurrentDrag(e)) {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n\n if (eventSource === 'touch') {\n const touch = (e as TouchEvent).touches?.[0] || (e as TouchEvent).changedTouches?.[0];\n if (!touch) return;\n this.handleDragMove(touch.clientX, touch.clientY);\n return;\n }\n\n // For mouse-driven drags, only react while primary button is held.\n // This prevents passive user cursor movement from interfering with\n // an active synthetic/storybook drag sequence.\n if (eventSource === 'mouse') {\n const mouseEvent = e as MouseEvent;\n if (typeof mouseEvent.buttons === 'number' && (mouseEvent.buttons & 1) !== 1) {\n return;\n }\n }\n\n this.handleDragMove((e as MouseEvent | PointerEvent).clientX, (e as MouseEvent | PointerEvent).clientY);\n }\n });\n\n const endSub = (document as any).when(upEventName).subscribe({\n next: (e: MouseEvent | PointerEvent | TouchEvent) => {\n if (!trustMatchesCurrentDrag(e)) {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n\n this.handleDragEnd();\n }\n });\n\n const cancelSub =\n eventSource === 'touch'\n ? (document as any).when('touchcancel').subscribe({\n next: (e: Event) => {\n if (!trustMatchesCurrentDrag(e)) {\n return;\n }\n this.handleDragEnd();\n }\n })\n : eventSource === 'mouse'\n ? null\n : (document as any).when('pointercancel').subscribe({\n next: (e: Event) => {\n if (!trustMatchesCurrentDrag(e)) {\n return;\n }\n this.handleDragEnd();\n }\n });\n\n const escapeSub = (document as any)\n .when('keydown')\n .filter((e: KeyboardEvent) => e.key === 'Escape')\n .subscribe({\n next: (e: KeyboardEvent) => {\n if (!trustMatchesCurrentDrag(e)) {\n return;\n }\n this.handleDragEnd();\n }\n });\n\n const nextSubscriptions = [moveSub, endSub, escapeSub];\n if (cancelSub) {\n nextSubscriptions.push(cancelSub);\n }\n this.dragSubscriptions.push(...nextSubscriptions);\n }\n\n protected handleDragMove(clientX: number, clientY: number): void {\n if (!this.dragState.dragging || !this.dragState.dragClone) return;\n\n this.updateClonePosition(clientX, clientY);\n\n const dropTarget = detectCollision(\n this.allDropzones,\n clientX,\n clientY,\n this.dragState.dragClone,\n this.collisionDetectionAlgorithm,\n this.trackedDragContainers\n );\n\n // Add hysteresis: only switch targets if enough time has passed (reduces flickering)\n const now = Date.now();\n const timeSinceLastChange = now - (this.dragState.lastTargetChangeTime || 0);\n const MIN_TARGET_SWITCH_INTERVAL = 50; // milliseconds\n\n if (dropTarget !== this.dragState.currentTarget) {\n // Allow immediate switch to null (leaving a zone) or if enough time has passed\n if (dropTarget === null || timeSinceLastChange >= MIN_TARGET_SWITCH_INTERVAL) {\n this.allDropzones.forEach(zone => zone.removeAttribute('hover'));\n if (dropTarget) {\n dropTarget.setAttribute('hover', '');\n }\n this.dragState.currentTarget = dropTarget;\n this.dragState.lastTargetChangeTime = now;\n }\n }\n }\n\n protected handleDragEnd(): void {\n if (!this.dragState.dragging) return;\n\n const { dragSource, dragClone, currentTarget, sourceDroppable } = this.dragState;\n let dropTarget = currentTarget;\n if (!dropTarget && dragClone) {\n const rect = dragClone.getBoundingClientRect();\n const probeX = this.dragState.initialCoordinates?.x ?? rect.left + rect.width / 2;\n const probeY = this.dragState.initialCoordinates?.y ?? rect.top + rect.height / 2;\n dropTarget = detectCollision(\n this.allDropzones,\n probeX,\n probeY,\n dragClone,\n this.collisionDetectionAlgorithm,\n this.trackedDragContainers\n );\n }\n\n // Allow dropping into the source droppable even if it's marked as disabled\n // The data-drag-source marker indicates this droppable should accept the item being returned\n const isDisabledButSource =\n dropTarget?.hasAttribute('disabled') && dropTarget.hasAttribute('data-drag-source');\n\n const canDrop =\n !!dragSource &&\n !!dropTarget &&\n this.allowDrop(dragSource, dropTarget) &&\n (!dropTarget.hasAttribute('disabled') || isDisabledButSource);\n\n if (canDrop && dragSource && dropTarget) {\n this.handleDrop(dragSource, dropTarget);\n } else {\n this.handleInvalidDrop(dragSource);\n }\n\n if (dragClone) {\n dragClone.remove();\n }\n\n if (this.dragState.touchCleanup) {\n this.dragState.touchCleanup();\n }\n\n this.resetDragState();\n this.deactivateAllDroppables();\n this.saveResponse();\n\n // Clear the drag-source marker AFTER saveResponse to ensure it's not disabled during drop processing\n if (sourceDroppable) {\n sourceDroppable.removeAttribute('data-drag-source');\n }\n\n // Re-sync dropzone capacity/disabled states after removing the drag-source marker.\n this.cacheInteractiveElements();\n const syncDropzones = (this as unknown as { checkAllMaxAssociations?: () => void }).checkAllMaxAssociations;\n if (typeof syncDropzones === 'function') {\n syncDropzones.call(this);\n }\n }\n\n public allowDrop(_draggable: HTMLElement, droppable: HTMLElement): boolean {\n // Allow drops into both regular droppables and drag containers (inventory)\n return this.trackedDroppables.includes(droppable) || this.trackedDragContainers.includes(droppable);\n }\n\n public abstract handleDrop(draggable: HTMLElement, droppable: HTMLElement): void;\n\n public handleInvalidDrop(dragSource: HTMLElement | null): void {\n if (dragSource) {\n dragSource.style.opacity = '1.0';\n dragSource.style.pointerEvents = 'auto';\n }\n }\n\n protected createDragClone(element: HTMLElement, rect: DOMRect): HTMLElement {\n const clone = element.cloneNode(true) as HTMLElement;\n\n const computedStyles = window.getComputedStyle(element);\n for (let i = 0; i < computedStyles.length; i++) {\n const property = computedStyles[i];\n clone.style.setProperty(property, computedStyles.getPropertyValue(property));\n }\n\n clone.style.position = 'fixed';\n clone.style.width = `${rect.width}px`;\n clone.style.height = `${rect.height}px`;\n clone.style.zIndex = '9999';\n clone.style.pointerEvents = 'none'; // Critical: never capture events\n clone.style.touchAction = 'none'; // Prevent touch interactions\n clone.style.userSelect = 'none'; // Prevent selection\n clone.style.opacity = '0.8';\n\n clone.removeAttribute('qti-draggable');\n clone.removeAttribute('tabindex');\n clone.setAttribute('data-drag-clone', 'true');\n\n document.body.appendChild(clone);\n return clone;\n }\n\n protected updateClonePosition(clientX: number, clientY: number): void {\n if (!this.dragState.dragClone) return;\n\n const { startOffset } = this.dragState;\n const x = clientX - startOffset.x;\n const y = clientY - startOffset.y;\n\n this.dragState.dragClone.style.left = `${x}px`;\n this.dragState.dragClone.style.top = `${y}px`;\n }\n\n protected activateAllDroppables(): void {\n this.setInternalsState('--dragzone-enabled', true);\n this.setInternalsState('--dragzone-active', true);\n\n this.allDropzones.forEach(zone => {\n zone.setAttribute('enabled', '');\n zone.setAttribute('active', '');\n });\n }\n\n protected deactivateAllDroppables(): void {\n this.setInternalsState('--dragzone-enabled', false);\n this.setInternalsState('--dragzone-active', false);\n\n this.allDropzones.forEach(zone => {\n zone.removeAttribute('enabled');\n zone.removeAttribute('active');\n zone.removeAttribute('hover');\n });\n }\n\n public resetDragState(): void {\n if (this.dragState.activationTimeout) {\n clearTimeout(this.dragState.activationTimeout);\n }\n\n if (this.dragState.touchCleanup) {\n try {\n this.dragState.touchCleanup();\n } catch (error) {\n console.warn('⚠️ [Observable DnD] Error during touch cleanup:', error);\n }\n }\n\n this.dragSubscriptions.forEach(sub => {\n try {\n if (sub && typeof sub.unsubscribe === 'function') {\n sub.unsubscribe();\n }\n } catch (error) {\n console.warn('⚠️ [Observable DnD] Error unsubscribing:', error);\n }\n });\n this.dragSubscriptions = [];\n\n this.dragState = {\n dragging: false,\n dragSource: null,\n dragClone: null,\n startOffset: { x: 0, y: 0 },\n currentTarget: null,\n sourceDroppable: null,\n inputType: null,\n pointerId: undefined,\n startedFromTrustedEvent: undefined,\n touchCleanup: undefined\n };\n }\n\n protected setInternalsState(state: string, enabled: boolean): void {\n const internals = (this as any)._internals;\n if (!internals?.states) return;\n\n if (enabled) {\n internals.states.add(state);\n } else {\n internals.states.delete(state);\n }\n }\n\n protected cleanup(): void {\n this.subscriptions.forEach(sub => {\n try {\n sub.unsubscribe();\n } catch (e) {\n // Ignore cleanup errors\n }\n });\n this.subscriptions = [];\n\n if (this.dragState.dragClone) {\n this.dragState.dragClone.remove();\n }\n this.resetDragState();\n }\n }\n\n return DragDropCoreElement as unknown as Constructor<DragDropCore> & T;\n};\n","/**\n * FLIP (First, Last, Invert, Play) animation utilities\n *\n * Based on Paul Lewis's FLIP technique for performant layout animations.\n * @see https://css-tricks.com/animating-layouts-with-the-flip-technique/\n *\n * FLIP enables smooth animations by:\n * 1. First - capturing initial position/size\n * 2. Last - capturing final position/size after DOM changes\n * 3. Invert - applying inverse transform to make element appear at start position\n * 4. Play - animating from inverted state back to final position\n */\n\nexport interface FlipState {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport interface FlipAnimationOptions {\n duration?: number;\n easing?: string;\n fill?: FillMode;\n}\n\nexport const DEFAULT_FLIP_OPTIONS: Required<FlipAnimationOptions> = {\n duration: 250,\n easing: 'ease',\n fill: 'both'\n};\n\n/**\n * Capture the current position and dimensions of an element\n */\nexport function captureFlipState(element: Element): FlipState {\n const rect = element.getBoundingClientRect();\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height\n };\n}\n\n/**\n * Capture FLIP states for multiple elements\n */\nexport function captureMultipleFlipStates(elements: Element[]): Map<Element, FlipState> {\n const states = new Map<Element, FlipState>();\n elements.forEach(element => {\n states.set(element, captureFlipState(element));\n });\n return states;\n}\n\n/**\n * Calculate the transform needed to invert an element back to its first state\n */\nexport function calculateInversion(\n first: FlipState,\n last: FlipState\n): {\n deltaX: number;\n deltaY: number;\n deltaW: number;\n deltaH: number;\n} {\n return {\n deltaX: first.left - last.left,\n deltaY: first.top - last.top,\n deltaW: first.width / last.width,\n deltaH: first.height / last.height\n };\n}\n\n/**\n * Animate a single element using FLIP technique\n */\nexport function animateFlip(\n element: HTMLElement,\n first: FlipState,\n options: FlipAnimationOptions = {}\n): Animation | null {\n const last = captureFlipState(element);\n const { deltaX, deltaY, deltaW, deltaH } = calculateInversion(first, last);\n\n if (deltaX === 0 && deltaY === 0 && deltaW === 1 && deltaH === 1) {\n return null;\n }\n\n const { duration, easing, fill } = { ...DEFAULT_FLIP_OPTIONS, ...options };\n\n const animation = element.animate(\n [\n {\n transformOrigin: 'top left',\n transform: `translate(${deltaX}px, ${deltaY}px) scale(${deltaW}, ${deltaH})`\n },\n {\n transformOrigin: 'top left',\n transform: 'none'\n }\n ],\n {\n duration,\n easing,\n fill\n }\n );\n\n return animation;\n}\n\n/**\n * Animate multiple elements using their captured states\n * Returns a map of elements to their animations\n */\nexport function animateMultipleFlips(\n previousStates: Map<Element, FlipState>,\n options: FlipAnimationOptions = {}\n): Map<Element, Animation> {\n const animations = new Map<Element, Animation>();\n\n previousStates.forEach((firstState, element) => {\n if (!(element instanceof HTMLElement)) return;\n\n const animation = animateFlip(element, firstState, options);\n if (animation) {\n animations.set(element, animation);\n }\n });\n\n return animations;\n}\n\n/**\n * Helper to perform a complete FLIP animation cycle\n *\n * @param elements - Elements to animate\n * @param mutationFn - Function that triggers DOM changes\n * @param options - Animation options\n *\n * @example\n * ```ts\n * performFlip(\n * [...this.children],\n * () => {\n * // Reorder children\n * this.appendChild(firstChild);\n * },\n * { duration: 400 }\n * );\n * ```\n */\nexport async function performFlip(\n elements: Element[],\n mutationFn: () => void | Promise<void>,\n options: FlipAnimationOptions = {}\n): Promise<void> {\n // First - capture initial states\n const firstStates = captureMultipleFlipStates(elements);\n\n // Last - execute the mutation\n await mutationFn();\n\n // Invert & Play - animate elements\n const animations = animateMultipleFlips(firstStates, options);\n\n // Wait for all animations to complete\n await Promise.all(Array.from(animations.values()).map(animation => animation.finished));\n}\n","import { property } from 'lit/decorators.js';\n\nimport {\n collectResponseData,\n countTotalAssociations,\n findInventoryItems,\n getMatchMaxValue,\n isDroppableAtCapacity,\n applyDropzoneAutoSizing\n} from './utils/drag-drop.utils';\nimport { DragDropCoreMixin } from './drag-drop-core.mixin';\nimport { captureMultipleFlipStates, animateMultipleFlips, type FlipAnimationOptions } from './utils/flip.utils';\n\nimport type { CollisionDetectionAlgorithm } from './utils/drag-drop.utils';\nimport type { Interaction, IInteraction } from '@qti-components/base';\nimport type { DragDropCore } from './drag-drop-core.mixin';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\nexport type DragDropSlotted = DragDropCore & {\n minAssociations: number;\n maxAssociations: number;\n disableAnimations: boolean;\n enableFlipAnimations: boolean;\n autoSizeDropzones: boolean;\n validate(): boolean;\n reportValidity(): boolean;\n reset(): void;\n saveResponse(value?: string | string[]): void;\n shouldTreatBlockedMaxAsInvalid(): boolean;\n shouldReturnToInventoryOnInventoryDrop(): boolean;\n};\n\ninterface InteractionConfiguration {\n copyStylesDragClone: boolean;\n dragCanBePlacedBack: boolean;\n dragOnClick: boolean;\n}\n\nexport const DragDropSlottedMixin = <T extends Constructor<Interaction>>(\n superClass: T,\n draggablesSelector: string,\n droppablesSelector: string,\n dragContainersSelector = 'slot[part=\"drags\"]',\n collisionAlgorithm: CollisionDetectionAlgorithm = 'closestCornersWithInventoryPriority'\n) => {\n // Use 'closestCorners' by default for associate interactions (better for multiple drop zones)\n const Core = DragDropCoreMixin(\n superClass,\n draggablesSelector,\n droppablesSelector,\n dragContainersSelector,\n collisionAlgorithm\n );\n\n abstract class DragDropSlottedElement extends Core implements IInteraction {\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\n private _maxAssociations = 0;\n private _maxAssociationsDefaultApplied = false;\n\n @property({ type: Number, reflect: true, attribute: 'max-associations' })\n get maxAssociations(): number {\n // QTI compatibility: gap-match interactions default max-associations to 1\n // when the attribute is omitted.\n if (!this._maxAssociationsDefaultApplied) {\n this._maxAssociationsDefaultApplied = true;\n const tagName = this.tagName?.toLowerCase() || '';\n const isGapMatchInteraction =\n tagName === 'qti-graphic-gap-match-interaction' || tagName === 'qti-gap-match-interaction';\n if (isGapMatchInteraction && !this.hasAttribute('max-associations') && this._maxAssociations === 0) {\n this._maxAssociations = 1;\n }\n }\n return this._maxAssociations;\n }\n\n set maxAssociations(value: number) {\n const oldValue = this._maxAssociations;\n this._maxAssociations = value;\n this.requestUpdate('maxAssociations', oldValue);\n }\n\n protected _response: string[] = [];\n\n // Track when a drop was blocked due to max capacity\n private _dropBlockedDueToMax = false;\n\n // FLIP animation configuration\n public flipAnimationConfig: FlipAnimationOptions = {\n duration: 200, // Slightly faster for slotted interactions\n easing: 'ease' // Simple, browser-optimized easing\n };\n\n private _enableFlipAnimations = true;\n\n @property({ type: Boolean, attribute: 'disable-animations' })\n set disableAnimations(value: boolean) {\n this._enableFlipAnimations = !value;\n }\n get disableAnimations(): boolean {\n return !this._enableFlipAnimations;\n }\n\n get enableFlipAnimations(): boolean {\n return this._enableFlipAnimations;\n }\n\n @property({ type: Boolean, attribute: 'auto-size-dropzones' })\n public autoSizeDropzones = false;\n\n get response(): string {\n const getResponse = (this as unknown as { getResponse?: () => unknown }).getResponse;\n const candidate = typeof getResponse === 'function' ? getResponse.call(this) : undefined;\n const computedResponse = Array.isArray(candidate)\n ? candidate\n : (() => {\n this.cacheInteractiveElements();\n return collectResponseData(this.trackedDroppables, draggablesSelector);\n })();\n return computedResponse.join(',');\n }\n\n set response(value: string | string[]) {\n if (Array.isArray(value)) {\n const getValue = (this as unknown as { getValue?: (v: string[]) => unknown }).getValue;\n const normalized = typeof getValue === 'function' ? getValue.call(this, value) : value;\n const responseEntries = Array.isArray(normalized)\n ? normalized\n : typeof normalized === 'string' && normalized.length > 0\n ? [normalized]\n : [];\n\n this.reset(false);\n responseEntries.forEach(entry => this.placeResponse(entry));\n\n const getResponse = (this as unknown as { getResponse?: () => unknown }).getResponse;\n const candidate = typeof getResponse === 'function' ? getResponse.call(this) : undefined;\n this._response = Array.isArray(candidate)\n ? candidate\n : (() => {\n this.cacheInteractiveElements();\n return collectResponseData(this.trackedDroppables, draggablesSelector);\n })();\n } else {\n // Compatibility note:\n // legacy drag/drop behavior treats string response assignment as form-state only.\n // It does not replay placements into dropzones; only array-based input does.\n this._response = typeof value === 'string' && value.length > 0 ? [value] : [];\n }\n\n this._internals.setFormValue(JSON.stringify(this._response));\n }\n\n public override afterCache(): void {\n this.applyConfiguredChoicesContainerWidth();\n this.updateMinDimensionsForDropZones();\n }\n\n private applyConfiguredChoicesContainerWidth(): void {\n const configuredWidth = this.dataset.choicesContainerWidth;\n if (!configuredWidth) return;\n\n this.trackedDroppables.forEach(droppable => {\n droppable.style.width = `${configuredWidth}px`;\n droppable.style.boxSizing = 'border-box';\n });\n }\n\n public shouldTreatBlockedMaxAsInvalid(): boolean {\n return true;\n }\n\n public shouldReturnToInventoryOnInventoryDrop(): boolean {\n return false;\n }\n\n private getFirstMessageAttribute(attributeNames: string[]): string | null {\n for (const name of attributeNames) {\n const direct = this.getAttribute(name);\n if (direct && direct.trim().length > 0) return direct;\n }\n\n const normalized = attributeNames.map(name => name.toLowerCase());\n for (const attr of Array.from(this.attributes)) {\n if (normalized.includes(attr.name.toLowerCase()) && attr.value.trim().length > 0) {\n return attr.value;\n }\n }\n\n return null;\n }\n\n public override allowDrop(_draggable: HTMLElement, droppable: HTMLElement): boolean {\n // Always allow dropping into drag containers (inventory).\n if (this.trackedDragContainers.includes(droppable)) {\n return true;\n }\n\n // Allow drop if:\n // 1. The droppable is tracked\n // 2. AND either: it's not disabled OR it has the data-drag-source marker (returning to source)\n const isTracked = this.trackedDroppables.includes(droppable);\n const isDisabled = droppable.hasAttribute('disabled');\n const isReturningToSource = droppable.hasAttribute('data-drag-source');\n\n return isTracked && (!isDisabled || isReturningToSource);\n }\n\n public override handleDrop(draggable: HTMLElement, droppable: HTMLElement): void {\n // Capture the drag clone's position before it gets removed\n // The dragClone is the visual element being dragged\n const dragClonePosition = this.dragState.dragClone?.getBoundingClientRect();\n\n this.dropDraggableInDroppable(draggable, droppable, dragClonePosition);\n const identifier = draggable.getAttribute('identifier');\n\n if (identifier) {\n this.updateInventoryBasedOnMatchMax(identifier);\n }\n\n // After drop, check if we've exceeded max and auto-validate if so\n const totalAssociations = countTotalAssociations(this.trackedDroppables, draggablesSelector);\n const exceedsMax = this.maxAssociations > 0 && totalAssociations > this.maxAssociations;\n\n if (exceedsMax) {\n // Automatically show validation message when max is exceeded\n this._dropBlockedDueToMax = true;\n this.validate();\n this.reportValidity();\n }\n }\n\n public override handleInvalidDrop(dragSource: HTMLElement | null): void {\n const sourceDroppable = this.dragState.sourceDroppable;\n const currentTarget = this.dragState.currentTarget;\n const droppedOutsideKnownZones = !currentTarget;\n const inventoryReturnTarget = this.trackedDragContainers[0] || null;\n\n if (!dragSource) {\n return;\n }\n\n // Legacy compatibility:\n // If drag started from a dropzone and ended on host/background (no collision target),\n // interpret this as \"return to inventory\".\n if (\n sourceDroppable &&\n droppedOutsideKnownZones &&\n inventoryReturnTarget &&\n this.configuration.dragCanBePlacedBack !== false\n ) {\n this.dropDraggableInDroppable(dragSource, inventoryReturnTarget);\n }\n // If drag started from a dropzone and the drop is invalid, restore only this\n // dragged instance back to its source droppable.\n else if (sourceDroppable && this.trackedDroppables.includes(sourceDroppable)) {\n this.dropDraggableInDroppable(dragSource, sourceDroppable);\n } else if (dragSource.style.opacity === '0') {\n // Drag started from inventory: simply restore inventory visual state.\n this.restoreInventoryItem(dragSource);\n this.cacheInteractiveElements();\n this.checkAllMaxAssociations();\n }\n\n // Only flag \"blocked due to max\" when the user attempted to drop on\n // a disabled non-source target while global max is reached.\n // This avoids showing max-capacity errors for unrelated invalid drops\n // (e.g. dropping outside any known dropzone).\n const totalAssociations = countTotalAssociations(this.trackedDroppables, draggablesSelector);\n const maxReached = this.maxAssociations > 0 && totalAssociations >= this.maxAssociations;\n const attemptedDisabledTarget =\n !!currentTarget && currentTarget.hasAttribute('disabled') && !currentTarget.hasAttribute('data-drag-source');\n\n this._dropBlockedDueToMax = attemptedDisabledTarget && maxReached;\n this.validate();\n this.reportValidity();\n }\n\n private updateMinDimensionsForDropZones(): void {\n if (this.trackedDraggables.length === 0) return;\n\n applyDropzoneAutoSizing(this.trackedDraggables, this.trackedDroppables, this.trackedDragContainers);\n }\n\n private restoreInventoryItem(dragSource: HTMLElement): void {\n dragSource.style.opacity = '1.0';\n dragSource.style.display = '';\n dragSource.style.position = '';\n dragSource.style.pointerEvents = 'auto';\n }\n\n private placeResponse(response: string): void {\n const [dropIdentifier, ...dragIdentifiers] = response.split(' ').reverse();\n const droppable = this.trackedDroppables.find(d => d.getAttribute('identifier') === dropIdentifier);\n if (!droppable) return;\n\n dragIdentifiers.forEach(dragId => {\n if (!dragId) return;\n\n const fromInventory = findInventoryItems(this.trackedDragContainers, dragId).at(0);\n const draggable = fromInventory || this.trackedDraggables.find(d => d.getAttribute('identifier') === dragId);\n if (!draggable) return;\n\n this.dropDraggableInDroppable(draggable, droppable);\n });\n }\n\n private dropDraggableInDroppable(\n draggable: HTMLElement,\n droppable: HTMLElement,\n dragClonePosition?: DOMRect\n ): void {\n const isDragContainer = this.trackedDragContainers.includes(droppable);\n\n if (isDragContainer) {\n // Optional legacy compatibility:\n // for some interactions, dropping an inventory item back onto inventory\n // clears placed clones for that identifier.\n if (!this.dragState.sourceDroppable) {\n if (this.shouldReturnToInventoryOnInventoryDrop()) {\n this.returnToInventory(draggable);\n this._dropBlockedDueToMax = false;\n this.validate();\n return;\n }\n\n // Keep the inventory source item in place for interactions that don't\n // use \"drop to inventory clears placed clones\" semantics (e.g. gap-match).\n this.restoreInventoryItem(draggable);\n this.cacheInteractiveElements();\n this.checkAllMaxAssociations();\n this._dropBlockedDueToMax = false;\n this.validate();\n return;\n }\n\n const identifier = draggable.getAttribute('identifier');\n draggable.remove();\n\n if (identifier) {\n this.restoreOriginalInInventory(identifier);\n }\n\n this.cacheInteractiveElements();\n this.checkAllMaxAssociations();\n\n // Clear the blocked flag and re-validate since we've removed an association\n this._dropBlockedDueToMax = false;\n this.validate();\n\n return;\n }\n\n const parsedMatchMax = parseInt(droppable.getAttribute('match-max') || '1', 10);\n const matchMax = Number.isNaN(parsedMatchMax) ? 1 : parsedMatchMax;\n const allowsMultiple = matchMax === 0 || matchMax > 1;\n\n // FLIP: First - capture positions of existing children in droppable\n const existingChildren = Array.from(droppable.querySelectorAll<HTMLElement>('[qti-draggable=\"true\"]'));\n const flipStates =\n this.enableFlipAnimations && existingChildren.length > 0 ? captureMultipleFlipStates(existingChildren) : null;\n\n if (!allowsMultiple) {\n const existing =\n droppable.querySelector(draggablesSelector) || droppable.querySelector('[qti-draggable=\"true\"]');\n if (existing) {\n const existingId = existing.getAttribute('identifier');\n existing.remove();\n\n if (existingId) {\n this.restoreOriginalInInventory(existingId);\n }\n }\n }\n\n const cleanClone = draggable.cloneNode(true) as HTMLElement;\n cleanClone.removeAttribute('style'); // Remove inline styles from the clone\n cleanClone.removeAttribute('data-keyboard-dragging'); // Remove keyboard dragging indicator\n cleanClone.setAttribute('qti-draggable', 'true');\n cleanClone.setAttribute('tabindex', '0');\n\n // FLIP: Last - add the new element (this may cause siblings to shift)\n if (droppable.tagName === 'SLOT') {\n cleanClone.setAttribute('slot', droppable.getAttribute('name') || '');\n } else if (droppable.tagName === 'QTI-SIMPLE-ASSOCIABLE-CHOICE') {\n cleanClone.setAttribute('slot', 'qti-simple-associable-choice');\n droppable.appendChild(cleanClone);\n droppable.setAttribute('data-has-drop', 'true');\n } else {\n droppable.appendChild(cleanClone);\n }\n\n if (flipStates && this.enableFlipAnimations) {\n animateMultipleFlips(flipStates, this.flipAnimationConfig);\n }\n\n // FLIP: Animate the newly dropped element from drag position to final position\n if (dragClonePosition && this.enableFlipAnimations) {\n requestAnimationFrame(() => {\n const finalPosition = cleanClone.getBoundingClientRect();\n\n const deltaX = dragClonePosition.left - finalPosition.left;\n const deltaY = dragClonePosition.top - finalPosition.top;\n\n // Only animate if there's actual movement\n if (deltaX !== 0 || deltaY !== 0) {\n cleanClone.animate(\n [\n {\n transform: `translate(${deltaX}px, ${deltaY}px)`,\n opacity: 0.8\n },\n {\n transform: 'translate(0, 0)',\n opacity: 1\n }\n ],\n {\n duration: this.flipAnimationConfig.duration || 200,\n easing: this.flipAnimationConfig.easing || 'ease',\n fill: 'both'\n }\n );\n }\n });\n }\n\n const identifier = draggable.getAttribute('identifier');\n if (identifier) {\n this.updateInventoryBasedOnMatchMax(identifier);\n }\n\n this.cacheInteractiveElements();\n this.checkAllMaxAssociations();\n }\n\n private returnToInventory(element: HTMLElement): void {\n const identifier = element.getAttribute('identifier');\n if (identifier) {\n // Remove all clones of this item from drop zones\n this.trackedDroppables.forEach(droppable => {\n const clones = Array.from(droppable.querySelectorAll(`[identifier=\"${identifier}\"][qti-draggable=\"true\"]`));\n clones.forEach(clone => {\n clone.remove();\n if (droppable.tagName === 'QTI-SIMPLE-ASSOCIABLE-CHOICE') {\n droppable.removeAttribute('data-has-drop');\n }\n });\n });\n\n this.restoreOriginalInInventory(identifier);\n }\n this.cacheInteractiveElements();\n this.checkAllMaxAssociations();\n }\n\n private restoreOriginalInInventory(identifier: string): void {\n const inventoryItems = findInventoryItems(this.trackedDragContainers, identifier);\n\n // FLIP: First - capture positions of all items in inventory containers\n const allInventoryItems: HTMLElement[] = [];\n this.trackedDragContainers.forEach(container => {\n allInventoryItems.push(...Array.from(container.querySelectorAll<HTMLElement>('[qti-draggable=\"true\"]')));\n });\n\n const flipStates =\n this.enableFlipAnimations && allInventoryItems.length > 0 ? captureMultipleFlipStates(allInventoryItems) : null;\n\n // FLIP: Last - restore the inventory items (may cause reflow)\n inventoryItems.forEach(item => {\n item.style.opacity = '1.0';\n item.style.pointerEvents = 'auto';\n item.style.display = '';\n item.style.visibility = 'visible';\n\n item.style.setProperty('opacity', '1.0', 'important');\n item.style.setProperty('pointer-events', 'auto', 'important');\n });\n\n // FLIP: Invert & Play - animate items that may have shifted\n if (flipStates && this.enableFlipAnimations) {\n animateMultipleFlips(flipStates, this.flipAnimationConfig);\n }\n }\n\n private updateInventoryBasedOnMatchMax(identifier: string): void {\n const inventoryItems = findInventoryItems(this.trackedDragContainers, identifier);\n const matchMax = getMatchMaxValue(this.trackedDraggables, identifier);\n \n // Count only items placed in dropzones, not in inventory/drag containers\n const placedInDropzones = this.trackedDroppables.reduce((count, droppable) => {\n const items = droppable.querySelectorAll(`[identifier=\"${identifier}\"]`);\n return count + items.length;\n }, 0);\n\n inventoryItems.forEach(item => {\n if (matchMax !== 0 && placedInDropzones >= matchMax) {\n item.style.opacity = '0.0';\n item.style.pointerEvents = 'none';\n } else {\n item.style.opacity = '1.0';\n item.style.pointerEvents = 'auto';\n }\n });\n }\n\n private checkAllMaxAssociations(): void {\n const totalAssociations = countTotalAssociations(this.trackedDroppables, draggablesSelector);\n\n const maxReached = this.maxAssociations > 0 && totalAssociations >= this.maxAssociations;\n\n this.trackedDroppables.forEach(droppable => {\n // Don't disable the source droppable during an active drag\n const isDragSource = droppable.hasAttribute('data-drag-source');\n const isAtCapacity = isDroppableAtCapacity(droppable, draggablesSelector);\n\n if ((maxReached || isAtCapacity) && !isDragSource) {\n droppable.setAttribute('disabled', '');\n } else {\n droppable.removeAttribute('disabled');\n }\n });\n }\n\n public override saveResponse(): void;\n public override saveResponse(value: string | string[]): void;\n public override saveResponse(value?: string | string[]): void {\n const getResponse = (this as unknown as { getResponse?: () => unknown }).getResponse;\n const candidate = value ?? (typeof getResponse === 'function' ? getResponse.call(this) : undefined);\n const responseData = Array.isArray(candidate)\n ? candidate\n : typeof candidate === 'string'\n ? [candidate]\n : (() => {\n this.cacheInteractiveElements();\n return collectResponseData(this.trackedDroppables, draggablesSelector);\n })();\n\n // Persist response state without mutating the DOM tree.\n // Using the response setter here can trigger reset/replay flows that clear\n // partially completed interactions (e.g. associate left side dropped first).\n this._response = responseData;\n this._internals.setFormValue(JSON.stringify(this._response));\n\n this.dispatchEvent(\n new CustomEvent('qti-interaction-response', {\n bubbles: true,\n composed: true,\n detail: {\n responseIdentifier: (this as unknown as { responseIdentifier?: string }).responseIdentifier,\n response: responseData\n }\n })\n );\n\n this.requestUpdate();\n }\n\n override reset(): void;\n override reset(save: boolean): void;\n override reset(save = true): void {\n this.trackedDroppables.forEach(droppable => {\n const items = Array.from(droppable.querySelectorAll(draggablesSelector));\n items.forEach(item => item.remove());\n if (droppable.tagName === 'QTI-SIMPLE-ASSOCIABLE-CHOICE') {\n droppable.removeAttribute('data-has-drop');\n }\n });\n\n this.trackedDraggables.forEach(draggable => {\n const identifier = draggable.getAttribute('identifier');\n if (identifier) {\n this.restoreOriginalInInventory(identifier);\n }\n });\n\n this.resetDragState();\n this.cacheInteractiveElements();\n\n this._response = [];\n this._internals.setFormValue(JSON.stringify(this._response));\n\n if (save) {\n this.saveResponse();\n }\n }\n\n public override validate(): boolean {\n const totalAssociations = countTotalAssociations(this.trackedDroppables, draggablesSelector);\n\n const atMaxCapacity = this.maxAssociations > 0 && totalAssociations >= this.maxAssociations;\n const exceedsMax = this.maxAssociations > 0 && totalAssociations > this.maxAssociations;\n const belowMin = this.minAssociations > 0 && totalAssociations < this.minAssociations;\n\n let validityMessage = '';\n let isValid = true;\n\n // Priority order: exceedsMax > (atMaxCapacity && blockedDrop) > belowMin\n if (exceedsMax) {\n // QTI conformance: default platform message format\n validityMessage =\n this.getFirstMessageAttribute(['data-max-associations-message', 'data-max-selections-message']) ||\n this.dataset.maxAssociationsMessage ||\n this.dataset.maxSelectionsMessage ||\n `You've selected too many associations. Maximum allowed is ${this.maxAssociations}.`;\n isValid = false;\n } else if (atMaxCapacity && this._dropBlockedDueToMax && this.shouldTreatBlockedMaxAsInvalid()) {\n validityMessage =\n this.getFirstMessageAttribute(['data-max-associations-message', 'data-max-selections-message']) ||\n this.dataset.maxAssociationsMessage ||\n this.dataset.maxSelectionsMessage ||\n `You've selected too many associations. Maximum allowed is ${this.maxAssociations}.`;\n isValid = false;\n } else if (belowMin) {\n validityMessage =\n this.getFirstMessageAttribute(['data-min-associations-message', 'data-min-selections-message']) ||\n this.dataset.minAssociationsMessage ||\n this.dataset.minSelectionsMessage ||\n `Please select at least ${this.minAssociations} ${this.minAssociations === 1 ? 'association' : 'associations'}.`;\n isValid = false;\n // Clear the blocked flag since we're now in a different error state\n this._dropBlockedDueToMax = false;\n } else {\n // Clear the blocked flag when validation passes\n this._dropBlockedDueToMax = false;\n }\n\n const validityAnchor = this.trackedDroppables[0] ?? this.trackedDraggables[0] ?? this;\n this._internals.setValidity(isValid ? {} : { customError: true }, validityMessage, validityAnchor);\n\n return isValid;\n }\n\n public override reportValidity(): boolean {\n const isValid = this._internals.reportValidity();\n\n // Query the validation message element directly in the shadow root\n // to avoid timing issues with @query decorator\n const validationMessageElement = this.shadowRoot?.querySelector('#validation-message') as HTMLElement | null;\n\n if (validationMessageElement) {\n if (!isValid) {\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\n return isValid;\n }\n }\n\n return DragDropSlottedElement as unknown as Constructor<DragDropSlotted> & T;\n};\n","/**\n * Sorting strategies for different layouts.\n */\n\nexport interface InsertPosition {\n index: number;\n placeAfter: boolean;\n}\n\nexport interface SortingStrategy {\n /**\n * Calculate where to insert an item based on pointer position\n * @param elements - Array of sortable elements\n * @param activeElement - The element being dragged\n * @param targetElement - The element being hovered over\n * @param clientX - Pointer X coordinate\n * @param clientY - Pointer Y coordinate\n * @returns Insert position information\n */\n getInsertPosition(\n elements: HTMLElement[],\n activeElement: HTMLElement,\n targetElement: HTMLElement,\n clientX: number,\n clientY: number\n ): InsertPosition | null;\n}\n\nexport class VerticalListSortingStrategy implements SortingStrategy {\n getInsertPosition(\n elements: HTMLElement[],\n _activeElement: HTMLElement,\n targetElement: HTMLElement,\n _clientX: number,\n clientY: number\n ): InsertPosition | null {\n const targetIndex = elements.indexOf(targetElement);\n if (targetIndex === -1) return null;\n\n const rect = targetElement.getBoundingClientRect();\n const relative = (clientY - rect.top) / rect.height;\n const clampedRelative = Math.min(1, Math.max(0, relative));\n\n // Use 50% threshold - simpler and more intuitive\n // If pointer is in top half, place before; if in bottom half, place after\n const placeAfter = clampedRelative > 0.5;\n\n return {\n index: targetIndex,\n placeAfter\n };\n }\n}\n\nexport class HorizontalListSortingStrategy implements SortingStrategy {\n getInsertPosition(\n elements: HTMLElement[],\n _activeElement: HTMLElement,\n targetElement: HTMLElement,\n clientX: number,\n _clientY: number\n ): InsertPosition | null {\n const targetIndex = elements.indexOf(targetElement);\n if (targetIndex === -1) return null;\n\n const rect = targetElement.getBoundingClientRect();\n const relative = (clientX - rect.left) / rect.width;\n const clampedRelative = Math.min(1, Math.max(0, relative));\n\n // Check if this is the last item in the list\n const isLastItem = targetIndex === elements.length - 1;\n\n // For the last item, use a 33% threshold to make it easier to place items after it\n // For other items, use 50% threshold for balanced behavior\n const threshold = isLastItem ? 0.33 : 0.5;\n const placeAfter = clampedRelative > threshold;\n\n return {\n index: targetIndex,\n placeAfter\n };\n }\n}\n\n/**\n * Default sorting strategy (vertical)\n * Use VerticalListSortingStrategy or HorizontalListSortingStrategy explicitly\n * for better control over orientation.\n */\nexport const defaultSortingStrategy = new VerticalListSortingStrategy();\n","/**\n * Shared utilities for sortable drag-and-drop behavior.\n * Used by both DragDropSortableMixin (standalone) and SlotSortableEnhancerMixin (composition).\n */\n\nimport { captureMultipleFlipStates, animateMultipleFlips, type FlipAnimationOptions } from './flip.utils';\n\nimport type { SortingStrategy, InsertPosition } from '../strategies/sorting.strategy';\n\n/**\n * Configuration for drop placeholder styling\n */\nexport interface PlaceholderConfig {\n borderStyle?: string;\n borderColor?: string;\n background?: string;\n transitionDuration?: number;\n}\n\nconst defaultPlaceholderConfig: PlaceholderConfig = {\n borderStyle: '2px dashed',\n borderColor: 'var(--qti-drop-placeholder, #c1c1c1)',\n background: 'transparent',\n transitionDuration: 150\n};\n\n/**\n * State tracking for sortable drag operations\n */\nexport interface SortableDragContext {\n /** The placeholder element shown during drag */\n placeholder: HTMLElement | null;\n /** Last element that was hovered over */\n lastHoverTarget: HTMLElement | null;\n /** Last calculated placement to avoid redundant DOM operations */\n lastPlacement: { target: HTMLElement; after: boolean } | null;\n /** Container where sorting is occurring */\n sortContainer: HTMLElement | null;\n}\n\n/**\n * Creates a new sortable drag context\n */\nexport function createSortableDragContext(): SortableDragContext {\n return {\n placeholder: null,\n lastHoverTarget: null,\n lastPlacement: null,\n sortContainer: null\n };\n}\n\n/**\n * Resets the sortable drag context, cleaning up any DOM elements\n */\nexport function resetSortableDragContext(context: SortableDragContext): void {\n context.placeholder?.remove();\n context.placeholder = null;\n context.lastHoverTarget = null;\n context.lastPlacement = null;\n context.sortContainer = null;\n}\n\n/**\n * Creates a placeholder element that matches the dimensions of the dragged element\n */\nexport function createDropPlaceholder(\n source: HTMLElement,\n rect: DOMRect,\n config: PlaceholderConfig = {}\n): HTMLElement {\n const mergedConfig = { ...defaultPlaceholderConfig, ...config };\n const placeholder = document.createElement('div');\n\n placeholder.setAttribute('data-drop-placeholder', 'true');\n placeholder.style.width = `${rect.width}px`;\n placeholder.style.height = `${rect.height}px`;\n placeholder.style.margin = window.getComputedStyle(source).margin;\n placeholder.style.boxSizing = 'border-box';\n placeholder.style.border = `${mergedConfig.borderStyle} ${mergedConfig.borderColor}`;\n placeholder.style.borderRadius = getComputedStyle(source).borderRadius;\n placeholder.style.background = mergedConfig.background!;\n placeholder.style.transition = `transform ${mergedConfig.transitionDuration}ms ease`;\n placeholder.style.pointerEvents = 'none';\n\n return placeholder;\n}\n\n/**\n * Options for placeholder positioning\n */\nexport interface PlacePlaceholderOptions {\n /** The sortable drag context */\n context: SortableDragContext;\n /** Selector to find sortable items */\n itemSelector: string;\n /** Sorting strategy to use */\n strategy: SortingStrategy;\n /** The element being dragged (to exclude from sibling calculations) */\n dragSource: HTMLElement | null;\n /** Target element under the pointer */\n dropTarget: HTMLElement | null;\n /** Pointer X coordinate */\n clientX: number;\n /** Pointer Y coordinate */\n clientY: number;\n /** Whether to animate sibling movements */\n enableAnimations: boolean;\n /** Animation configuration */\n animationConfig?: FlipAnimationOptions;\n}\n\n/**\n * Places the placeholder at the appropriate position within the sort container.\n * Uses FLIP animations for smooth sibling transitions.\n *\n * @returns The calculated insert position, or null if placement was skipped\n */\nexport function placePlaceholderAtPosition(options: PlacePlaceholderOptions): InsertPosition | null {\n const {\n context,\n itemSelector,\n strategy,\n dragSource,\n dropTarget,\n clientX,\n clientY,\n enableAnimations,\n animationConfig = { duration: 150, easing: 'ease' }\n } = options;\n\n if (!context.placeholder || !context.sortContainer) return null;\n\n const target = dropTarget || context.lastHoverTarget;\n if (!target || target === dragSource) return null;\n\n // Ensure placeholder is in the container\n if (context.placeholder.parentElement !== context.sortContainer) {\n context.sortContainer.appendChild(context.placeholder);\n }\n\n // Get visible siblings (exclude placeholder and hidden elements)\n const siblings = Array.from(context.sortContainer.querySelectorAll<HTMLElement>(itemSelector)).filter(\n el => el !== context.placeholder && el.style.display !== 'none'\n );\n\n if (!dragSource || siblings.indexOf(target) === -1) return null;\n\n // Use strategy to determine insertion position\n const insertPosition = strategy.getInsertPosition(siblings, dragSource, target, clientX, clientY);\n if (!insertPosition) return null;\n\n const { placeAfter } = insertPosition;\n\n // Check if this placement is the same as the last one\n if (context.lastPlacement && context.lastPlacement.target === target && context.lastPlacement.after === placeAfter) {\n return insertPosition;\n }\n\n // FLIP: First - capture positions of all visible siblings before moving placeholder\n const visibleSiblings = Array.from(context.sortContainer.children).filter(\n child => child !== context.placeholder && (child as HTMLElement).style.display !== 'none'\n ) as HTMLElement[];\n\n const flipStates = enableAnimations ? captureMultipleFlipStates(visibleSiblings) : null;\n\n // Calculate the reference node for insertion\n const referenceNode = placeAfter ? target.nextElementSibling : target;\n\n // FLIP: Last - perform the DOM mutation\n context.sortContainer.insertBefore(context.placeholder, referenceNode);\n context.lastPlacement = { target, after: placeAfter };\n\n // FLIP: Invert & Play - animate siblings to their new positions\n if (flipStates && enableAnimations) {\n animateMultipleFlips(flipStates, animationConfig);\n }\n\n return insertPosition;\n}\n\n/**\n * Options for finalizing a sortable drop\n */\nexport interface FinalizeSortableDropOptions {\n /** The sortable drag context */\n context: SortableDragContext;\n /** The element being dropped */\n draggable: HTMLElement;\n /** Callback after the element is placed */\n onPlaced?: (draggable: HTMLElement, container: HTMLElement) => void;\n}\n\n/**\n * Finalizes a sortable drop by replacing the placeholder with the actual element\n */\nexport function finalizeSortableDrop(options: FinalizeSortableDropOptions): boolean {\n const { context, draggable, onPlaced } = options;\n\n if (context.placeholder?.parentElement) {\n context.placeholder.parentElement.replaceChild(draggable, context.placeholder);\n\n // Restore draggable styles\n draggable.style.opacity = '1.0';\n draggable.style.display = '';\n draggable.style.pointerEvents = 'auto';\n\n if (onPlaced && context.sortContainer) {\n onPlaced(draggable, context.sortContainer);\n }\n\n // Cleanup\n context.placeholder = null;\n context.lastPlacement = null;\n\n return true;\n }\n\n return false;\n}\n\n/**\n * Cancels a sortable drag, cleaning up the placeholder\n */\nexport function cancelSortableDrag(context: SortableDragContext, dragSource: HTMLElement | null): void {\n if (dragSource) {\n dragSource.style.opacity = '1.0';\n dragSource.style.display = '';\n dragSource.style.pointerEvents = 'auto';\n }\n\n resetSortableDragContext(context);\n}\n\n/**\n * Reorders DOM elements according to a list of identifiers.\n * Uses FLIP animation for smooth transitions.\n */\nexport function reorderDOMByIdentifiers(\n container: HTMLElement,\n draggables: HTMLElement[],\n identifiers: string[],\n enableAnimations: boolean,\n animationConfig: FlipAnimationOptions = { duration: 250, easing: 'ease' }\n): void {\n if (!container) return;\n\n const byId = new Map(\n draggables\n .map(el => [el.getAttribute('identifier') ?? '', el] as const)\n .filter(([id]) => Boolean(id))\n );\n\n // FLIP: First - capture initial positions before DOM changes\n const flipStates = enableAnimations ? captureMultipleFlipStates(draggables) : null;\n\n // FLIP: Last - perform the DOM mutation\n identifiers.forEach(id => {\n const el = byId.get(id);\n if (el) {\n container.appendChild(el);\n }\n });\n\n // Append any elements not in the identifiers list at the end\n draggables\n .filter(el => {\n const id = el.getAttribute('identifier') ?? '';\n return id && !identifiers.includes(id);\n })\n .forEach(el => container.appendChild(el));\n\n // FLIP: Invert & Play - animate elements to their new positions\n if (flipStates && enableAnimations) {\n animateMultipleFlips(flipStates, animationConfig);\n }\n}\n\n/**\n * Collects identifiers from elements in DOM order\n */\nexport function collectIdentifiersInOrder(elements: HTMLElement[]): string[] {\n return elements.map(el => el.getAttribute('identifier')).filter((id): id is string => Boolean(id));\n}\n\n/**\n * Checks if an element is inside a slot/droppable container\n */\nexport function isElementInContainer(element: HTMLElement, containers: HTMLElement[]): HTMLElement | null {\n for (const container of containers) {\n if (container.contains(element) && container !== element) {\n return container;\n }\n }\n return null;\n}\n","import {\n createSortableDragContext,\n resetSortableDragContext,\n createDropPlaceholder,\n isElementInContainer,\n type SortableDragContext,\n type PlaceholderConfig\n} from './utils/sortable.utils';\nimport { captureMultipleFlipStates, animateMultipleFlips, type FlipAnimationOptions } from './utils/flip.utils';\nimport { detectCollision } from './utils/collision.utils';\n\nimport type { DragDropSlotted } from './drag-drop-slotted.mixin';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\nexport type DragDropSlottedSortable = DragDropSlotted & {\n allowReorder: boolean;\n readonly isDraggingFromSlot: boolean;\n sortablePlaceholderConfig: PlaceholderConfig;\n};\n\ninterface ShiftState {\n hoveredSlot: HTMLElement | null;\n originalPositions: Map<HTMLElement, HTMLElement>;\n}\n\nexport const DragDropSlottedSortableMixin = <T extends Constructor<DragDropSlotted>>(\n superClass: T,\n sortableItemSelector = '[qti-draggable=\"true\"]'\n) => {\n abstract class DragDropSlottedSortableElement extends superClass {\n #sourceSlot: HTMLElement | null = null;\n #sortableContext: SortableDragContext = createSortableDragContext();\n #shiftState: ShiftState = {\n hoveredSlot: null,\n originalPositions: new Map()\n };\n #temporarilyEnabledSlots = new Set<HTMLElement>();\n\n public allowReorder = true;\n public sortablePlaceholderConfig: PlaceholderConfig = {};\n public sortableAnimationConfig: FlipAnimationOptions = {\n duration: 150,\n easing: 'ease'\n };\n\n get isDraggingFromSlot(): boolean {\n return this.#sourceSlot !== null;\n }\n\n protected findContainingDroppable(element: HTMLElement): HTMLElement | null {\n return isElementInContainer(element, this.trackedDroppables);\n }\n\n #getItemInSlot(slot: HTMLElement): HTMLElement | null {\n return slot.querySelector(sortableItemSelector) as HTMLElement | null;\n }\n\n #slotAllowsMultiple(slot: HTMLElement): boolean {\n const matchMax = this.#getSlotMatchMax(slot);\n return matchMax === 0 || matchMax > 1;\n }\n\n #getSlotMatchMax(slot: HTMLElement): number {\n const parsedMatchMax = parseInt(slot.getAttribute('match-max') || '1', 10);\n return Number.isNaN(parsedMatchMax) ? 1 : parsedMatchMax;\n }\n\n #getSlotItemCount(slot: HTMLElement): number {\n return slot.querySelectorAll(sortableItemSelector).length;\n }\n\n #isSlotAtCapacity(slot: HTMLElement): boolean {\n const matchMax = this.#getSlotMatchMax(slot);\n if (matchMax === 0) return false;\n return this.#getSlotItemCount(slot) >= matchMax;\n }\n\n #resetShiftState(): void {\n this.#shiftState = {\n hoveredSlot: null,\n originalPositions: new Map()\n };\n }\n\n #performVisualSwap(targetSlot: HTMLElement): void {\n if (!this.#sourceSlot || targetSlot === this.#sourceSlot) {\n this.#revertVisualSwaps();\n return;\n }\n\n if (this.#shiftState.hoveredSlot === targetSlot) {\n return;\n }\n\n this.#revertVisualSwaps();\n\n const targetItem = this.#getItemInSlot(targetSlot);\n if (!targetItem) {\n if (this.#sortableContext.placeholder) {\n targetSlot.appendChild(this.#sortableContext.placeholder);\n }\n this.#shiftState.hoveredSlot = targetSlot;\n return;\n }\n\n // For multi-capacity slots we preview append semantics, not swap semantics.\n if (this.#slotAllowsMultiple(targetSlot)) {\n if (this.#isSlotAtCapacity(targetSlot)) {\n if (this.#sortableContext.placeholder && this.#sourceSlot) {\n this.#sourceSlot.appendChild(this.#sortableContext.placeholder);\n }\n this.#shiftState.hoveredSlot = null;\n return;\n }\n if (this.#sortableContext.placeholder) {\n targetSlot.appendChild(this.#sortableContext.placeholder);\n }\n this.#shiftState.hoveredSlot = targetSlot;\n return;\n }\n\n const itemsToAnimate = [targetItem];\n const flipStates = captureMultipleFlipStates(itemsToAnimate);\n\n this.#shiftState.originalPositions.set(targetItem, targetSlot);\n\n if (this.#sortableContext.placeholder && this.#sortableContext.placeholder.parentElement) {\n this.#sortableContext.placeholder.remove();\n }\n\n this.#sourceSlot.appendChild(targetItem);\n\n if (this.#sortableContext.placeholder) {\n targetSlot.appendChild(this.#sortableContext.placeholder);\n }\n\n this.#shiftState.hoveredSlot = targetSlot;\n\n animateMultipleFlips(flipStates, this.sortableAnimationConfig);\n }\n\n #revertVisualSwaps(): void {\n if (this.#shiftState.originalPositions.size === 0 && this.#shiftState.hoveredSlot === null) {\n return;\n }\n\n const itemsToAnimate = Array.from(this.#shiftState.originalPositions.keys());\n const flipStates = itemsToAnimate.length > 0 ? captureMultipleFlipStates(itemsToAnimate) : null;\n\n for (const [item, originalSlot] of this.#shiftState.originalPositions) {\n originalSlot.appendChild(item);\n }\n\n if (this.#sortableContext.placeholder && this.#sourceSlot) {\n this.#sourceSlot.appendChild(this.#sortableContext.placeholder);\n }\n\n if (flipStates) {\n animateMultipleFlips(flipStates, this.sortableAnimationConfig);\n }\n\n this.#shiftState.originalPositions.clear();\n this.#shiftState.hoveredSlot = null;\n }\n\n public override initiateDrag(\n dragElement: HTMLElement,\n startX: number,\n startY: number,\n inputType: 'mouse' | 'touch',\n ...rest: [eventSource?: 'pointer' | 'mouse' | 'touch']\n ): void {\n this.#sourceSlot = null;\n this.#sortableContext = createSortableDragContext();\n this.#resetShiftState();\n\n const containingDroppable = this.findContainingDroppable(dragElement);\n\n if (containingDroppable && this.allowReorder) {\n this.#sourceSlot = containingDroppable;\n this.#sortableContext.sortContainer = containingDroppable;\n\n const rect = dragElement.getBoundingClientRect();\n this.#sortableContext.placeholder = createDropPlaceholder(\n dragElement,\n rect,\n this.sortablePlaceholderConfig\n );\n // Copy the slot attribute from the dragged element so the placeholder\n // renders in the same named slot (e.g. slot=\"drags\" in qti-gap), preserving\n // the droppable's dimensions when the drag element is removed.\n // Use visibility:hidden instead of display:none so it occupies space but\n // remains invisible, preventing inline layout shift of surrounding text.\n const slotAttr = dragElement.getAttribute('slot');\n if (slotAttr) {\n this.#sortableContext.placeholder.setAttribute('slot', slotAttr);\n }\n this.#sortableContext.placeholder.style.visibility = 'hidden';\n\n containingDroppable.appendChild(this.#sortableContext.placeholder);\n\n // Temporarily enable peer slots so slot-origin drags can still land on max-gated targets.\n this.trackedDroppables.forEach(slot => {\n if (slot !== containingDroppable && slot.hasAttribute('disabled')) {\n if (this.#slotAllowsMultiple(slot) && this.#isSlotAtCapacity(slot)) {\n return;\n }\n slot.removeAttribute('disabled');\n this.#temporarilyEnabledSlots.add(slot);\n }\n });\n }\n\n const [eventSource] = rest;\n (super.initiateDrag as any)(dragElement, startX, startY, inputType, eventSource);\n }\n\n protected cleanupSortableState(revertSwaps = true): void {\n if (revertSwaps) {\n for (const [item, originalSlot] of this.#shiftState.originalPositions) {\n originalSlot.appendChild(item);\n }\n }\n\n if (this.#sortableContext.placeholder) {\n this.#sortableContext.placeholder.remove();\n }\n\n resetSortableDragContext(this.#sortableContext);\n this.#temporarilyEnabledSlots.clear();\n this.#sourceSlot = null;\n this.#resetShiftState();\n }\n\n public onSortableDragMove(clientX: number, clientY: number): void {\n if (!this.isDraggingFromSlot) return;\n\n const dropTarget = detectCollision(\n this.trackedDroppables,\n clientX,\n clientY,\n this.dragState.dragClone,\n this.collisionDetectionAlgorithm\n );\n\n if (dropTarget) {\n this.#performVisualSwap(dropTarget);\n } else {\n this.#revertVisualSwaps();\n }\n }\n\n protected handleDragMove(clientX: number, clientY: number): void {\n const baseProto = Object.getPrototypeOf(DragDropSlottedSortableElement.prototype) as {\n handleDragMove?: (x: number, y: number) => void;\n };\n baseProto.handleDragMove?.call(this, clientX, clientY);\n this.onSortableDragMove(clientX, clientY);\n }\n\n public override allowDrop(draggable: HTMLElement, droppable: HTMLElement): boolean {\n if (this.isDraggingFromSlot && this.trackedDroppables.includes(droppable)) {\n if (!this.#slotAllowsMultiple(droppable)) {\n return true;\n }\n return !this.#isSlotAtCapacity(droppable);\n }\n if (this.isDraggingFromSlot && this.trackedDragContainers.includes(droppable)) {\n return true;\n }\n return super.allowDrop(draggable, droppable);\n }\n\n public override handleDrop(draggable: HTMLElement, droppable: HTMLElement): void {\n super.handleDrop(draggable, droppable);\n this.cleanupSortableState(false);\n }\n\n public override handleInvalidDrop(dragSource: HTMLElement | null): void {\n this.cleanupSortableState();\n super.handleInvalidDrop(dragSource);\n }\n }\n\n return DragDropSlottedSortableElement as Constructor<DragDropSlottedSortable> & T;\n};\n\nexport type { PlaceholderConfig };\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 margin: 1rem 0;\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'] {\n display: grid;\n min-height: 3rem;\n min-width: 10rem;\n border: 1px solid var(--qti-border-color, #d1d5db);\n border-radius: 0.25rem;\n box-sizing: border-box;\n }\n\n [part='drop-container'] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\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 justify-content: space-between;\n background: linear-gradient(\n 180deg,\n rgb(0 0 0 / 0%) calc(50% - 1px),\n var(--qti-border-color) 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';\nimport { DragDropSlottedMixin, DragDropSlottedSortableMixin } from '@qti-components/interactions-core/mixins/drag-drop-observables';\n\n// import { DragDropInteractionMixin } from '@qti-components/interactions-core/mixins/drag-drop';\nimport styles from './qti-associate-interaction.styles';\n\nimport type { QtiSimpleAssociableChoice } from '@qti-components/interactions-core/elements/qti-simple-associable-choice';\nimport type { CSSResultGroup } from 'lit';\nconst SlottedBase = DragDropSlottedMixin(\n Interaction,\n 'qti-simple-associable-choice',\n '.dl',\n `slot[name='qti-simple-associable-choice']`,\n 'pointerWithin'\n);\n\nexport class QtiAssociateInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[qti-draggable=\"true\"]') {\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 // Use composedPath()[0] to get the actual origin — event.target is retargeted to `this`\n // when a composed event crosses the shadow DOM boundary, making it useless for filtering.\n const origin = event.composedPath()[0] as HTMLElement;\n // Ignore clones placed in shadow DOM drop zones — only register light DOM choices\n if (this.shadowRoot?.contains(origin)) return;\n const choice = origin as QtiSimpleAssociableChoice;\n if (!this._childrenMap.includes(choice)) {\n this._childrenMap = [...this._childrenMap, choice];\n }\n }\n\n protected getResponse(): string[] {\n const pairCount = Math.ceil(this._childrenMap.length / 2);\n const response: string[] = [];\n for (let i = 0; i < pairCount; i++) {\n const leftDrop = this.shadowRoot?.querySelector(`.dl[identifier=\"droplist${i}_left\"]`);\n const rightDrop = this.shadowRoot?.querySelector(`.dl[identifier=\"droplist${i}_right\"]`);\n const leftId = leftDrop?.querySelector('[qti-draggable=\"true\"]')?.getAttribute('identifier');\n const rightId = rightDrop?.querySelector('[qti-draggable=\"true\"]')?.getAttribute('identifier');\n if (leftId && rightId) {\n response.push(`${leftId} ${rightId}`);\n }\n }\n return response;\n }\n\n getValue(val: string[]) {\n return (\n val?.flatMap((pair, i) => {\n const parts = pair.split(' ');\n if (parts.length !== 2) return [];\n return [`${parts[0]} droplist${i}_left`, `${parts[1]} droplist${i}_right`];\n }) ?? []\n );\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 protected override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('_childrenMap')) {\n this.cacheInteractiveElements();\n }\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, 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 /* removed waitUntilFirstUpdate to fix issues with stories and tests */\n @watch('maxChoices')\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 async _setInputType(choiceElement: Choice) {\n this._internals.role = this.maxChoices === 1 ? 'radiogroup' : null;\n\n // Wait for the next update cycle to ensure DOM is ready before setting input type\n // There was a weird bug in the shuffle stories only where radiobuttons were not shown\n // This was because the choices were not upgraded to custom elements yet when this code ran, so internals was not available and role was not set\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 { property } from 'lit/decorators.js';\n\nimport type { QtiSimpleChoice } from '../../elements/qti-simple-choice';\nimport type { LitElement, PropertyValues } from 'lit';\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\ntype LabelType =\n | 'qti-labels-none'\n | 'qti-labels-decimal'\n | 'qti-labels-lower-alpha'\n | 'qti-labels-upper-alpha';\ntype LabelSuffixType =\n | 'qti-labels-suffix-none'\n | 'qti-labels-suffix-period'\n | '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 #classes: string[] = [];\n #allLabels: LabelType[] = [\n 'qti-labels-none',\n 'qti-labels-decimal',\n 'qti-labels-lower-alpha',\n 'qti-labels-upper-alpha',\n ];\n #allLabelSuffixes: LabelSuffixType[] = [\n 'qti-labels-suffix-none',\n 'qti-labels-suffix-period',\n 'qti-labels-suffix-parenthesis',\n ];\n #mutationObserver: MutationObserver | null = null;\n\n @property({\n type: String,\n attribute: 'class',\n })\n set class(value: string) {\n this.#classes = this.#tokenizeClasses(value);\n this.#syncLabels();\n }\n\n get class(): string {\n return this.#classes.join(' ');\n }\n\n override attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n super.attributeChangedCallback(name, oldValue, newValue);\n\n if (name === 'class' && oldValue !== newValue) {\n this.class = newValue ?? '';\n }\n }\n\n protected override updated(_changedProperties: PropertyValues): void {\n super.updated(_changedProperties);\n this.#syncLabels();\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.class = this.getAttribute('class') ?? '';\n this.#mutationObserver = new MutationObserver(mutations => {\n if (\n mutations.some(\n mutation =>\n mutation.type === 'childList' ||\n (mutation.type === 'attributes' && mutation.attributeName === 'style')\n )\n ) {\n this.#syncLabels();\n }\n });\n this.#mutationObserver.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style'],\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#mutationObserver?.disconnect();\n this.#mutationObserver = null;\n }\n\n #tokenizeClasses(value: string | null | undefined): string[] {\n if (!value) return [];\n\n return value\n .split(/\\s+/)\n .map(token => token.trim())\n .filter(Boolean)\n .filter((token, index, tokens) => tokens.indexOf(token) === index);\n }\n\n #syncLabels() {\n const choiceElements = Array.from(this.querySelectorAll('qti-simple-choice')).map(c => c as QtiSimpleChoice);\n const choices = this.#getOrderedChoices(choiceElements);\n const labelType = this.#getActiveLabelType();\n const labelSuffixType = this.#getActiveLabelSuffixType();\n\n choices.forEach((choice, index) => {\n choice.marker = this.#getLabel(index + 1, labelType, labelSuffixType);\n });\n }\n\n #getOrderedChoices(choiceElements: QtiSimpleChoice[]): QtiSimpleChoice[] {\n return choiceElements\n .map((choice, index) => {\n const order = Number(choice.style.order);\n return { el: choice, order: Number.isFinite(order) ? order : index + 1, index };\n })\n .sort((a, b) => a.order - b.order || a.index - b.index)\n .map(choice => choice.el);\n }\n\n #getActiveLabelType(): LabelType | null {\n return this.#classes.filter(c => this.#allLabels.includes(c as LabelType)).pop() as LabelType | undefined ?? null;\n }\n\n #getActiveLabelSuffixType(): LabelSuffixType | null {\n return this.#classes.filter(c => this.#allLabelSuffixes.includes(c as LabelSuffixType)).pop() as LabelSuffixType | undefined ?? null;\n }\n\n #getLabel(index: number, labelType: LabelType | null, labelSuffixType: LabelSuffixType | null): string {\n let effectiveLabelType = labelType;\n\n if (!effectiveLabelType && labelSuffixType && labelSuffixType !== 'qti-labels-suffix-none') {\n effectiveLabelType = 'qti-labels-upper-alpha';\n }\n\n if (!effectiveLabelType || effectiveLabelType === 'qti-labels-none') {\n return '';\n }\n\n let label = '';\n switch (effectiveLabelType) {\n case 'qti-labels-decimal':\n label = `${index}`;\n break;\n case 'qti-labels-lower-alpha':\n label = this.#toAlphabetic(index, 'lower');\n break;\n case 'qti-labels-upper-alpha':\n label = this.#toAlphabetic(index, 'upper');\n break;\n }\n\n if (labelSuffixType === 'qti-labels-suffix-period') {\n return `${label}.`;\n }\n\n if (labelSuffixType === 'qti-labels-suffix-parenthesis') {\n return `${label})`;\n }\n\n return label;\n }\n\n #toAlphabetic(index: number, casing: 'lower' | 'upper'): string {\n let value = index;\n let label = '';\n const charCodeBase = casing === 'lower' ? 97 : 65;\n\n while (value > 0) {\n value -= 1;\n label = String.fromCharCode(charCodeBase + (value % 26)) + label;\n value = Math.floor(value / 26);\n }\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 { html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\nimport { ChoicesMixin } from '@qti-components/interactions-core/mixins/choices/choices.mixin';\nimport { VocabularyMixin } from '@qti-components/interactions-core/mixins/vocabulary/vocabulary-mixin';\n\nimport styles from './qti-choice-interaction.styles';\n\nimport type { ChoicesInterface } from '@qti-components/interactions-core/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 #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 { css } from 'lit';\n\nexport default css``;\n","import { html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { Interaction, removeDoubleSlashes } from '@qti-components/base';\n\nimport styles from './qti-custom-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\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 (function() {\n var blobUrlReceived = null;\n \n const createIframe = () => {\n if (!blobUrlReceived || !document.body) return;\n var n = document.createElement('iframe');\n n.frameBorder = '0';\n n.scrolling = 'no';\n n.src = blobUrlReceived;\n n.style.width = '100%';\n n.style.height = '100%';\n document.body.appendChild(n);\n };\n \n const handleMessage = (event) => {\n if (event.data.type === 'blobUrl') {\n blobUrlReceived = event.data.data;\n window.removeEventListener('message', handleMessage);\n createIframe();\n }\n };\n \n window.addEventListener('message', handleMessage);\n \n // Wait for document ready before requesting blobUrl\n const requestBlobUrl = () => {\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 if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', requestBlobUrl);\n } else {\n requestBlobUrl();\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 #rawResponse: string | string[] = '';\n #manifestUrl: string = null;\n #resourceBaseUrl: string = null;\n static override styles: CSSResultGroup = styles;\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 #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\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\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\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 if (indexResolved.text) {\n let html = indexResolved.text;\n\n // Check if the HTML was already modified (e.g., by backend import process)\n // If it already has postToParentWindows or CES proxy, skip injection\n const alreadyModified = html.includes('postToParentWindows') || html.includes('window.CES');\n\n if (!alreadyModified) {\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\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 if (indexResolved.text) {\n let html = indexResolved.text;\n\n // Check if the HTML was already modified (e.g., by backend import process)\n const alreadyModified = html.includes('postToParentWindows') || html.includes('window.CES');\n\n if (!alreadyModified) {\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\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 // Check if the HTML was already modified (e.g., by backend import process)\n const alreadyModified = html.includes('postToParentWindows') || html.includes('window.CES');\n\n if (!alreadyModified) {\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\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\n window.addEventListener('message', this.handlePostMessage);\n\n const htmlContent = `\n <!DOCTYPE html>\n <html>\n <head>\n ${cssUrl ? `<link href='${cssUrl}' rel=\"stylesheet\" />` : ''}\n ${inlineScript}\n </head>\n <body></body>\n </html>\n `;\n\n // Use srcdoc instead of document.write for better script execution\n iframe.srcdoc = htmlContent;\n }\n\n #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 #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 #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 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 // Also respond directly to the source window if possible\n if (event.source && event.source !== window) {\n (event.source as Window).postMessage({ type: 'blobUrl', data: this.#contentBlobUrl }, '*');\n }\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 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 #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 #getManifestBaseUrl(): string | null {\n if (!this.#manifestUrl) {\n return null;\n }\n return new URL('.', this.#manifestUrl).toString();\n }\n\n #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 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 { css } from 'lit';\n\nexport default css``;\n","import { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport styles from './qti-end-attempt-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nexport class QtiEndAttemptInteraction extends LitElement {\n static override styles: CSSResultGroup = styles;\n\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';\nimport { DragDropSlottedMixin, DragDropSlottedSortableMixin } from '@qti-components/interactions-core/mixins/drag-drop-observables';\n\n// import { DragDropInteractionMixin } from '@qti-components/interactions-core/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 '@qti-components/interactions-core/elements/qti-gap';\nimport type { QtiGapText } from '@qti-components/interactions-core/elements/qti-gap-text';\nimport type { CSSResultGroup } from 'lit';\nconst SlottedBase = DragDropSlottedMixin(\n Interaction,\n 'qti-gap-text',\n 'qti-gap',\n `slot[part='drags']`\n);\n\nexport class QtiGapMatchInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[qti-draggable=\"true\"]') {\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 #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<QtiGapText>(`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';\nimport { positionShapes } from '@qti-components/interactions-core/internal/hotspots/hotspot';\n\nimport styles from './qti-graphic-associate-interaction.styles';\n\nimport type { QtiAssociableHotspot } from '@qti-components/interactions-core/elements/qti-associable-hotspot';\nimport type { QtiHotspotChoice } from '@qti-components/interactions-core/elements/qti-hotspot-choice';\nimport type { CSSResultGroup } from 'lit';\nexport class QtiGraphicAssociateInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\n\n #hotspots: any[] | NodeListOf<QtiAssociableHotspot>;\n #startPoint: HTMLElement | null = null;\n #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' }) 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 #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 #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 #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 = thisgrImage[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';\nimport { DragDropSlottedMixin, DragDropSlottedSortableMixin } from '@qti-components/interactions-core/mixins/drag-drop-observables';\n\n// import { DragDropInteractionMixin } from '@qti-components/interactions-core/mixins/drag-drop';\nimport styles from './qti-graphic-gap-match-interaction.styles';\n\nimport type { QtiHotspotChoice } from '@qti-components/interactions-core/elements/qti-hotspot-choice';\nimport type { CSSResultGroup } from 'lit';\nconst SlottedBase = DragDropSlottedMixin(\n Interaction,\n 'qti-gap-img, qti-gap-text',\n 'qti-associable-hotspot',\n `slot[part='drags']`\n);\n\nexport class QtiGraphicGapMatchInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[qti-draggable=\"true\"]') {\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 public override shouldReturnToInventoryOnInventoryDrop(): boolean {\n return true;\n }\n\n #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';\nimport { ChoicesMixin } from '@qti-components/interactions-core/mixins/choices/choices.mixin';\nimport { positionShapes } from '@qti-components/interactions-core/internal/hotspots/hotspot';\n\nimport styles from './qti-graphic-order-interaction.styles';\n\nimport type { QtiHotspotChoice } from '@qti-components/interactions-core/elements/qti-hotspot-choice';\nimport type { Choice } from '@qti-components/interactions-core/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 #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 #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';\nimport { ChoicesMixin } from '@qti-components/interactions-core/mixins/choices/choices.mixin';\nimport { positionShapes } from '@qti-components/interactions-core/internal/hotspots/hotspot';\n\nimport styles from './qti-hotspot-interaction.styles';\n\nimport type { QtiHotspotChoice } from '@qti-components/interactions-core/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 #imageLoadPromise: Promise<HTMLImageElement> | null = null;\n\n #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 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 { css } from 'lit';\n\nexport default css``;\n","import { html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\nimport { ChoicesMixin } from '@qti-components/interactions-core/mixins/choices/choices.mixin';\n\nimport styles from './qti-hottext-interaction.styles';\n\nimport type { CSSResultGroup, PropertyValues } from 'lit';\nexport class QtiHottextInteraction extends ChoicesMixin(Interaction, 'qti-hottext') {\n static override styles: CSSResultGroup = styles;\n\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 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 #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 } from 'lit';\n\nimport type { CSSResultGroup } from 'lit';\n\nconst styles: CSSResultGroup = css`\n :host {\n display: inline-block;\n vertical-align: baseline;\n position: relative;\n }\n\n button[part='trigger'] {\n anchor-name: --qti-inline-choice-trigger;\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 line-height: 1;\n }\n\n [part='menu'] {\n position-anchor: --qti-inline-choice-trigger;\n inset: auto;\n margin: 0;\n z-index: 1000;\n top: calc(anchor(bottom) + 4px);\n left: anchor(left);\n min-width: anchor-size(width);\n max-width: min(90vw, 36rem);\n max-height: min(40vh, 20rem);\n position-try-fallbacks: flip-block, flip-inline;\n }\n\n button[part~='option'] {\n width: 100%;\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 overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n }\n\n button[part~='option'] img,\n button[part='trigger'] img,\n [part='menu'] img {\n display: inline-block;\n vertical-align: middle;\n }\n`;\n\nexport default styles;\n","import { 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 styles from './qti-inline-choice-interaction.styles.js';\n\nimport type { PropertyValues } from 'lit';\nimport type { ConfigContext } from '@qti-components/base';\nimport type { ActiveElementMixinInterface } from '@qti-components/interactions-core/mixins/active-element/active-element.mixin';\n\ninterface OptionType {\n textContent: string;\n value: string;\n selected: boolean;\n}\n\ntype InlineChoiceOptionElement = HTMLElement & ActiveElementMixinInterface;\n\nlet inlineChoiceMenuCounter = 0;\n\nexport class QtiInlineChoiceInteraction extends Interaction {\n constructor() {\n super();\n this.internals.role = 'listbox';\n }\n\n override get isInline(): boolean {\n return true;\n }\n\n static override get styles() {\n return [styles];\n }\n\n @state()\n protected options: OptionType[] = [];\n\n @state()\n protected correctOption: string = '';\n\n @state()\n protected _dropdownOpen = false;\n\n private _slotObserver: MutationObserver | null = null;\n private readonly _menuId = `qti-inline-choice-menu-${inlineChoiceMenuCounter++}`;\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\n return html`\n <button\n part=\"trigger\"\n type=\"button\"\n @click=${this.#onTriggerClick}\n @keydown=${this.#onCustomTriggerKeyDown}\n aria-haspopup=\"listbox\"\n aria-expanded=\"${this._dropdownOpen ? 'true' : 'false'}\"\n aria-controls=\"${this._menuId}\"\n popovertarget=\"${this._menuId}\"\n popovertargetaction=\"toggle\"\n ?disabled=\"${this.disabled}\"\n data-readonly=\"${this.readonly ? 'true' : 'false'}\"\n >\n <span part=\"value\">${unsafeHTML(selected?.textContent ?? '')}</span>\n <span part=\"${this._dropdownOpen ? 'dropdown-icon dropdown-icon-open' : 'dropdown-icon'}\" aria-hidden=\"true\"\n >▾</span\n >\n </button>\n <div\n id=\"${this._menuId}\"\n part=\"menu\"\n role=\"listbox\"\n popover=\"auto\"\n @toggle=${this.#onMenuToggle}\n @keydown=${this.#onCustomMenuKeyDown}\n >\n <button\n part=\"${this.options[0]?.selected ? 'option option-prompt option-selected' : 'option option-prompt'}\"\n type=\"button\"\n role=\"option\"\n aria-selected=\"${this.options[0]?.selected ? 'true' : 'false'}\"\n @click=${() => this.#selectValue('')}\n >\n <span part=\"option-content\">${unsafeHTML(this.options[0]?.textContent ?? '')}</span>\n </button>\n <slot @slotchange=${this.#onChoicesSlotChange}></slot>\n </div>\n ${unsafeHTML(this.correctOption)}\n `;\n }\n\n override async connectedCallback() {\n super.connectedCallback();\n this.#updateOptions();\n this.#startSlotObserver();\n\n // Simple width estimation - no recalculation needed\n await this.updateComplete;\n\n this.#estimateOptimalWidth();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n this.#teardownSlottedChoices();\n this._slotObserver?.disconnect();\n this._slotObserver = null;\n }\n\n override willUpdate(changed: PropertyValues<this>) {\n if (changed.has('configContext')) {\n this.#updateOptions();\n }\n }\n\n override updated(changed: PropertyValues<this>) {\n const dropdownOpenKey = '_dropdownOpen' as keyof QtiInlineChoiceInteraction;\n if (changed.has(dropdownOpenKey) && this._dropdownOpen) {\n this.#syncSlottedChoices();\n const first = this.#allMenuOptions()[0];\n first?.focus();\n }\n\n if (changed.has('disabled') || changed.has('readonly')) {\n this.#syncSlottedChoices();\n }\n }\n\n #selectedOption(): OptionType | undefined {\n return this.options.find(option => option.selected) ?? this.options[0];\n }\n\n #updateOptions() {\n const choices = Array.from(this.querySelectorAll('qti-inline-choice'));\n const prompt = this.dataset.prompt || 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 this.#syncSlottedChoices();\n\n // Simple width estimation based on content length\n this.#estimateOptimalWidth();\n }\n\n #estimateOptimalWidth() {\n const menu = this.#menuElement();\n const trigger = this.renderRoot.querySelector<HTMLElement>('button[part=\"trigger\"]');\n\n if (!menu || !trigger) return;\n\n // Find dropdown icon element inside the trigger\n const dropdownIcon = trigger.querySelector<HTMLElement>('span[part~=\"dropdown-icon\"]');\n const iconWidth = dropdownIcon ? dropdownIcon.getBoundingClientRect().width : 0;\n\n // Save current popover state and style\n const wasOpen = menu.matches(':popover-open');\n const prevVisibility = menu.style.visibility;\n const prevDisplay = menu.style.display;\n\n // Open the menu invisibly for measurement\n if (!wasOpen) {\n menu.style.visibility = 'hidden';\n menu.style.display = 'block';\n menu.showPopover();\n }\n\n // Measure width\n const rectWidth = menu.getBoundingClientRect().width;\n const widthPx = Math.max(rectWidth, menu.scrollWidth);\n\n // Restore menu state and style\n if (!wasOpen) {\n menu.hidePopover();\n menu.style.visibility = prevVisibility;\n menu.style.display = prevDisplay;\n }\n\n trigger.style.width = `${widthPx + iconWidth}px`;\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 this.#syncSlottedChoices();\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 this.#syncSlottedChoices();\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 #selectValue(value: string) {\n this.options = this.options.map(option => ({ ...option, selected: option.value === value }));\n this.#syncSlottedChoices();\n this.saveResponse(value);\n this.#setDropdownOpen(false);\n }\n\n #setDropdownOpen(open: boolean) {\n const menu = this.#menuElement();\n if (!menu) return;\n\n if (open) {\n if (!menu.matches(':popover-open')) {\n menu.showPopover();\n }\n return;\n }\n\n if (menu.matches(':popover-open')) {\n menu.hidePopover();\n }\n }\n\n #onTriggerClick = (event: MouseEvent) => {\n if (this.disabled || this.readonly) {\n event.preventDefault();\n }\n };\n\n #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 #onMenuToggle = (event: Event) => {\n const toggleEvent = event as Event & { newState?: 'open' | 'closed' };\n const open = toggleEvent.newState === 'open';\n if (this._dropdownOpen !== open) {\n this._dropdownOpen = open;\n }\n };\n\n #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 optionElements = this.#allMenuOptions();\n const shadowActive = (this.renderRoot as ShadowRoot).activeElement as HTMLElement | null;\n const deepActive = this.#getDeepActiveElement();\n const active =\n shadowActive ||\n (deepActive instanceof HTMLElement && this.#isElementInsideInteraction(deepActive) ? deepActive : null);\n const activeIndex = optionElements.findIndex(el => el === active);\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n optionElements[Math.min(optionElements.length - 1, Math.max(0, activeIndex + 1))]?.focus();\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n optionElements[Math.max(0, activeIndex - 1)]?.focus();\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n if (!active) return;\n event.preventDefault();\n if (active instanceof HTMLButtonElement) {\n active.click();\n } else {\n const value = active.getAttribute('identifier') ?? '';\n this.#selectValue(value);\n }\n }\n };\n\n #focusTrigger() {\n this.renderRoot.querySelector<HTMLButtonElement>('button[part=\"trigger\"]')?.focus();\n }\n\n #getDeepActiveElement(): Element | null {\n let current: Element | null = document.activeElement;\n\n while (current && current instanceof HTMLElement && current.shadowRoot?.activeElement) {\n current = current.shadowRoot.activeElement;\n }\n\n return current;\n }\n\n #isElementInsideInteraction(element: HTMLElement): boolean {\n return element === this || this.contains(element) || this.renderRoot.contains(element);\n }\n\n #menuElement(): HTMLElement | null {\n return this.renderRoot.querySelector<HTMLElement>(`#${this._menuId}`);\n }\n\n #startSlotObserver() {\n this._slotObserver = new MutationObserver(() => this.#updateOptions());\n this._slotObserver.observe(this, { childList: true, subtree: true });\n }\n\n #onChoicesSlotChange = () => {\n this.#updateOptions();\n };\n\n #onSlottedChoiceClick = (event: Event) => {\n if (this.disabled || this.readonly) return;\n const target = event.currentTarget as HTMLElement;\n const value = target.getAttribute('identifier') ?? '';\n this.#selectValue(value);\n };\n\n #teardownSlottedChoices() {\n const choices = Array.from(this.querySelectorAll<InlineChoiceOptionElement>('qti-inline-choice'));\n for (const choice of choices) {\n choice.removeEventListener('click', this.#onSlottedChoiceClick);\n choice.removeAttribute('tabindex');\n choice.internals.role = null;\n choice.internals.ariaSelected = null;\n choice.internals.ariaChecked = 'false';\n choice.internals.states.delete('--checked');\n }\n }\n\n async #syncSlottedChoices() {\n await this.updateComplete;\n const selectedValue = this.options.find(option => option.selected)?.value ?? '';\n const choices = Array.from(this.querySelectorAll<InlineChoiceOptionElement>('qti-inline-choice'));\n for (const choice of choices) {\n const value = choice.getAttribute('identifier') ?? '';\n const isSelected = value === selectedValue;\n choice.removeEventListener('click', this.#onSlottedChoiceClick);\n choice.addEventListener('click', this.#onSlottedChoiceClick);\n choice.disabled = this.disabled;\n choice.readonly = this.readonly;\n choice.internals.role = 'option';\n choice.internals.ariaSelected = isSelected ? 'true' : 'false';\n choice.internals.ariaChecked = isSelected ? 'true' : 'false';\n choice.internals.ariaDisabled = this.disabled ? 'true' : 'false';\n choice.internals.ariaReadOnly = this.readonly ? 'true' : 'false';\n choice.removeAttribute('aria-disabled');\n choice.removeAttribute('aria-readonly');\n if (isSelected) {\n choice.internals.states.add('--checked');\n } else {\n choice.internals.states.delete('--checked');\n }\n choice.tabIndex = -1;\n }\n }\n\n #allMenuOptions(): HTMLElement[] {\n const promptOption = this.renderRoot.querySelector<HTMLElement>('button[part~=\"option\"]');\n const slottedChoices = Array.from(this.querySelectorAll<HTMLElement>('qti-inline-choice'));\n return [...(promptOption ? [promptOption] : []), ...slottedChoices];\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';\nimport { DragDropSlottedMixin, DragDropSlottedSortableMixin } from '@qti-components/interactions-core/mixins/drag-drop-observables';\n\n// import { DragDropInteractionMixin } from '@qti-components/interactions-core/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 '@qti-components/interactions-core/elements/qti-simple-associable-choice';\nconst SlottedBase = DragDropSlottedMixin(\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\nexport class QtiMatchInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[qti-draggable=\"true\"]') {\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 #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 } from 'lit';\n\nexport default css``;\n","import { html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\n\nimport styles from './qti-media-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nexport class QtiMediaInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\n\n #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 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='drop-list'][data-cross-slot-target] {\n border-color: var(--qti-border-active, #0066cc) !important;\n background-color: var(--qti-bg-active, rgba(0, 102, 204, 0.1)) !important;\n outline: 2px dashed var(--qti-border-active, #0066cc);\n outline-offset: -2px;\n }\n\n /* Candidate correction colors for choices placed inside drop-lists. */\n drop-list [qti-draggable='true']:state(candidate-correct),\n [part='qti-simple-choice']:state(candidate-correct) {\n background-color: var(--qti-correct) !important;\n }\n\n drop-list [qti-draggable='true']:state(candidate-incorrect),\n [part='qti-simple-choice']:state(candidate-incorrect) {\n background-color: var(--qti-incorrect) !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';\nimport {\n DragDropSlottedMixin,\n DragDropSlottedSortableMixin\n} from '@qti-components/interactions-core/mixins/drag-drop-observables';\n\nimport styles from './qti-order-interaction.styles';\n\nimport type { PropertyValueMap } from 'lit';\nimport type { QtiSimpleChoice } from '@qti-components/interactions-core/elements/qti-simple-choice';\n\nconst SlottedBase = DragDropSlottedMixin(Interaction, `qti-simple-choice`, 'drop-list', `slot[part='drags']`);\n\nexport class QtiOrderInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[qti-draggable=\"true\"]') {\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 #getCorrectOrderEntries(): Array<{ identifier: string; dropIndex: number }> {\n const responseVariable = this.responseVariable;\n if (!responseVariable?.correctResponse) {\n return [];\n }\n\n const response = Array.isArray(responseVariable.correctResponse)\n ? responseVariable.correctResponse\n : [responseVariable.correctResponse];\n\n return response\n .map((entry, index) => {\n const [identifier, dropId] = entry.split(' ');\n const parsedDropIndex = dropId?.startsWith('droplist') ? parseInt(dropId.replace('droplist', ''), 10) : index;\n const dropIndex = Number.isNaN(parsedDropIndex) ? index : parsedDropIndex;\n return { identifier, dropIndex };\n })\n .filter(entry => Boolean(entry.identifier));\n }\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 // Always start by removing old correct answers\n this.shadowRoot.querySelectorAll('.correct-option').forEach(option => option.remove());\n\n if (show) {\n const entries = this.#getCorrectOrderEntries();\n const labelsByIdentifier = new Map<string, string>();\n Array.from(this.querySelectorAll('qti-simple-choice')).forEach(choice => {\n const id = choice.getAttribute('identifier');\n const label = choice.textContent?.trim();\n if (id && label) {\n labelsByIdentifier.set(id, label);\n }\n });\n\n entries.forEach(({ identifier, dropIndex }) => {\n const label = labelsByIdentifier.get(identifier);\n if (!label) return;\n\n const relativeDrop = this.shadowRoot.querySelector(`drop-list[identifier=\"droplist${dropIndex}\"]`);\n if (!relativeDrop) return;\n\n const span = document.createElement('span');\n span.classList.add('correct-option');\n span.textContent = label;\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 public override toggleCandidateCorrection(show: boolean): void {\n super.toggleCandidateCorrection(show);\n\n const placedChoices = Array.from(\n this.shadowRoot.querySelectorAll<QtiSimpleChoice>('drop-list [qti-draggable=\"true\"]')\n );\n placedChoices.forEach(choice => {\n choice.internals.states.delete('candidate-correct');\n choice.internals.states.delete('candidate-incorrect');\n });\n\n if (!show) return;\n\n const entries = this.#getCorrectOrderEntries();\n const correctByDrop = new Map<number, string>();\n entries.forEach(entry => correctByDrop.set(entry.dropIndex, entry.identifier));\n\n const dropLists = Array.from(this.shadowRoot.querySelectorAll<HTMLElement>('drop-list'));\n dropLists.forEach((dropList, index) => {\n const placedChoice = dropList.querySelector<QtiSimpleChoice>('[qti-draggable=\"true\"]');\n if (!placedChoice) return;\n\n const expectedIdentifier = correctByDrop.get(index);\n const actualIdentifier = placedChoice.getAttribute('identifier');\n if (expectedIdentifier && actualIdentifier === expectedIdentifier) {\n placedChoice.internals.states.add('candidate-correct');\n } else {\n placedChoice.internals.states.add('candidate-incorrect');\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 public override shouldTreatBlockedMaxAsInvalid(): boolean {\n return false;\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 :host {\n display: block;\n width: 100%;\n min-height: 50px;\n }\n\n ::slotted(qti-interaction-markup) {\n display: none;\n }\n`;\n","import { css, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { consume } from '@lit/context';\n\nimport { Interaction, itemContext, qtiContext, removeDoubleSlashes } from '@qti-components/base';\n\nimport styles from './qti-portable-custom-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nimport type { BaseType, Cardinality, ItemContext, QtiContext } from '@qti-components/base';\nimport type { QtiRecordItem, QtiVariableJSON, ResponseVariableType } from './interface';\n\nexport class QtiPortableCustomInteraction extends Interaction {\n #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 private _iframeObjectUrl: 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-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 @consume({ context: qtiContext, subscribe: true })\n @state()\n protected qtiContext?: QtiContext;\n\n @state() response: string | string[] | null = null;\n\n #parsedRequirePaths: Record<string, string | string[]> = null;\n #parsedRequireShim: Record<string, any> = null;\n #pciValidity: boolean | null = null;\n #pciCustomValidityMessage = '';\n\n /**\n * Parse the require paths JSON string into an object\n */\n #getRequirePaths(): Record<string, string | string[]> {\n if (this.#parsedRequirePaths === null && this.requirePathsJson) {\n try {\n const parsedJson = JSON.parse(this.requirePathsJson);\n if (Array.isArray(parsedJson) || !parsedJson || typeof parsedJson !== 'object') {\n throw new Error('Require paths must be a JSON object.');\n }\n this.#parsedRequirePaths = parsedJson;\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 #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 final require paths by combining defaults with user-provided paths\n */\n #getFinalRequirePaths(): Record<string, string | string[]> {\n // Return only user-provided paths to keep PCI completely self-contained\n return this.#getRequirePaths();\n }\n\n /**\n * Get the final require shim\n */\n #getFinalRequireShim(): Record<string, any> {\n return this.#getRequireShim();\n }\n\n /**\n * Converts QtiVariableJSON to a string or string array\n */\n #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 * Get direct child elements by tag name\n */\n private getDirectChildrenByTag(tagName: string): Element[] {\n const needle = tagName.toLowerCase();\n return Array.from(this.children).filter(child => child.tagName.toLowerCase() === needle);\n }\n\n /**\n * Coerce a scalar value to the expected base-type when possible\n */\n private coerceBaseValue(value: unknown, baseType: BaseType): unknown {\n if (value === null || value === undefined) return value;\n\n switch (baseType) {\n case 'integer': {\n if (typeof value === 'number') return value;\n const parsed = parseInt(String(value), 10);\n return Number.isNaN(parsed) ? value : parsed;\n }\n case 'float':\n case 'duration': {\n if (typeof value === 'number') return value;\n const parsed = parseFloat(String(value));\n return Number.isNaN(parsed) ? value : parsed;\n }\n case 'boolean': {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') {\n const lowered = value.toLowerCase();\n if (lowered === 'true') return true;\n if (lowered === 'false') return false;\n }\n return value;\n }\n case 'string':\n case 'identifier':\n default:\n return String(value);\n }\n }\n\n /**\n * Normalize an input into a list form\n */\n private normalizeListValue(value: unknown): unknown[] {\n if (value === null || value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n }\n\n /**\n * Convert a variable value to QtiVariableJSON\n */\n private variableToQtiVariableJSON(value: unknown, cardinality: Cardinality, baseType: BaseType): QtiVariableJSON {\n if (cardinality === 'record' || baseType === 'record') {\n return this.recordToQtiVariableJSON(value);\n }\n\n if (cardinality !== 'single') {\n const listValues = this.normalizeListValue(value).map(v => this.coerceBaseValue(v, baseType));\n return { list: { [baseType]: listValues } };\n }\n\n return { base: { [baseType]: this.coerceBaseValue(value, baseType) } };\n }\n\n /**\n * Convert a record object into QtiVariableJSON\n */\n private recordToQtiVariableJSON(value: unknown): QtiVariableJSON {\n if (!value || typeof value !== 'object') {\n return { record: [] };\n }\n\n const recordEntries: QtiRecordItem[] = [];\n for (const [name, entryValue] of Object.entries(value as Record<string, unknown>)) {\n recordEntries.push(this.recordEntryFromValue(name, entryValue));\n }\n\n return { record: recordEntries };\n }\n\n /**\n * Build a record entry from an arbitrary value\n */\n private recordEntryFromValue(name: string, entryValue: unknown): QtiRecordItem {\n if (Array.isArray(entryValue)) {\n const filtered = entryValue.filter(v => v !== null && v !== undefined);\n\n if (filtered.length && filtered.every(v => typeof v === 'boolean')) {\n return { name, list: { boolean: filtered as boolean[] } };\n }\n\n if (filtered.length && filtered.every(v => typeof v === 'number')) {\n const numbers = filtered as number[];\n const isIntegers = numbers.every(n => Number.isInteger(n));\n return { name, list: { [isIntegers ? 'integer' : 'float']: numbers } };\n }\n\n return { name, list: { string: entryValue.map(v => (v === null || v === undefined ? '' : String(v))) } };\n }\n\n if (typeof entryValue === 'boolean') {\n return { name, base: { boolean: entryValue } };\n }\n\n if (typeof entryValue === 'number') {\n if (Number.isInteger(entryValue)) return { name, base: { integer: entryValue } };\n return { name, base: { float: entryValue } };\n }\n\n if (entryValue === null || entryValue === undefined) {\n return { name, base: { string: '' } };\n }\n\n if (typeof entryValue === 'object') {\n try {\n return { name, base: { string: JSON.stringify(entryValue) } };\n } catch {\n return { name, base: { string: String(entryValue) } };\n }\n }\n\n return { name, base: { string: String(entryValue) } };\n }\n\n /**\n * Extract default QTI_CONTEXT values from qti-context-declaration elements\n */\n private getQtiContextDefaultsFromItem(): Record<string, unknown> {\n const itemElement = this.closest('qti-assessment-item');\n if (!itemElement) return {};\n\n const defaults: Record<string, unknown> = {};\n const contextDeclarations = itemElement.querySelectorAll('qti-context-declaration[identifier=\"QTI_CONTEXT\"]');\n\n contextDeclarations.forEach(declaration => {\n const defaultValueElement = declaration.querySelector('qti-default-value');\n if (!defaultValueElement) return;\n\n const valueElements = defaultValueElement.querySelectorAll('qti-value[field-identifier]');\n valueElements.forEach(valueElement => {\n const fieldIdentifier = valueElement.getAttribute('field-identifier');\n if (!fieldIdentifier) return;\n\n const baseType = (valueElement.getAttribute('base-type') || 'string') as BaseType;\n const textContent = valueElement.textContent?.trim() || '';\n defaults[fieldIdentifier] = this.coerceBaseValue(textContent, baseType);\n });\n });\n\n return defaults;\n }\n\n /**\n * Build a QTI_CONTEXT record for PCI consumption\n */\n private getQtiContextRecord(): QtiVariableJSON | null {\n const defaults = this.getQtiContextDefaultsFromItem();\n const runtime = this.qtiContext?.QTI_CONTEXT || {};\n const merged: Record<string, unknown> = { ...defaults, ...runtime };\n if (!Object.keys(merged).length) return null;\n\n const normalized = {\n candidateIdentifier: merged.candidateIdentifier ?? '',\n testIdentifier: merged.testIdentifier ?? '',\n environmentIdentifier: merged.environmentIdentifier ?? '',\n ...merged\n };\n\n return this.recordToQtiVariableJSON(normalized);\n }\n\n /**\n * Collect template variables referenced by qti-template-variable children\n */\n private getTemplateVariables(): Record<string, QtiVariableJSON> {\n const templateVariables: Record<string, QtiVariableJSON> = {};\n const templateVariableElements = this.getDirectChildrenByTag('qti-template-variable');\n if (!templateVariableElements.length) return templateVariables;\n\n templateVariableElements.forEach(el => {\n const identifier = el.getAttribute('template-identifier') || el.getAttribute('identifier') || '';\n if (!identifier) return;\n\n const variable = this.context?.variables?.find(v => v.identifier === identifier);\n if (!variable) return;\n\n const cardinality = (variable.cardinality || 'single') as Cardinality;\n const baseType = (variable.baseType || 'string') as BaseType;\n templateVariables[identifier] = this.variableToQtiVariableJSON(variable.value, cardinality, baseType);\n });\n\n return templateVariables;\n }\n\n /**\n * Collect context variables referenced by qti-context-variable children\n */\n private getContextVariables(): Record<string, QtiVariableJSON> {\n const contextVariables: Record<string, QtiVariableJSON> = {};\n const contextVariableElements = this.getDirectChildrenByTag('qti-context-variable');\n if (!contextVariableElements.length) return contextVariables;\n\n contextVariableElements.forEach(el => {\n const identifier = el.getAttribute('identifier') || '';\n if (!identifier) return;\n\n if (identifier === 'QTI_CONTEXT') {\n const record = this.getQtiContextRecord();\n if (record) contextVariables[identifier] = record;\n return;\n }\n\n const variable = this.context?.variables?.find(v => v.identifier === identifier);\n if (!variable) return;\n\n const cardinality = (variable.cardinality || 'single') as Cardinality;\n const baseType = (variable.baseType || 'string') as BaseType;\n contextVariables[identifier] = this.variableToQtiVariableJSON(variable.value, cardinality, baseType);\n });\n\n return contextVariables;\n }\n\n /**\n * Adds hyphenated versions of camelCase keys to properties object\n */\n #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 #toNestedProperties(properties: Record<string, any>): Record<string, any> {\n const nestedProperties = { ...properties };\n\n const setNestedValue = (root: Record<string, any>, path: string[], value: any): void => {\n let cursor = root;\n\n for (let i = 0; i < path.length; i += 1) {\n const segment = path[i];\n const isLast = i === path.length - 1;\n\n if (isLast) {\n cursor[segment] = value;\n return;\n }\n\n if (!cursor[segment] || typeof cursor[segment] !== 'object' || Array.isArray(cursor[segment])) {\n cursor[segment] = {};\n }\n\n cursor = cursor[segment];\n }\n };\n\n for (const [key, value] of Object.entries(properties)) {\n if (!key.includes('__')) continue;\n const path = key.split('__').filter(Boolean);\n if (path.length < 2) continue;\n setNestedValue(nestedProperties, path, value);\n }\n\n return nestedProperties;\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 #hasNonEmptyResponse(): 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 #setInteractionValidity(isValid: boolean, customMessage?: string): void {\n const fallbackMessage = this.dataset.invalidresponsemessage || 'Invalid response.';\n const message = isValid ? '' : customMessage && customMessage.trim().length > 0 ? customMessage : fallbackMessage;\n this._internals.setValidity(isValid ? {} : { customError: true }, message);\n }\n\n validate(): boolean {\n const isValid = typeof this.#pciValidity === 'boolean' ? this.#pciValidity : this.#hasNonEmptyResponse();\n this.#setInteractionValidity(isValid, this.#pciCustomValidityMessage);\n return isValid;\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 #unescapeHtml(str: string): string {\n if (!str) return str;\n\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(///g, '/')\n .replace(/`/g, '`')\n .replace(/=/g, '=');\n }\n\n /**\n * Unescape HTML entities in all values of an object\n */\n #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 if (this._iframeObjectUrl) {\n URL.revokeObjectURL(this._iframeObjectUrl);\n this._iframeObjectUrl = null;\n }\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 #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 case 'console':\n this.dispatchEvent(\n new CustomEvent('qti-pci-console', {\n detail: {\n level: data.level,\n args: data.args\n },\n bubbles: true\n })\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 const pciValid = typeof data?.params?.valid === 'boolean' ? (data.params.valid as boolean) : null;\n const pciCustomValidity =\n typeof data?.params?.customValidity === 'string' ? (data.params.customValidity as string) : null;\n if (pciValid !== null) {\n this.#pciValidity = pciValid;\n if (pciValid && pciCustomValidity === null) {\n this.#pciCustomValidityMessage = '';\n }\n }\n if (pciCustomValidity !== null) {\n this.#pciCustomValidityMessage = pciCustomValidity;\n }\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 if (this._iframeObjectUrl) {\n URL.revokeObjectURL(this._iframeObjectUrl);\n this._iframeObjectUrl = null;\n }\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 if (this._iframeObjectUrl) {\n URL.revokeObjectURL(this._iframeObjectUrl);\n this._iframeObjectUrl = null;\n }\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 // Prefer a same-origin blob URL to avoid postMessage target-origin mismatches (e.g. in Storybook).\n try {\n const blob = new Blob([iframeContent], { type: 'text/html' });\n this._iframeObjectUrl = URL.createObjectURL(blob);\n this.iframe.src = this._iframeObjectUrl;\n } catch {\n const encodedContent = encodeURIComponent(iframeContent);\n this.iframe.src = `data:text/html;charset=utf-8,${encodedContent}`;\n }\n\n // Append iframe to component\n this.appendChild(this.iframe);\n }\n\n /**\n * IFRAME MODE: Send initialization data to iframe\n */\n #sendIframeInitData() {\n // Once iframe is loaded, send initialization data\n const properties = this.#addHyphenatedKeys(\n this.#toNestedProperties(this.#unescapeDataAttributes({ ...this.dataset }))\n );\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 contextVariables: this.getContextVariables(),\n templateVariables: this.getTemplateVariables(),\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 #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, stylesheets, and properties to iframe\n */\n #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\n const stylesheets = Array.from(this.querySelectorAll('qti-stylesheet'));\n if (stylesheets.length) {\n const stylesheetsHtml = stylesheets.map(sheet => sheet.outerHTML).join('\\n');\n this.sendMessageToIframe('setStylesheets', stylesheetsHtml);\n }\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 #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 this.#pciValidity = null;\n this.#pciCustomValidityMessage = '';\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 const iframeBaseUrl = this.dataset.baseUrl\n ? this.dataset.baseUrl.startsWith('/')\n ? `${window.location.origin}${this.dataset.baseUrl}`\n : this.dataset.baseUrl\n : '';\n const forwardConsole = this.dataset.forwardConsole === 'true';\n const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';\n const defaultComponentsCdnUrl = isLocalhost\n ? `${window.location.origin}/cdn/index.js`\n : 'https://unpkg.com/@citolab/qti-components/cdn';\n const defaultComponentsCssUrl = isLocalhost\n ? `${window.location.origin}/dist/item.css`\n : 'https://unpkg.com/@citolab/qti-components@latest/dist/item.css';\n const componentsCdnUrl = this.dataset.componentsCdnUrl || defaultComponentsCdnUrl;\n const componentsCssUrl = this.dataset.componentsCssUrl || defaultComponentsCssUrl;\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\n return /* html */ `<!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 <script type=\"module\">\n import '${componentsCdnUrl}';\n </script>\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 <link href=\"${componentsCssUrl}\" rel=\"stylesheet\" />\n <script src=\"${this.requireJsUrl}\"></script>\n <script>\n const forwardConsole = ${forwardConsole ? 'true' : 'false'};\n if (forwardConsole) {\n const originalLog = console.log.bind(console);\n const originalError = console.error.bind(console);\n const stringifyArgs = args =>\n args.map(arg => {\n if (typeof arg === 'string') return arg;\n try {\n return JSON.stringify(arg);\n } catch (e) {\n return String(arg);\n }\n });\n console.log = (...args) => {\n originalLog(...args);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: (window.PCIManager && window.PCIManager.responseIdentifier) || null,\n method: 'console',\n level: 'log',\n args: stringifyArgs(args)\n },\n '*'\n );\n };\n console.error = (...args) => {\n originalError(...args);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: (window.PCIManager && window.PCIManager.responseIdentifier) || null,\n method: 'console',\n level: 'error',\n args: stringifyArgs(args)\n },\n '*'\n );\n };\n }\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: '${iframeBaseUrl}',\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 // Notify parent window about the error\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: (window.PCIManager && window.PCIManager.responseIdentifier) || null,\n method: 'error',\n params: {\n message: 'RequireJS ' + err.requireType + ' error for modules: ' + err.requireModules,\n details: {\n type: err.requireType,\n modules: err.requireModules,\n error: err.toString()\n }\n }\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 pendingStylesheets: null,\n stylesheetKeys: {},\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 if (this.pendingStylesheets !== null) {\n this.setStylesheets(this.pendingStylesheets);\n this.pendingStylesheets = 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 this.container.addEventListener(\n 'qti-interaction-changed',\n function (evt) {\n try {\n self.interactionChangedViaEvent = true;\n const value = evt && evt.detail ? evt.detail.value : undefined;\n if (value !== undefined) {\n const validFromEvent =\n evt && evt.detail && typeof evt.detail.valid === 'boolean' ? evt.detail.valid : undefined;\n let valid = validFromEvent;\n if (valid === undefined && self.pciInstance && typeof self.pciInstance.checkValidity === 'function') {\n try {\n valid = self.pciInstance.checkValidity();\n } catch (e) {\n // Keep undefined on PCI validity read errors.\n }\n }\n const customValidityFromEvent =\n evt && evt.detail && typeof evt.detail.customValidity === 'string'\n ? evt.detail.customValidity\n : undefined;\n let customValidity = customValidityFromEvent;\n if (\n customValidity === undefined &&\n self.pciInstance &&\n typeof self.pciInstance.getCustomValidity === 'function'\n ) {\n try {\n customValidity = self.pciInstance.getCustomValidity();\n } catch (e) {\n // Keep undefined on PCI custom validity read errors.\n }\n }\n const state =\n self.pciInstance && typeof self.pciInstance.getState === 'function'\n ? self.pciInstance.getState()\n : null;\n self.notifyInteractionChanged(value, state, valid, customValidity);\n }\n } catch (e) {\n // ignore bridge errors, polling fallback may still work\n }\n },\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 ensureDirectoryBasePath(basePath) {\n if (!basePath) return basePath;\n if (basePath.endsWith('/')) return basePath;\n return basePath + '/';\n }\n\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,\n module.fallbackPath,\n config.baseUrl\n );\n window.requirePaths[module.id] = newPath.concat(currentPaths)\n .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 ondone: (pciInstance, response, state, status) => {\n const valid =\n this.pciInstance && typeof this.pciInstance.checkValidity === 'function'\n ? this.pciInstance.checkValidity()\n : undefined;\n const customValidity =\n this.pciInstance && typeof this.pciInstance.getCustomValidity === 'function'\n ? this.pciInstance.getCustomValidity()\n : undefined;\n this.notifyInteractionChanged(\n response,\n typeof state === 'string' ? state : null,\n valid,\n customValidity\n );\n },\n responseIdentifier: config.responseIdentifier,\n boundTo: config.boundTo\n };\n\n if (pciInstance.getInstance) {\n const dom = this.markupEl || this.container;\n // Round-trip support for object states (stored as a prefixed JSON string by the host).\n // For strict string-based PCIs we pass the original string through unchanged.\n let restoredState = config.state;\n if (typeof restoredState === 'string' && restoredState.indexOf('__qti_json__::') === 0) {\n try {\n restoredState = JSON.parse(restoredState.substring('__qti_json__::'.length));\n } catch (e) {\n // If parsing fails, fall back to the raw string.\n restoredState = config.state;\n }\n }\n pciInstance.getInstance(dom, pciConfig, restoredState || undefined);\n } else {\n this.notifyError('Loaded PCI module has no getInstance().');\n }\n },\n notifyReady: () => {\n PCIManager.notifyReady();\n }\n };\n });\n\n function getResolvablePathString(path, basePath) {\n path = path.replace(/\\\\.js$/, '');\n if (/^[a-z][a-z0-9+.-]*:/i.test(path) || !basePath) {\n return path;\n }\n\n if (path.startsWith('/') && !path.startsWith('//')) {\n path = path.slice(1);\n }\n\n try {\n const resolved = new URL(path, ensureDirectoryBasePath(basePath)).toString();\n return resolved.replace(/\\\\.js$/, '');\n } catch (error) {\n return removeDoubleSlashes(ensureDirectoryBasePath(basePath) + path);\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], () => {}, 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 notifyReady: function () {\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: this.responseIdentifier,\n method: 'iframeReady'\n },\n '*'\n );\n },\n\n notifyInteractionChanged: function (response, state, valid, customValidity) {\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: this.responseIdentifier,\n method: 'interactionChanged',\n params: {\n value: response,\n state: state,\n valid: typeof valid === 'boolean' ? valid : undefined,\n customValidity: typeof customValidity === 'string' ? customValidity : undefined\n }\n },\n '*'\n );\n },\n\n notifyError: function (message) {\n console.error('PCI Error:', message);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: this.responseIdentifier,\n method: 'error',\n params: { message: message }\n },\n '*'\n );\n },\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 minifyCss: function (cssContent) {\n return cssContent\n .replace(/\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\//g, '')\n .replace(/\\\\s+/g, ' ')\n .replace(/\\\\s*([{}:;])\\\\s*/g, '$1')\n .trim();\n },\n\n setStylesheets: function (stylesheetsHtml) {\n if (!stylesheetsHtml) return;\n if (!this.container) {\n this.container = document.getElementById('pci-container');\n }\n const target = this.container || document.body;\n if (!target) return;\n target.insertAdjacentHTML('afterbegin', stylesheetsHtml);\n },\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 // Set up message listener for communication with parent\n let expectedParentOrigin = null;\n window.addEventListener('message', function (event) {\n const { data } = event;\n\n // Ensure the message is from our parent\n if (event.source !== window.parent || !data || data.source !== 'qti-portable-custom-interaction') {\n return;\n }\n if (expectedParentOrigin === null) {\n expectedParentOrigin = event.origin;\n } else if (event.origin !== expectedParentOrigin) {\n return;\n }\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 'setStylesheets':\n PCIManager.setStylesheets(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 window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'getContentResponse',\n messageId: messageId,\n content: (document.documentElement ? document.documentElement.outerHTML : '') + '\\\\n' + shadowHtml\n },\n '*'\n );\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 const target = (el && el.closest && el.closest('.hitbox')) || document.querySelector('.hitbox') || el;\n if (target) {\n const evt = new MouseEvent('click', {\n bubbles: true,\n clientX: x,\n clientY: y,\n screenX: x,\n screenY: y,\n view: window\n });\n target.dispatchEvent(evt);\n }\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'clickResponse',\n messageId: messageId\n },\n '*'\n );\n break;\n }\n\n case 'getBoundingRect': {\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 const rect = el && typeof el.getBoundingClientRect === 'function' ? el.getBoundingClientRect() : null;\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'getBoundingRectResponse',\n messageId: messageId,\n rect: rect\n ? {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height\n }\n : null\n },\n '*'\n );\n break;\n }\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 const success = !!el;\n if (el && typeof el.click === 'function') el.click();\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'clickSelectorResponse',\n messageId: messageId,\n success: success\n },\n '*'\n );\n break;\n }\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 const success = !!target;\n if (target && typeof target.click === 'function') target.click();\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'clickTextResponse',\n messageId: messageId,\n success: success\n },\n '*'\n );\n break;\n }\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 }\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'setValueResponse',\n messageId: messageId,\n success: success\n },\n '*'\n );\n break;\n }\n\n case 'console':\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'console',\n level: data.level,\n args: data.args\n },\n '*'\n );\n break;\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 resizeTimeout = setTimeout(() => {\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'resize',\n height: newHeight,\n width: container.scrollWidth\n },\n '*'\n );\n }, 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 const valid =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.checkValidity === 'function'\n ? PCIManager.pciInstance.checkValidity()\n : undefined;\n const customValidity =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.getCustomValidity === 'function'\n ? PCIManager.pciInstance.getCustomValidity()\n : undefined;\n if (response === undefined) {\n // Don't emit an initial empty on load; only emit a clear if we previously had a value\n if (!PCIManager.hadResponse) return;\n PCIManager.hadResponse = false;\n PCIManager.lastResponseStr = null;\n const state =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.getState === 'function'\n ? PCIManager.pciInstance.getState()\n : null;\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'interactionChanged',\n params: { value: null, state: state, valid: valid, customValidity: customValidity }\n },\n '*'\n );\n return;\n }\n\n const responseStr = JSON.stringify(response);\n\n if (responseStr !== PCIManager.lastResponseStr) {\n PCIManager.lastResponseStr = responseStr;\n PCIManager.hadResponse = true;\n const state =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.getState === 'function'\n ? PCIManager.pciInstance.getState()\n : null;\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'interactionChanged',\n params: { value: response, state: state, valid: valid, customValidity: customValidity }\n },\n '*'\n );\n }\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 applyCorrectResponse = () => {\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 };\n\n if (this._iframeLoaded) {\n applyCorrectResponse();\n } else {\n this.addEventListener('qti-portable-custom-interaction-loaded', applyCorrectResponse, { once: true });\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 #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 { css } from 'lit';\n\nexport default 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","import { LitElement, html } from 'lit';\n\nimport styles from './qti-position-object-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\n\nexport class QtiPositionObjectInteraction extends LitElement {\n static override styles: CSSResultGroup = styles;\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: inline-block;\n position: relative;\n }\n`;\n","import { LitElement, html } from 'lit';\n\nimport styles from './qti-position-object-stage.styles';\n\nimport type { CSSResultGroup, PropertyValueMap } from 'lit';\nexport class QtiPositionObjectStage extends LitElement {\n static override styles: CSSResultGroup = styles;\n\n choiceOrdering: boolean;\n startX: any;\n startY: any;\n dragElement: any;\n\n override render() {\n return html`<slot></slot>`;\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 } from 'lit';\n\nexport default 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","import { 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';\nimport { positionShapes } from '@qti-components/interactions-core/internal/hotspots/hotspot';\n\nimport styles from './qti-select-point-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nimport type { QtiAreaMapEntry, QtiAreaMapping } from '@qti-components/base';\nexport class QtiSelectPointInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\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 #imgElement: HTMLImageElement | null = null;\n\n #scaleX = 1;\n #scaleY = 1;\n #imageWidthOriginal = 0;\n #imageHeightOriginal = 0;\n\n // Extracted click handler method\n #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 #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 #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 #value = 0;\n #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 #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 #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 #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 #startDrag(pageX: number) {\n this.#onDrag(pageX);\n }\n\n #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 #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 #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 } from 'lit';\n\nexport default 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","import { html } from 'lit';\n\nimport { Interaction } from '@qti-components/base';\n\nimport styles from './qti-upload-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nexport class QtiUploadInteraction extends Interaction {\n static override styles: CSSResultGroup = styles;\n\n #file: File | null = null;\n #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 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 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 #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 { 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","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 #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 * Gets the bounding client rect for an element inside the iframe\n * @param selector The CSS selector string\n * @returns Promise that resolves with the rect or null\n */\n async iFrameGetBoundingClientRect(\n selector: string\n ): Promise<{ left: number; top: number; width: number; height: number } | null> {\n return new Promise(resolve => {\n const messageId = `get-bounding-rect-${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 === 'getBoundingRectResponse' &&\n data?.messageId === messageId\n ) {\n window.removeEventListener('message', messageHandler);\n resolve(data.rect ?? null);\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n this.sendMessageToIframe('getBoundingRect', { selector, messageId });\n\n setTimeout(() => {\n window.removeEventListener('message', messageHandler);\n resolve(null);\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"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["i","i","i","i","i","i","i","i","i","i","WeakMap","r","e","subscriber","subscriberState","Subscriber","Observable","value","v","p","styles","window","e","i","x","identifier","i","c","c","e","iframe","i","o","SlottedBase","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","SlottedBase","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","styles","o","i","SlottedBase","e","v","x","m","o","SlottedBase","i","v","e","v","n","i","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","v","x"]}
|