@citolab/qti-components 7.28.1 → 8.0.1

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.
Files changed (88) hide show
  1. package/cdn/index.global.js +1 -1
  2. package/cdn/index.js +6316 -2710
  3. package/dist/base.d.ts +100 -15
  4. package/dist/base.js +27 -6
  5. package/dist/chunk-3AJOQCDU.js +11 -0
  6. package/dist/chunk-3AJOQCDU.js.map +1 -0
  7. package/dist/chunk-64XSIBGO.js +241 -0
  8. package/dist/chunk-64XSIBGO.js.map +1 -0
  9. package/dist/chunk-7HC5SMCU.js +102 -0
  10. package/dist/chunk-7HC5SMCU.js.map +1 -0
  11. package/dist/{chunk-SP6S2WMG.js → chunk-7V4HJFHW.js} +3 -3
  12. package/dist/{chunk-SP6S2WMG.js.map → chunk-7V4HJFHW.js.map} +1 -1
  13. package/dist/chunk-CAO4JRLY.js +11 -0
  14. package/dist/chunk-CAO4JRLY.js.map +1 -0
  15. package/dist/{chunk-MPC7LIPC.js → chunk-F4BNJWYN.js} +4264 -3647
  16. package/dist/chunk-F4BNJWYN.js.map +1 -0
  17. package/dist/{chunk-3XV26R5M.js → chunk-H3J7LFRO.js} +829 -1005
  18. package/dist/chunk-H3J7LFRO.js.map +1 -0
  19. package/dist/{chunk-3WBG257S.js → chunk-IJD53WY6.js} +96 -74
  20. package/dist/chunk-IJD53WY6.js.map +1 -0
  21. package/dist/chunk-LVBIQDPM.js +1374 -0
  22. package/dist/chunk-LVBIQDPM.js.map +1 -0
  23. package/dist/{chunk-REI3AMCZ.js → chunk-NA2N2WSG.js} +1303 -1193
  24. package/dist/chunk-NA2N2WSG.js.map +1 -0
  25. package/dist/chunk-QECOPVPO.js +294 -0
  26. package/dist/chunk-QECOPVPO.js.map +1 -0
  27. package/dist/{chunk-HFCZFWSH.js → chunk-RXGDQDOV.js} +1993 -1764
  28. package/dist/chunk-RXGDQDOV.js.map +1 -0
  29. package/dist/chunk-V5G7X53Y.js +11 -0
  30. package/dist/chunk-V5G7X53Y.js.map +1 -0
  31. package/dist/{chunk-WDO2TRFM.js → chunk-WVVMNF74.js} +851 -925
  32. package/dist/chunk-WVVMNF74.js.map +1 -0
  33. package/dist/{chunk-FLJAKWXL.js → chunk-X3E5HXG2.js} +2 -2
  34. package/dist/chunk-XU7HNT4F.js +1608 -0
  35. package/dist/chunk-XU7HNT4F.js.map +1 -0
  36. package/dist/{computed-item.context-DfsW_96S.d.ts → computed-item.types.d-BKZdSLLJ.d.ts} +2 -5
  37. package/dist/{computed.context-DHbxad0N.d.ts → computed.types.d-rKLSPvVG.d.ts} +2 -5
  38. package/dist/config.context.d-BvU9r-Mg.d.ts +91 -0
  39. package/dist/corrections.d.ts +432 -0
  40. package/dist/corrections.js +84 -0
  41. package/dist/elements.d.ts +8 -14
  42. package/dist/elements.js +6 -5
  43. package/dist/index.d.ts +51 -16
  44. package/dist/index.js +193 -76
  45. package/dist/interaction.d-D4MstYRz.d.ts +115 -0
  46. package/dist/interaction.interface.d-CvjHM2bi.d.ts +46 -0
  47. package/dist/interactions.d.ts +1206 -552
  48. package/dist/interactions.js +19 -15
  49. package/dist/item.css +4228 -1656
  50. package/dist/item.d.ts +13 -55
  51. package/dist/item.js +6 -11
  52. package/dist/{variables-CMYcDbyW.d.ts → item.types.d-QU7LljEK.d.ts} +13 -1
  53. package/dist/loader.d.ts +4 -4
  54. package/dist/loader.js +2 -3
  55. package/dist/processing.d.ts +6 -7
  56. package/dist/processing.js +2 -3
  57. package/dist/qti-components-jsx.d.ts +5348 -2709
  58. package/dist/qti-components-jsx.js +1 -0
  59. package/dist/qti-condition-expression.d-aMvBvpc6.d.ts +8 -0
  60. package/dist/{qti-condition-expression-Dam-RER6.d.ts → qti-expression.d-BietT_8b.d.ts} +14 -9
  61. package/dist/{qti-feedback-ChmXhZuf.d.ts → qti-feedback.d-DZbad0RN.d.ts} +1 -1
  62. package/dist/{qti-transform-test-DoZaWItm.d.ts → qti-transform-test.d-BL7GGFJj.d.ts} +2 -2
  63. package/dist/response.d-_8y4kjGP.d.ts +106 -0
  64. package/dist/test.d.ts +199 -39
  65. package/dist/test.js +34 -11
  66. package/dist/transformers.d.ts +1 -1
  67. package/dist/transformers.js +1 -2
  68. package/package.json +24 -17
  69. package/custom-elements.json +0 -43251
  70. package/dist/chunk-3WBG257S.js.map +0 -1
  71. package/dist/chunk-3XV26R5M.js.map +0 -1
  72. package/dist/chunk-AQ5RJFM6.js +0 -3673
  73. package/dist/chunk-AQ5RJFM6.js.map +0 -1
  74. package/dist/chunk-HFCZFWSH.js.map +0 -1
  75. package/dist/chunk-MPC7LIPC.js.map +0 -1
  76. package/dist/chunk-QXBXORM3.js +0 -27
  77. package/dist/chunk-REI3AMCZ.js.map +0 -1
  78. package/dist/chunk-RLTYVS2I.js +0 -530
  79. package/dist/chunk-RLTYVS2I.js.map +0 -1
  80. package/dist/chunk-WDO2TRFM.js.map +0 -1
  81. package/dist/config.context-BjZ2bZSY.d.ts +0 -42
  82. package/dist/interaction-Bgzlw7Iu.d.ts +0 -110
  83. package/dist/item.context-CkUeDcaO.d.ts +0 -15
  84. package/dist/test.context-CByZZjkR.d.ts +0 -15
  85. /package/dist/{chunk-FLJAKWXL.js.map → chunk-X3E5HXG2.js.map} +0 -0
  86. /package/dist/{chunk-QXBXORM3.js.map → corrections.js.map} +0 -0
  87. /package/dist/{qti-rule-base-ajOnfGXY.d.ts → qti-rule-base.d-ajOnfGXY.d.ts} +0 -0
  88. /package/dist/{qti.context-CejJMlfZ.d.ts → qti.context.d-CejJMlfZ.d.ts} +0 -0
@@ -1,501 +1,269 @@
1
1
  import * as lit from 'lit';
2
- import { CSSResultGroup, LitElement, PropertyValues, PropertyValueMap } from 'lit';
3
- import { a as Interaction, I as IInteraction, C as Correctness } from './interaction-Bgzlw7Iu.js';
4
- import { C as ConfigContext } from './config.context-BjZ2bZSY.js';
5
- import { a as Cardinality, B as BaseType } from './variables-CMYcDbyW.js';
6
- import { I as ItemContext } from './item.context-CkUeDcaO.js';
7
- import { Q as QtiContext } from './qti.context-CejJMlfZ.js';
2
+ import { CSSResultGroup, LitElement, PropertyValueMap, PropertyValues } from 'lit';
3
+ import { I as Interaction } from './interaction.d-D4MstYRz.js';
8
4
  import * as lit_directives_ref_js from 'lit/directives/ref.js';
5
+ import { Q as QtiAreaMapEntry, B as BaseType, a as Cardinality, I as ItemContext } from './item.types.d-QU7LljEK.js';
6
+ import * as _qti_components_portable_custom_interaction_qti_portable_custom_test_interaction_js from '@qti-components/portable-custom-interaction/qti-portable-custom-test-interaction.js';
7
+ import { Q as QtiContext } from './qti.context.d-CejJMlfZ.js';
8
+ import * as _qti_components_interactions_core_mixins_drag_drop_observables from '@qti-components/interactions-core/mixins/drag-drop-observables';
9
+ import { QtiSimpleAssociableChoice as QtiSimpleAssociableChoice$1 } from '@qti-components/interactions-core/elements/qti-simple-associable-choice';
10
+ export * from '@qti-components/interactions-core/elements/qti-simple-associable-choice';
11
+ import * as _qti_components_interactions_core_mixins_menu_auto_size from '@qti-components/interactions-core/mixins/menu-auto-size';
12
+ import { C as ConfigContext } from './config.context.d-BvU9r-Mg.js';
13
+ import * as _qti_components_interactions_core_mixins_choices_choices_mixin from '@qti-components/interactions-core/mixins/choices/choices.mixin';
14
+ import { Choice, ChoicesInterface as ChoicesInterface$1 } from '@qti-components/interactions-core/mixins/choices/choices.mixin';
15
+ import { V as ValidatableInteraction } from './interaction.interface.d-CvjHM2bi.js';
16
+ export * from '@qti-components/interactions-core/elements/qti-gap-img';
17
+ export * from '@qti-components/interactions-core/elements/qti-gap-text';
18
+ export * from '@qti-components/interactions-core/elements/qti-gap';
19
+ export * from '@qti-components/interactions-core/elements/qti-inline-choice';
20
+ export * from '@qti-components/interactions-core/elements/qti-hottext';
21
+ export * from '@qti-components/interactions-core/elements/qti-simple-choice';
22
+ export * from '@qti-components/interactions-core/elements/qti-hotspot-choice';
23
+ export * from '@qti-components/interactions-core/elements/qti-associable-hotspot';
24
+ export * from '@qti-components/interactions-core/elements/qti-prompt';
9
25
 
10
26
  /**
11
- * Collision detection algorithms for drag and drop interactions
12
- * Based on dnd-kit collision detection strategies
13
- */
14
- type CollisionDetectionAlgorithm = 'pointerWithin' | 'rectangleIntersection' | 'closestCenter' | 'closestCorners' | 'closestCornersWithInventoryPriority';
15
-
16
- type DragDropCore = Interaction & {
17
- trackedDraggables: HTMLElement[];
18
- trackedDroppables: HTMLElement[];
19
- trackedDragContainers: HTMLElement[];
20
- allDropzones: HTMLElement[];
21
- dragState: DragState;
22
- collisionDetectionAlgorithm: CollisionDetectionAlgorithm;
23
- get response(): string | string[] | null;
24
- set response(value: string | string[] | null);
25
- saveResponse(value?: string | string[]): void;
26
- validate(): boolean;
27
- reportValidity(): boolean;
28
- cacheInteractiveElements(): void;
29
- resetDragState(): void;
30
- afterCache(): void;
31
- allowDrop(draggable: HTMLElement, droppable: HTMLElement): boolean;
32
- handleDrop(draggable: HTMLElement, droppable: HTMLElement): void;
33
- handleInvalidDrop(dragSource: HTMLElement | null): void;
34
- initiateDrag(dragElement: HTMLElement, startX: number, startY: number, inputType: 'mouse' | 'touch', eventSource?: 'pointer' | 'mouse' | 'touch', pointerId?: number, startedFromTrustedEvent?: boolean): void;
35
- createDragClone(element: HTMLElement, rect: DOMRect): HTMLElement;
36
- updateClonePosition(clientX: number, clientY: number): void;
37
- activateAllDroppables(): void;
38
- setupMoveObservables(inputType: 'mouse' | 'touch', eventSource?: 'pointer' | 'mouse' | 'touch'): void;
39
- };
40
- interface DragState {
41
- dragging: boolean;
42
- dragSource: HTMLElement | null;
43
- dragClone: HTMLElement | null;
44
- startOffset: {
45
- x: number;
46
- y: number;
47
- };
48
- currentTarget: HTMLElement | null;
49
- sourceDroppable: HTMLElement | null;
50
- inputType: 'mouse' | 'touch' | null;
51
- pointerId?: number;
52
- startedFromTrustedEvent?: boolean;
53
- initialCoordinates?: {
54
- x: number;
55
- y: number;
56
- };
57
- activationTimeout?: number;
58
- touchCleanup?: () => void;
59
- lastTargetChangeTime?: number;
60
- }
61
-
62
- type DragDropSlotted = DragDropCore & {
63
- minAssociations: number;
64
- maxAssociations: number;
65
- disableAnimations: boolean;
66
- enableFlipAnimations: boolean;
67
- autoSizeDropzones: boolean;
68
- validate(): boolean;
69
- reportValidity(): boolean;
70
- reset(): void;
71
- saveResponse(value?: string | string[]): void;
72
- shouldTreatBlockedMaxAsInvalid(): boolean;
73
- shouldReturnToInventoryOnInventoryDrop(): boolean;
74
- };
75
-
76
- /**
77
- * Shared utilities for sortable drag-and-drop behavior.
78
- * Used by both DragDropSortableMixin (standalone) and SlotSortableEnhancerMixin (composition).
79
- */
80
-
81
- /**
82
- * Configuration for drop placeholder styling
83
- */
84
- interface PlaceholderConfig {
85
- borderStyle?: string;
86
- borderColor?: string;
87
- background?: string;
88
- transitionDuration?: number;
89
- }
90
-
91
- type DragDropSlottedSortable = DragDropSlotted & {
92
- allowReorder: boolean;
93
- readonly isDraggingFromSlot: boolean;
94
- sortablePlaceholderConfig: PlaceholderConfig;
95
- };
96
-
97
- declare const QtiAssociateInteraction_base: (abstract new (...args: any[]) => DragDropSlottedSortable) & (abstract new (...args: any[]) => DragDropSlotted) & typeof Interaction;
98
- declare class QtiAssociateInteraction extends QtiAssociateInteraction_base {
99
- static styles: CSSResultGroup;
100
- protected _childrenMap: Element[];
101
- protected _registerChoiceHandler: (event: CustomEvent) => void;
102
- constructor();
103
- protected _registerChoice(event: CustomEvent): void;
104
- protected getResponse(): string[];
105
- getValue(val: string[]): string[];
106
- render(): lit.TemplateResult<1>;
107
- protected updated(changedProperties: Map<string, unknown>): void;
108
- disconnectedCallback(): void;
109
- }
110
- declare global {
111
- interface HTMLElementTagNameMap {
112
- 'qti-associate-interaction': QtiAssociateInteraction;
113
- }
114
- }
115
-
116
- interface ChoiceInterface {
117
- identifier: string;
118
- disabled: boolean;
119
- readonly: boolean;
120
- }
121
- /**
122
- * A mixin that adds choice functionality to a LitElement-based class.
123
- * It dispatches events with a custom `type` and handles selection logic.
27
+ * Upload interaction: candidates attach a file as their response.
124
28
  *
125
- * @param Base - The base class to extend.
126
- * @param type - The type of the choice, used in event names.
127
- * @returns A new class extending the base class with choice functionality.
29
+ * @slot prompt - The prompt shown above the file input.
128
30
  */
129
- interface ActiveElementMixinInterface {
130
- identifier: string;
131
- tabIndex: number;
132
- disabled: boolean;
133
- readonly: boolean;
134
- internals: ElementInternals;
135
- }
136
-
137
- type Choice = HTMLElement & ChoiceInterface & {
138
- internals: ElementInternals;
139
- };
140
- interface ChoicesInterface extends IInteraction {
141
- minChoices: number;
142
- maxChoices: number;
143
- value: string | null;
144
- response: string | string[] | null;
145
- validate(): boolean;
146
- reportValidity(): boolean;
147
- }
148
-
149
- type Orientation = 'horizontal' | 'vertical' | undefined;
150
- declare const QtiChoiceInteraction_base: (abstract new (...args: any[]) => {}) & (abstract new (...args: any[]) => ChoicesInterface) & typeof Interaction;
151
- declare class QtiChoiceInteraction extends QtiChoiceInteraction_base implements ChoicesInterface {
31
+ declare class QtiUploadInteraction extends Interaction {
152
32
  #private;
153
33
  static styles: CSSResultGroup;
154
- /** @deprecated, use 'qti-orientation-horizontal' or 'qti-orientation-vertical' instead */
155
- orientation: Orientation;
34
+ reset(): void;
35
+ validate(): boolean;
36
+ get response(): string | null;
37
+ set response(base64: string | null);
38
+ static get properties(): {
39
+ [key: string]: lit.PropertyDeclaration<unknown, unknown>;
40
+ };
156
41
  render(): lit.TemplateResult<1>;
157
42
  }
158
43
  declare global {
159
44
  interface HTMLElementTagNameMap {
160
- 'qti-choice-interaction': QtiChoiceInteraction;
45
+ 'qti-upload-interaction': QtiUploadInteraction;
161
46
  }
162
47
  }
163
48
 
164
49
  /**
165
- * QTI Custom Interaction component for legacy CES-based interactions.
50
+ * Text-entry interaction: single-line inline text input.
166
51
  *
167
- * This component implements support for custom interactions originally built for the CES
168
- * (Custom Element Standard) player - the predecessor to FACET and the Trifork QTI Player.
169
- *
170
- * @remarks
171
- * The interaction workflow:
172
- * 1. Fetch the CI manifest (JSON file with script, style, media references)
173
- * 2. Check if bootstrap.js uses the CES API
174
- * 3. If CES is used:
175
- * - Fetch index.html from main window (where service worker/fetch works)
176
- * - Inject registerCES proxy script for postMessage-based communication
177
- * - Create blob URL and pass it to ciBootstrap
178
- * 4. Create pciContainer iframe with style and bootstrap script
179
- * 5. Handle postMessage events for getMedia, getResponse, setResponse, getBlobUrl
52
+ * @customElement qti-text-entry-interaction
180
53
  *
181
- * The postMessage bridge is necessary because:
182
- * - Iframes created via document.write() have about:blank origin
183
- * - They cannot access the parent's global CES object (cross-origin)
184
- * - Service workers don't control about:blank documents
54
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
55
+ * @attr {number} expected-length - Hint at the expected answer length; drives the rendered
56
+ * field width and the input's `maxlength`.
57
+ * @attr {string} pattern-mask - Regular expression the value must match to be valid.
58
+ * @attr {string} placeholder-text - Placeholder shown while the field is empty.
59
+ * @attr {string} data-patternmask-message - Custom validation message shown when
60
+ * `pattern-mask` fails. Part of the QTI shared interaction vocabulary.
61
+ * @attr {number} [base=10] - Not implemented. Numeric base used when recording the value.
62
+ * @attr {string} string-identifier - Not implemented. Identifier of a second, string-typed
63
+ * response variable that also receives the raw entry.
64
+ * @attr {string} format - Not implemented. QTI types this as a bare normalized string here rather
65
+ * than as the `plain | preformatted | xhtml` vocabulary it defines for extended-text, and a
66
+ * single-line input has no formatting to render: it can show neither preserved line breaks nor
67
+ * markup. The field is always plain text, so this is not planned either.
185
68
  *
186
- * Messages are sent to all parent windows to support embedding scenarios like Storybook
187
- * where window.top might not be the actual host application.
69
+ * @csspart answer - The answer-key line, revealed above the field when the correct response is shown.
70
+ * @csspart input - The text input element.
71
+ * @csspart message - The validation message, hidden until `reportValidity` shows it.
188
72
  */
189
- declare class QtiCustomInteraction extends Interaction {
190
- #private;
191
- static styles: CSSResultGroup;
192
- constructor();
193
- data: string;
194
- baseItemUrl: string;
195
- baseRefUrl: string;
196
- id: string;
197
- private _errorMessage;
198
- manifest: {
199
- script: string[];
200
- style: string[];
201
- media: string[];
202
- };
203
- connectedCallback(): void;
204
- /**
205
- * Sets up the CES custom interaction by creating the iframe structure and
206
- * handling the CES API communication via postMessage.
207
- *
208
- * For interactions that use CES, this method:
209
- * 1. Fetches the original bootstrap.js and checks if it uses CES
210
- * 2. If CES is used, fetches index.html and injects the registerCES proxy
211
- * 3. Creates a blob URL for the modified HTML (stored in _contentBlobUrl)
212
- * 4. Replaces bootstrap.js with ciBootstrap that loads the blob URL
213
- * 5. Sets up postMessage listeners for CES API calls
214
- */
215
- setupCES(): Promise<void>;
216
- handlePostMessage(event: MessageEvent): void;
217
- validate(): boolean;
218
- get response(): string | string[] | null;
219
- set response(val: string | string[] | null);
220
- disconnectedCallback(): void;
221
- render(): lit.TemplateResult<1>;
222
- }
223
- declare global {
224
- interface HTMLElementTagNameMap {
225
- 'qti-custom-interaction': QtiCustomInteraction;
226
- }
227
- }
228
-
229
- declare class QtiEndAttemptInteraction extends LitElement {
230
- static styles: CSSResultGroup;
231
- responseIdentifier: string;
232
- disabled: boolean;
233
- /** 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) */
234
- countAttempt: 'true' | 'false' | null;
235
- title: string;
236
- render(): lit.TemplateResult<1>;
237
- endAttempt(_: Event): void;
238
- }
239
- declare global {
240
- interface HTMLElementTagNameMap {
241
- 'qti-end-attempt-interaction': QtiEndAttemptInteraction;
242
- }
243
- }
244
-
245
- declare class QtiExtendedTextInteraction extends Interaction {
73
+ declare class QtiTextEntryInteraction extends Interaction {
246
74
  static styles: CSSResultGroup;
247
- protected _rows: number;
248
- /** expected length is mapped to the property maxlength on the textarea */
75
+ inputRef: lit_directives_ref_js.Ref<HTMLInputElement>;
249
76
  expectedLength: number;
250
77
  patternMask: string;
251
- /** text appearing in the extended-text-interaction if it is empty */
252
78
  placeholderText: string;
253
79
  dataPatternmaskMessage: string;
254
- classNames: string;
255
- handleclassNamesChange(_: any, classes: string): void;
256
80
  response: string | null;
257
- protected _handleResponseChange: () => void;
81
+ private _input;
82
+ protected _handleValueChange: () => void;
258
83
  get value(): string | null;
259
84
  set value(val: string | null);
85
+ get isInline(): boolean;
260
86
  validate(): boolean;
261
- toggleCorrectResponse(): void;
262
- reportValidity(): boolean;
87
+ /** The answer-key line, revealed above the field when the correct response is shown. */
88
+ protected renderAnswer(): unknown;
89
+ /** The field itself. */
90
+ protected renderInput(): unknown;
91
+ /** Hidden until `Interaction.reportValidity` shows it. */
92
+ protected renderValidationMessage(): unknown;
263
93
  render(): lit.TemplateResult<1>;
264
94
  protected textChanged(event: Event): void;
265
- protected setEmptyAttribute(text: string): void;
95
+ reportValidity(): boolean;
96
+ reset(): void;
266
97
  }
267
98
  declare global {
268
99
  interface HTMLElementTagNameMap {
269
- 'qti-extended-text-interaction': QtiExtendedTextInteraction;
100
+ 'qti-text-entry-interaction': QtiTextEntryInteraction;
270
101
  }
271
102
  }
272
103
 
273
- declare const QtiGapMatchInteraction_base: (abstract new (...args: any[]) => DragDropSlottedSortable) & (abstract new (...args: any[]) => DragDropSlotted) & typeof Interaction;
274
- declare class QtiGapMatchInteraction extends QtiGapMatchInteraction_base {
104
+ /**
105
+ * Slider interaction: candidates pick a numeric value along a rail.
106
+ *
107
+ * @slot prompt - The prompt shown above the slider.
108
+ *
109
+ * @csspart slider - The slider root element.
110
+ * @csspart bounds - The min/max bounds label wrapper.
111
+ * @csspart ticks - The tick marks along the rail.
112
+ * @csspart rail - The rail element the knob slides along.
113
+ * @csspart knob - The draggable knob.
114
+ * @csspart value - The current value display (used twice in the layout).
115
+ * @csspart knob-correct - Ghost knob shown at the correct response position.
116
+ */
117
+ declare class QtiSliderInteraction extends Interaction {
275
118
  #private;
276
119
  static styles: CSSResultGroup;
120
+ private _rail;
121
+ min: number;
122
+ max: number;
123
+ step: number;
124
+ validate(): boolean;
125
+ connectedCallback(): void;
126
+ get response(): string;
127
+ set response(val: string | null);
128
+ /** Extension hook for optional content rendered on the slider rail. */
129
+ protected renderRailSupplement(): unknown;
277
130
  render(): lit.TemplateResult<1>;
278
- toggleCorrectResponse(show: boolean): void;
279
- toggleCandidateCorrection(show: boolean): void;
280
131
  }
281
132
  declare global {
282
133
  interface HTMLElementTagNameMap {
283
- 'qti-gap-match-interaction': QtiGapMatchInteraction;
134
+ 'qti-slider-interaction': QtiSliderInteraction;
284
135
  }
285
136
  }
286
137
 
287
- declare class QtiGraphicAssociateInteraction extends Interaction {
138
+ /**
139
+ * Select-point interaction: candidates place points onto a background image.
140
+ *
141
+ * @customElement qti-select-point-interaction
142
+ *
143
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable,
144
+ * which must have base-type `point`.
145
+ * @attr {number} [max-choices=0] - Maximum points the candidate may place; `0` means unlimited.
146
+ * @attr {number} [min-choices=0] - Minimum points for a valid response.
147
+ * @attr {string} area-mappings - Extension, not QTI. JSON array of
148
+ * `{shape, coords, mappedValue?, defaultValue?}` entries used when no
149
+ * `qti-response-declaration` supplies an `qti-area-mapping`.
150
+ *
151
+ * @slot prompt - The prompt shown above the image.
152
+ * @slot - Default slot for the base image.
153
+ *
154
+ * @csspart point - Each selected point marker.
155
+ * @cssprop --qti-select-point-icon - Marker mask image (SVG data URL). Should be a solid silhouette for color inheritance.
156
+ * @cssprop --qti-select-point-marker-size - Marker size.
157
+ * @cssprop --qti-select-point-marker-anchor - Vertical translate anchor (`-100%` for bottom tip, `-50%` for center).
158
+ * @cssprop --qti-select-point-marker-color - Marker color; defaults to currentColor so it can be inherited.
159
+ */
160
+ declare class QtiSelectPointInteraction extends Interaction {
288
161
  #private;
289
162
  static styles: CSSResultGroup;
290
- private _correctLines;
291
- private startCoord;
292
- private mouseCoord;
293
- grImage: any[];
294
- private _response;
295
- constructor();
296
- reset(): void;
297
- validate(): boolean;
298
- set response(val: string[]);
299
- get response(): string[];
300
- toggleInternalCorrectResponse(show: boolean): void;
163
+ maxChoices: number;
164
+ minChoices: number;
165
+ response: string[] | null;
166
+ /**
167
+ * Standalone area mapping as a JSON string. Mirrors the editor's
168
+ * `#syncAreaEntriesFromAttribute` codec — each entry has `{shape, coords, mappedValue?, defaultValue?}`
169
+ * and `shape` must be `'circle'` or `'rect'`. Used when no
170
+ * `qti-response-declaration` provides `areaMapping`.
171
+ *
172
+ * @example
173
+ * ```html
174
+ * <qti-select-point-interaction area-mappings='[{"shape":"circle","coords":"191,393,10","mappedValue":1}]'>
175
+ * ```
176
+ */
177
+ areaMappings: string | null;
178
+ private _areaEntries;
179
+ protected _handleAreaMappingsChange: () => void;
180
+ protected get _effectiveAreaEntries(): QtiAreaMapEntry[];
181
+ connectedCallback(): void;
182
+ get responsePoints(): {
183
+ x: number;
184
+ y: number;
185
+ }[];
186
+ /** Extension hook for additional part tokens on a rendered response point. */
187
+ protected pointPart(_point: string, _index: number): string;
188
+ /** Extension hook for optional layers rendered above the response points. */
189
+ protected renderSupplementalLayer(): unknown;
190
+ /** Positions overlay elements that carry `data-coord` and `data-shape`. */
191
+ protected positionOverlayElements(elements: Iterable<HTMLElement>): void;
301
192
  render(): lit.TemplateResult<1>;
193
+ validate(): boolean;
194
+ reportValidity(): boolean;
302
195
  firstUpdated(): void;
303
196
  disconnectedCallback(): void;
304
197
  }
305
198
  declare global {
306
199
  interface HTMLElementTagNameMap {
307
- 'qti-graphic-associate-interaction': QtiGraphicAssociateInteraction;
200
+ 'qti-select-point-interaction': QtiSelectPointInteraction;
308
201
  }
309
202
  }
310
203
 
311
- declare const QtiGraphicGapMatchInteraction_base: (abstract new (...args: any[]) => DragDropSlottedSortable) & (abstract new (...args: any[]) => DragDropSlotted) & typeof Interaction;
312
- declare class QtiGraphicGapMatchInteraction extends QtiGraphicGapMatchInteraction_base {
313
- #private;
204
+ /**
205
+ * Position-object interaction: candidates place draggable objects onto a stage image.
206
+ *
207
+ * @slot - Default slot for the object choices and stage.
208
+ */
209
+ declare class QtiPositionObjectInteraction extends LitElement {
314
210
  static styles: CSSResultGroup;
315
211
  render(): lit.TemplateResult<1>;
316
- shouldReturnToInventoryOnInventoryDrop(): boolean;
317
- connectedCallback(): void;
212
+ }
213
+
214
+ declare class QtiPositionObjectStage extends LitElement {
215
+ static styles: CSSResultGroup;
216
+ choiceOrdering: boolean;
217
+ startX: any;
218
+ startY: any;
219
+ dragElement: any;
220
+ render(): lit.TemplateResult<1>;
221
+ constructor();
222
+ dragElementHandler(event: MouseEvent): void;
223
+ firstUpdated(a: PropertyValueMap<any>): void;
224
+ removeMoveListener(): void;
318
225
  disconnectedCallback(): void;
319
226
  }
320
227
  declare global {
321
228
  interface HTMLElementTagNameMap {
322
- 'qti-graphic-gap-match-interaction': QtiGraphicGapMatchInteraction;
229
+ 'qti-position-object-stage': QtiPositionObjectStage;
323
230
  }
324
231
  }
325
232
 
326
- declare const QtiGraphicOrderInteraction_base: (abstract new (...args: any[]) => ChoicesInterface) & typeof Interaction;
327
- declare class QtiGraphicOrderInteraction extends QtiGraphicOrderInteraction_base {
328
- #private;
329
- static styles: CSSResultGroup;
330
- protected choiceOrdering: boolean;
331
- protected _choiceElements: Choice[];
332
- render(): lit.TemplateResult<1>;
333
- toggleCorrectResponse(show: boolean): void;
334
- connectedCallback(): void;
335
- disconnectedCallback(): void;
336
- }
337
- declare global {
338
- interface HTMLElementTagNameMap {
339
- 'qti-graphic-order-interaction': QtiGraphicOrderInteraction;
340
- }
341
- }
342
-
343
- declare const QtiHotspotInteraction_base: (abstract new (...args: any[]) => ChoicesInterface) & typeof Interaction;
344
- declare class QtiHotspotInteraction extends QtiHotspotInteraction_base {
345
- #private;
346
- static styles: CSSResultGroup;
347
- render(): lit.TemplateResult<1>;
348
- connectedCallback(): void;
349
- disconnectedCallback(): void;
350
- }
351
- declare global {
352
- interface HTMLElementTagNameMap {
353
- 'qti-hotspot-interaction': QtiHotspotInteraction;
354
- }
355
- }
356
-
357
- declare const QtiHottextInteraction_base: (abstract new (...args: any[]) => ChoicesInterface) & typeof Interaction;
358
- declare class QtiHottextInteraction extends QtiHottextInteraction_base {
359
- #private;
360
- static styles: CSSResultGroup;
361
- class: string;
362
- render: () => lit.TemplateResult<1>;
363
- connectedCallback(): void;
364
- updated(_changedProperties: PropertyValues): void;
365
- }
366
-
367
- interface OptionType {
368
- content: string | Node[];
369
- value: string;
370
- selected: boolean;
371
- }
372
- declare class QtiInlineChoiceInteraction extends Interaction {
373
- #private;
374
- constructor();
375
- get isInline(): boolean;
376
- static get styles(): lit.CSSResultGroup[];
377
- protected options: OptionType[];
378
- protected correctOption: any;
379
- protected _dropdownOpen: boolean;
380
- private _slotObserver;
381
- private readonly _menuId;
382
- configContext: ConfigContext;
383
- render(): lit.TemplateResult<1>;
384
- connectedCallback(): Promise<void>;
385
- disconnectedCallback(): void;
386
- willUpdate(changed: PropertyValues<this>): void;
387
- updated(changed: PropertyValues<this>): void;
388
- validate(): boolean;
389
- reset(): void;
390
- set response(value: string | null);
391
- get response(): string | null;
392
- toggleInternalCorrectResponse(show: boolean): void;
393
- }
394
- declare global {
395
- interface HTMLElementTagNameMap {
396
- 'qti-inline-choice-interaction': QtiInlineChoiceInteraction;
397
- }
398
- }
399
-
400
- declare const QtiSimpleAssociableChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
401
- declare class QtiSimpleAssociableChoice extends QtiSimpleAssociableChoice_base {
402
- static styles: CSSResultGroup;
403
- /** the minimal number of selections a candidate must make */
404
- matchMin: number;
405
- /** the maximum number of selections a candidate must make, the other options will be disabled when max options is checked */
406
- matchMax: number;
407
- fixed: boolean;
408
- connectedCallback(): void;
409
- render(): lit.TemplateResult<1>;
410
- }
411
- declare global {
412
- interface HTMLElementTagNameMap {
413
- 'qti-simple-associable-choice': QtiSimpleAssociableChoice;
414
- }
415
- }
416
-
417
- declare const QtiMatchInteraction_base: (abstract new (...args: any[]) => DragDropSlottedSortable) & (abstract new (...args: any[]) => DragDropSlotted) & typeof Interaction;
418
- declare class QtiMatchInteraction extends QtiMatchInteraction_base {
419
- #private;
420
- static styles: CSSResultGroup;
421
- protected sourceChoices: QtiSimpleAssociableChoice[];
422
- protected targetChoices: QtiSimpleAssociableChoice[];
423
- protected lastCheckedRadio: HTMLInputElement | null;
424
- class: string;
425
- protected _response: string | string[];
426
- get response(): string[];
427
- set response(val: string[]);
428
- responseIdentifier: string;
429
- protected correctOptions: {
430
- source: string;
431
- target: string;
432
- }[];
433
- connectedCallback(): Promise<void>;
434
- protected handleRadioClick: (e: {
435
- target: HTMLInputElement;
436
- }) => void;
437
- protected handleRadioChange: (e: {
438
- target: any;
439
- }) => void;
440
- validate(): boolean;
441
- toggleInternalCorrectResponse(show: boolean): void;
442
- toggleCandidateCorrection(show: boolean): void;
443
- render(): lit.TemplateResult<1>;
444
- }
445
- declare global {
446
- interface HTMLElementTagNameMap {
447
- 'qti-match-interaction': QtiMatchInteraction;
448
- }
449
- }
450
-
451
- declare class QtiMediaInteraction extends Interaction {
452
- #private;
453
- static styles: CSSResultGroup;
454
- reset(): void;
455
- validate(): boolean;
456
- get response(): string | null;
457
- set response(val: string | null);
458
- static get properties(): {
459
- step: {
460
- type: NumberConstructor;
461
- attribute: string;
462
- default: number;
463
- };
464
- };
465
- render(): lit.TemplateResult<1>;
466
- constructor();
467
- connectedCallback(): void;
468
- }
469
- declare global {
470
- interface HTMLElementTagNameMap {
471
- 'qti-media-interaction': QtiMediaInteraction;
472
- }
473
- }
474
-
475
- declare const QtiOrderInteraction_base: (abstract new (...args: any[]) => DragDropSlottedSortable) & (abstract new (...args: any[]) => DragDropSlotted) & typeof Interaction;
476
- declare class QtiOrderInteraction extends QtiOrderInteraction_base {
477
- #private;
478
- static styles: lit.CSSResult;
479
- protected childrenMap: Element[];
480
- protected nrChoices: number;
481
- correctResponses: string[];
482
- showCorrectResponses: boolean;
483
- /** orientation of choices */
484
- orientation: 'horizontal' | 'vertical';
485
- render(): lit.TemplateResult<1>;
486
- toggleCorrectResponse(show: boolean): void;
487
- toggleCandidateCorrection(show: boolean): void;
488
- getValue(val: string[]): string[];
489
- protected getResponse(): string[];
490
- shouldTreatBlockedMaxAsInvalid(): boolean;
491
- firstUpdated(): Promise<void>;
233
+ /**
234
+ * Shared status values for PCI lifecycle callbacks.
235
+ *
236
+ * Matches the status vocabulary used in IMS QTI 3 PCI documentation.
237
+ */
238
+ type PciInteractionStatus = 'interacting' | 'suspended' | 'closed' | 'solution' | 'review';
239
+ /**
240
+ * Correct response of a response declaration, mirroring `qti-correct-response`.
241
+ *
242
+ * `value` holds the authored `qti-value` content: a single value for `single`
243
+ * cardinality, an array of values for every other cardinality.
244
+ */
245
+ interface PciCorrectResponse {
246
+ value: string | string[];
492
247
  }
493
- declare global {
494
- interface HTMLElementTagNameMap {
495
- 'qti-order-interaction': QtiOrderInteraction;
496
- }
248
+ /**
249
+ * Response declaration passed into the `getInstance` configuration so a PCI can
250
+ * render a correct response itself when the item is in `solution` status.
251
+ *
252
+ * Mirrors `qti-response-declaration` with camelCased names. Every field is
253
+ * optional, a delivery engine passes as much or as little as it has, and
254
+ * `correctResponse` is absent when the response variable has none.
255
+ *
256
+ * `correctResponse` is also withheld while the candidate is still working: it is
257
+ * only sent when `status` is `solution` or `review`, so a PCI never holds the
258
+ * answer key during `interacting`.
259
+ *
260
+ * See https://github.com/1EdTech/qti-project-management/issues/210
261
+ */
262
+ interface PciResponseDeclaration {
263
+ baseType?: BaseType;
264
+ cardinality?: Cardinality;
265
+ correctResponse?: PciCorrectResponse;
497
266
  }
498
-
499
267
  /**
500
268
  * QTI base-type `file` representation.
501
269
  */
@@ -571,13 +339,13 @@ declare type QtiVariableJSON = {
571
339
  declare class QtiPortableCustomInteraction extends Interaction {
572
340
  #private;
573
341
  protected _iframeLoaded: boolean;
342
+ protected _interactionReady: boolean;
574
343
  protected _pendingMessages: Array<{
575
344
  method: string;
576
345
  params: any;
577
346
  }>;
578
347
  protected iframe: HTMLIFrameElement;
579
348
  protected _iframeMessageOrigin: string | null;
580
- private _iframeObjectUrl;
581
349
  static styles: CSSResultGroup;
582
350
  module: string;
583
351
  customInteractionTypeIdentifier: string;
@@ -586,6 +354,22 @@ declare class QtiPortableCustomInteraction extends Interaction {
586
354
  requireJsUrl: string;
587
355
  baseUrl: string;
588
356
  useDefaultPaths: boolean;
357
+ /**
358
+ * Item lifecycle status handed to the PCI in its `getInstance` configuration.
359
+ * A delivery engine sets `solution` to let a PCI render the correct response.
360
+ */
361
+ status: PciInteractionStatus;
362
+ /**
363
+ * Response declaration passed into the PCI configuration, so a PCI can render
364
+ * the correct response itself instead of having it pushed in as a response.
365
+ *
366
+ * Derived from the item context, unless a host sets it explicitly - the
367
+ * correct response viewer does, since it has no response declaration of its own.
368
+ *
369
+ * See https://github.com/1EdTech/qti-project-management/issues/210
370
+ */
371
+ set responseDeclaration(declaration: PciResponseDeclaration | null);
372
+ get responseDeclaration(): PciResponseDeclaration | null;
589
373
  private _errorMessage;
590
374
  protected context?: ItemContext;
591
375
  protected qtiContext?: QtiContext;
@@ -657,12 +441,6 @@ declare class QtiPortableCustomInteraction extends Interaction {
657
441
  * IFRAME MODE: Generate iframe HTML content
658
442
  */
659
443
  protected generateIframeContent(): string;
660
- /**
661
- * Toggle the display of the correct response
662
- * @param responseVariable The response variable containing the correct response
663
- * @param show Whether to show or hide the correct response
664
- */
665
- toggleInternalCorrectResponse(show: boolean): void;
666
444
  /**
667
445
  * Method to disable the PCI for review mode
668
446
  * This can be used when showing the correct response
@@ -680,236 +458,1112 @@ declare global {
680
458
  }
681
459
  }
682
460
 
683
- declare class QtiPositionObjectInteraction extends LitElement {
461
+ declare const QtiOrderInteraction_base: (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlottedSortable) & (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlotted) & typeof Interaction;
462
+ /**
463
+ * Order interaction: candidates arrange choices into a target sequence.
464
+ *
465
+ * @customElement qti-order-interaction
466
+ *
467
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
468
+ * @attr {'horizontal'|'vertical'} [orientation=vertical] - Layout direction of the drop
469
+ * sequence. Unlike on `qti-choice-interaction`, QTI does not deprecate this for order.
470
+ * @attr {boolean} [shuffle=false] - Requests choice shuffling. Applied by the transform
471
+ * pipeline (`qti-transformers`), not by this element.
472
+ * @attr {number} [min-associations=1] - Non-QTI vocabulary inherited from the drag-drop
473
+ * mixin; currently the only way to set the lower bound. QTI spells this `min-choices`.
474
+ * @attr {number} [max-associations=0] - Non-QTI vocabulary inherited from the drag-drop
475
+ * mixin; currently the only way to set the upper bound. QTI spells this `max-choices`.
476
+ * @attr {number} min-choices - Not implemented. The QTI-correct spelling of the lower bound.
477
+ * See plans/interaction-attribute-spec-conformance.md.
478
+ * @attr {number} max-choices - Not implemented. The QTI-correct spelling of the upper bound.
479
+ * See plans/interaction-attribute-spec-conformance.md.
480
+ * @attr {boolean} [auto-size-dropzones=true] - Extension, not QTI. Sizes every drop target to
481
+ * the widest chip so placement does not reflow the layout. On by default: an order slot is a
482
+ * socket cut to one chip, and both axes are measured (see DROP-SIZING.md).
483
+ * @attr {boolean} [disable-animations=false] - Extension, not QTI. Disables the FLIP move
484
+ * animation.
485
+ *
486
+ * @slot prompt - The prompt shown above the interaction.
487
+ * @slot drags - The draggable choice sources.
488
+ *
489
+ * @csspart container - The outer container wrapping drags and drops.
490
+ * @csspart drags - Wrapper around the drag sources slot.
491
+ * @csspart drops - The drop-target region.
492
+ * @csspart drop - Each individual drop target.
493
+ * @csspart drag - A choice that has been placed into a drop target.
494
+ */
495
+ declare class QtiOrderInteraction extends QtiOrderInteraction_base {
496
+ static styles: lit.CSSResult[];
497
+ protected childrenMap: Element[];
498
+ protected nrChoices: number;
499
+ /** orientation of choices */
500
+ orientation: 'horizontal' | 'vertical';
501
+ render(): lit.TemplateResult<1>;
502
+ getValue(val: string[]): string[];
503
+ protected getResponse(): string[];
504
+ shouldTreatBlockedMaxAsInvalid(): boolean;
505
+ firstUpdated(): Promise<void>;
506
+ }
507
+ declare global {
508
+ interface HTMLElementTagNameMap {
509
+ 'qti-order-interaction': QtiOrderInteraction;
510
+ }
511
+ }
512
+
513
+ /**
514
+ * Media interaction: wraps an embedded media object (audio/video) and tracks play events.
515
+ *
516
+ * @slot prompt - The prompt shown above the media element.
517
+ * @slot - Default slot for the embedded media element.
518
+ */
519
+ declare class QtiMediaInteraction extends Interaction {
520
+ #private;
684
521
  static styles: CSSResultGroup;
522
+ reset(): void;
523
+ validate(): boolean;
524
+ get response(): string | null;
525
+ set response(val: string | null);
526
+ static get properties(): {
527
+ step: {
528
+ type: NumberConstructor;
529
+ attribute: string;
530
+ default: number;
531
+ };
532
+ };
685
533
  render(): lit.TemplateResult<1>;
534
+ constructor();
535
+ connectedCallback(): void;
536
+ }
537
+ declare global {
538
+ interface HTMLElementTagNameMap {
539
+ 'qti-media-interaction': QtiMediaInteraction;
540
+ }
686
541
  }
687
542
 
688
- declare class QtiPositionObjectStage extends LitElement {
543
+ declare const QtiMatchInteraction_base: (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlottedSortable) & (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlotted) & typeof Interaction;
544
+ /**
545
+ * Match interaction: candidates pair items from two sets, either as drag-and-drop or as a tabular grid.
546
+ *
547
+ * @customElement qti-match-interaction
548
+ *
549
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
550
+ * @attr {number} [max-associations=0] - Maximum pairings across the whole interaction; `0`
551
+ * means unlimited. QTI's own default is `1`; this element defaults to unlimited because a
552
+ * literal `1` breaks any multi-pair match item. See plans/interaction-attribute-spec-conformance.md.
553
+ * @attr {number} [min-associations=1] - Minimum pairings for a valid response.
554
+ * @attr {boolean} [shuffle=false] - Requests shuffling of both match sets. Applied by the
555
+ * transform pipeline (`qti-transformers`), not by this element.
556
+ * @attr {'qti-match-tabular'|'qti-choices-top'|'qti-choices-bottom'|'qti-choices-left'|'qti-choices-right'} class -
557
+ * QTI shared presentation vocabulary. `qti-match-tabular` renders a checkbox/radio grid
558
+ * instead of drag-and-drop; the `qti-choices-*` values position the source set.
559
+ * @attr {boolean} [auto-size-dropzones=false] - Extension, not QTI. Sizes every drop target to
560
+ * the widest chip so placement does not reflow the layout. The mixin default is `true`; this
561
+ * interaction is the one that overrides it to `false`, because a match target is a category card
562
+ * rather than a socket (see the field below and DROP-SIZING.md §1).
563
+ * @attr {boolean} [disable-animations=false] - Extension, not QTI. Disables the FLIP move
564
+ * animation.
565
+ *
566
+ * @slot prompt - The prompt shown above the interaction.
567
+ * @slot match-cols - Column headers (tabular mode).
568
+ * @slot match-rows - Row headers (tabular mode).
569
+ * @slot - Default slot for the two match sets (drag-and-drop mode).
570
+ *
571
+ * @csspart grid - The tabular grid container.
572
+ * @csspart corner - The top-left corner cell of the grid.
573
+ * @csspart cols-wrap - Wrapper row for the column headers.
574
+ * @csspart c-header - The column header slot wrapper.
575
+ * @csspart rows-wrap - Wrapper column for the row headers.
576
+ * @csspart r-header - The row header slot wrapper.
577
+ * @csspart checkbox-grid - The interactive cell grid area.
578
+ * @csspart input-cell - Each cell's label element.
579
+ * @csspart control - The visible checkbox/radio box (tabular mode). Also carries the variant
580
+ * tokens `radio` | `checkbox`, `checked`, and `correct` | `incorrect` — e.g.
581
+ * `::part(control radio checked correct)`. These mirror the custom-state vocabulary; the cells
582
+ * are plain spans in the shadow root, so they cannot carry real `:state()`.
583
+ * @csspart control-mark - The inner mark element; carries the same variant tokens as `control`.
584
+ * @csspart message - Live validation message region (role="alert").
585
+ */
586
+ declare class QtiMatchInteraction extends QtiMatchInteraction_base {
689
587
  static styles: CSSResultGroup;
690
- choiceOrdering: boolean;
691
- startX: any;
692
- startY: any;
693
- dragElement: any;
588
+ /**
589
+ * Match targets are categories, not slots. They should look able to hold several answers, so they
590
+ * take a flat floor (the `--qti-dropzone-min-height` fallback) rather than the size of the widest chip.
591
+ *
592
+ * This is a property of the INTERACTION, not of an individual target. A `match-max="1"` target is
593
+ * still a category that happens to take one answer, and it sits in a grid beside targets that take
594
+ * several — sizing each one to its own contents would make that grid ragged. So the whole
595
+ * interaction opts out, and the per-target `match-max` decides nothing about size here.
596
+ *
597
+ * The interactions where a drop IS a slot — gap-match, order, associate — keep measurement on, and
598
+ * their drops are exactly the widest chip plus the inset.
599
+ */
600
+ autoSizeDropzones: boolean;
601
+ protected sourceChoices: QtiSimpleAssociableChoice$1[];
602
+ protected targetChoices: QtiSimpleAssociableChoice$1[];
603
+ protected lastCheckedRadio: HTMLInputElement | null;
604
+ class: string;
605
+ protected _response: string | string[];
606
+ get response(): string[];
607
+ set response(val: string[]);
608
+ isDragDropEnabled(): boolean;
609
+ initiateDrag(...args: any[]): void;
610
+ afterCache(): void;
611
+ responseIdentifier: string;
612
+ connectedCallback(): Promise<void>;
613
+ protected willUpdate(changed: PropertyValues): void;
614
+ private syncTabularSlotting;
615
+ protected handleRadioClick: (e: {
616
+ target: HTMLInputElement;
617
+ }) => void;
618
+ protected handleRadioChange: (e: {
619
+ target: any;
620
+ }) => void;
621
+ validate(): boolean;
622
+ /** Extension hook for packages that add visual state tokens to tabular cells. */
623
+ protected getCellStateVariant(_value: string, _checked: boolean): string;
694
624
  render(): lit.TemplateResult<1>;
625
+ }
626
+ declare global {
627
+ interface HTMLElementTagNameMap {
628
+ 'qti-match-interaction': QtiMatchInteraction;
629
+ }
630
+ }
631
+
632
+ interface OptionType {
633
+ content: string | Node[];
634
+ value: string;
635
+ selected: boolean;
636
+ }
637
+ declare const QtiInlineChoiceInteraction_base: (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_menu_auto_size.MenuAutoSize) & typeof Interaction;
638
+ /**
639
+ * Inline choice interaction: dropdown selector rendered inline with surrounding text.
640
+ *
641
+ * @customElement qti-inline-choice-interaction
642
+ *
643
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
644
+ * @attr {string} data-prompt - Placeholder shown before a choice is picked. Falls back to
645
+ * the item configuration's `inlineChoicePrompt`, then to `select`.
646
+ * @attr {boolean} [shuffle=false] - Requests option shuffling. Applied by the transform
647
+ * pipeline (`qti-transformers`), not by this element.
648
+ * @attr {boolean} [required=false] - Whether a choice must be selected for the response to be
649
+ * valid. Written as `required="true"` / `required="false"`; a bare `required` is accepted too.
650
+ * @attr {number} [min-choices=0] - Equivalent spelling of `required`: `1` demands an answer.
651
+ * Absent from the QTI attribute table for this element but used by the conformance suite.
652
+ *
653
+ * @slot - Default slot for `qti-inline-choice` options.
654
+ *
655
+ * @csspart trigger - The dropdown trigger button.
656
+ * @csspart value - The currently displayed value inside the trigger.
657
+ * @csspart dropdown-icon - The chevron icon inside the trigger; also carries `dropdown-icon-open` when open.
658
+ * @csspart menu - The popover element containing the option list.
659
+ * @csspart option - Each option button; also carries `option-prompt` and `option-selected` variants.
660
+ * @csspart option-content - The content wrapper inside each option.
661
+ */
662
+ declare class QtiInlineChoiceInteraction extends QtiInlineChoiceInteraction_base {
663
+ #private;
695
664
  constructor();
696
- dragElementHandler(event: MouseEvent): void;
697
- firstUpdated(a: PropertyValueMap<any>): void;
698
- removeMoveListener(): void;
665
+ get isInline(): boolean;
666
+ static get styles(): lit.CSSResultGroup[];
667
+ protected options: OptionType[];
668
+ protected _dropdownOpen: boolean;
669
+ private _slotObserver;
670
+ private readonly _menuId;
671
+ configContext: ConfigContext;
672
+ /**
673
+ * Placeholder shown in the closed combobox before a choice is picked.
674
+ *
675
+ * Declared rather than read straight off `dataset` so it reaches the custom elements
676
+ * manifest, the generated types and the Storybook controls — and so that changing it
677
+ * re-renders, which reading `dataset` at render time never did.
678
+ *
679
+ * Falls back to the item configuration's `inlineChoicePrompt`, then to `select`.
680
+ */
681
+ dataPrompt: string;
682
+ protected _handleDataPromptChange: () => void;
683
+ /**
684
+ * Whether a choice must be selected for the response to be valid. QTI defaults this to
685
+ * false, so an untouched dropdown is a valid empty response unless an author opts in.
686
+ *
687
+ * QTI writes `required="true"` / `required="false"` rather than using HTML's bare-attribute
688
+ * boolean, so `required="false"` must read as false — which Lit's default Boolean converter
689
+ * would get backwards, since it only tests for the attribute's presence.
690
+ */
691
+ required: boolean;
692
+ /**
693
+ * Minimum selections for a valid response — in practice 0 or 1, since the dropdown holds one.
694
+ *
695
+ * Not in the QTI 3 Implementation Guide's attribute table for this element, which offers only
696
+ * `required`. It is in the conformance suite: `Advanced/Q12-inline-choice/inline-choice-sv-3`
697
+ * expresses "must answer" as `min-choices="1"`, and pairs it with `data-min-selections-message`.
698
+ * Authors reach for it because every sibling interaction takes it, so it is honoured here as an
699
+ * equivalent spelling of `required`.
700
+ */
701
+ minChoices: number;
702
+ protected _handleRequiredChange: () => void;
703
+ /** The closed combobox — the box showing the chosen option. */
704
+ protected renderTrigger(): unknown;
705
+ /** The popover listbox. */
706
+ protected renderMenu(): unknown;
707
+ /** Hidden until `Interaction.reportValidity` shows it. */
708
+ protected renderValidationMessage(): unknown;
709
+ render(): lit.TemplateResult<1>;
710
+ connectedCallback(): Promise<void>;
699
711
  disconnectedCallback(): void;
712
+ willUpdate(changed: PropertyValues<this>): void;
713
+ updated(changed: PropertyValues<this>): void;
714
+ /**
715
+ * Autosizing is opt-in through `configContext.inlineChoiceAutosize`, and an explicit
716
+ * `qti-input-width-*` class always wins.
717
+ *
718
+ * That second check has to live here rather than in CSS: the measurement is written as an inline
719
+ * style on the trigger, and the width classes set the same property on `:host`, so the cascade
720
+ * would hand it to the measurement every time. Not writing at all is what makes the class win.
721
+ */
722
+ shouldAutoSizeMenu(): boolean;
723
+ /**
724
+ * The chevron sits in the trigger and not in the menu, so the menu never measures it.
725
+ *
726
+ * `offsetWidth`, NOT `getBoundingClientRect().width`: the icon rotates when the menu opens, and a
727
+ * client rect reports the TRANSFORMED box — so a chevron caught mid-rotation measures wider than
728
+ * it is, and the trigger grew and shrank by a few pixels on every open. offsetWidth is the layout
729
+ * box and ignores the transform. (Same trap the drag-drop clone code documents for a chip picked
730
+ * up mid-animation.)
731
+ */
732
+ menuAutoSizeExtraWidth(): number;
733
+ validate(): boolean;
734
+ reportValidity(): boolean;
735
+ reset(): void;
736
+ /**
737
+ * Captures an attribute-set response before slotted options have been
738
+ * gathered. `#updateOptions` consumes it once the options exist.
739
+ * `undefined` = no pending value.
740
+ */
741
+ private _pendingResponse;
742
+ set response(value: string | null);
743
+ get response(): string | null;
700
744
  }
701
745
  declare global {
702
746
  interface HTMLElementTagNameMap {
703
- 'qti-position-object-stage': QtiPositionObjectStage;
747
+ 'qti-inline-choice-interaction': QtiInlineChoiceInteraction;
704
748
  }
705
749
  }
706
750
 
707
- declare class QtiSelectPointInteraction extends Interaction {
708
- #private;
751
+ declare const QtiHottextInteraction_base: (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_choices_choices_mixin.ChoicesInterface) & typeof Interaction;
752
+ /**
753
+ * Hottext interaction: candidates select highlighted words within a text block.
754
+ *
755
+ * @customElement qti-hottext-interaction
756
+ *
757
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
758
+ * @attr {number} [max-choices=1] - Maximum selectable hottexts; `0` means unlimited.
759
+ * @attr {number} [min-choices=0] - Minimum selectable hottexts for a valid response.
760
+ * @attr {'qti-unselected-hidden'} class - QTI shared presentation vocabulary.
761
+ * `qti-unselected-hidden` leaves the selectable words visually indistinguishable from the
762
+ * surrounding prose until they are selected.
763
+ *
764
+ * @slot - Default slot for the mixed content and `qti-hottext` choices.
765
+ *
766
+ * @csspart message - Live validation message region (role="alert").
767
+ */
768
+ declare class QtiHottextInteraction extends QtiHottextInteraction_base {
709
769
  static styles: CSSResultGroup;
710
- maxChoices: number;
711
- minChoices: number;
712
- response: string[] | null;
713
- private _correctAreas;
714
- private _responseCorrection;
770
+ render: () => lit.TemplateResult<1>;
771
+ }
772
+
773
+ /**
774
+ * A drop target positioned over an image. Like `qti-gap`, it renders the chips it holds from
775
+ * `dragDropContext` rather than having them appended into it.
776
+ *
777
+ * @csspart drop - The region a chip lands in.
778
+ */
779
+ declare class QtiAssociableHotspot extends LitElement {
780
+ static styles: CSSResultGroup;
781
+ /** Carries `:state(filled)` while the hotspot holds a chip. */
782
+ internals: ElementInternals;
783
+ /** Opt-in marker read by `DragDropSlottedMixin`; see qti-gap. */
784
+ readonly acceptsDeclarativeDrops = true;
785
+ identifier: string;
786
+ private _dragDrop?;
787
+ /** The chips this hotspot holds. Stable node references, cloned once at drop time. */
788
+ get drags(): readonly HTMLElement[];
715
789
  connectedCallback(): void;
716
- get responsePoints(): {
717
- x: number;
718
- y: number;
719
- }[];
720
- toggleCandidateCorrection(show: boolean): void;
721
- toggleCorrectResponse(show: boolean): any;
722
- updated(changedProperties: Map<string | number | symbol, unknown>): void;
723
790
  render(): lit.TemplateResult<1>;
724
- validate(): boolean;
725
- firstUpdated(): void;
726
- disconnectedCallback(): void;
727
791
  }
728
792
  declare global {
729
793
  interface HTMLElementTagNameMap {
730
- 'qti-select-point-interaction': QtiSelectPointInteraction;
794
+ 'qti-associable-hotspot': QtiAssociableHotspot;
731
795
  }
732
796
  }
733
797
 
734
- declare class QtiSliderInteraction extends Interaction {
798
+ /**
799
+ * A gap in the prose, and the first drop target to render its own chips.
800
+ *
801
+ * The interaction owns placement and publishes it on `dragDropContext`; this element subscribes and
802
+ * renders what it holds. Nothing appends into it. That inverts the old flow, where `handleDrop` did
803
+ * `cloneNode` + `appendChild` and the response was recovered afterwards by reading the DOM back
804
+ * out — which is why placement and the response could ever disagree at all.
805
+ *
806
+ * The chips land in this shadow root rather than in the light DOM, so a theme reaches them as
807
+ * `::part(drag)` — a bare `::part()` matches in any shadow root — instead of by tag. The gap's own
808
+ * `:state(filled)` says whether it holds anything.
809
+ *
810
+ * @customElement qti-gap
811
+ *
812
+ * @attr {string} identifier - Required. Value recorded as the gap side of the response pair.
813
+ * @attr {number} [match-max=1] - How many tokens this gap can hold; `0` means unlimited. Read
814
+ * from the DOM by the drag-drop mixin.
815
+ * @attr {number} [match-min=0] - Minimum tokens this gap must hold.
816
+ * @attr {boolean} [required=false] - Not implemented. Whether this gap must be filled for the
817
+ * response to be valid.
818
+ * @attr {string} template-identifier - Not implemented. Identifier of a template variable
819
+ * controlling this gap's visibility.
820
+ * @attr {'show'|'hide'} [show-hide=show] - Not implemented. How `template-identifier` controls
821
+ * visibility.
822
+ *
823
+ * @csspart drop - The region a chip lands in. Reserves the widest chip's box; see qti-gap.styles.
824
+ */
825
+ declare class QtiGap extends LitElement {
826
+ static styles: CSSResultGroup;
827
+ /** Carries `:state(filled)` while the gap holds a chip. */
828
+ internals: ElementInternals;
829
+ /**
830
+ * Opt-in marker, read by `DragDropSlottedMixin`. While this is true the interaction keeps this
831
+ * target's chips in its placement map and never touches this element's children.
832
+ */
833
+ readonly acceptsDeclarativeDrops = true;
834
+ tabindex: number | undefined;
835
+ identifier: string;
836
+ private _dragDrop?;
837
+ /** The chips this gap holds. Stable node references, cloned once at drop time by the interaction. */
838
+ get drags(): readonly HTMLElement[];
839
+ render(): lit.TemplateResult<1>;
840
+ }
841
+ declare global {
842
+ interface HTMLElementTagNameMap {
843
+ 'qti-gap': QtiGap;
844
+ }
845
+ }
846
+
847
+ declare class QtiGapImg extends LitElement {
848
+ static styles: CSSResultGroup;
849
+ tabindex: number | undefined;
850
+ /**
851
+ * `qti-gap-img` is a draggable chip, so it needs ElementInternals to carry the drag states
852
+ * (`dragging`, `placeholder`). It works without a shadow root.
853
+ *
854
+ * NOTE: this element never calls `super.connectedCallback()`, so Lit never enables updating
855
+ * and it has no shadow root — which makes `qti-gap-img.styles.ts` dead code. Fixing that means
856
+ * adding a `<slot>` to a `render()` first, otherwise the authored `<img>` child disappears.
857
+ */
858
+ internals: ElementInternals;
859
+ connectedCallback(): void;
860
+ }
861
+ declare global {
862
+ interface HTMLElementTagNameMap {
863
+ 'qti-gap-img': QtiGapImg;
864
+ }
865
+ }
866
+
867
+ declare const QtiHotspotChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
868
+ declare class QtiHotspotChoice extends QtiHotspotChoice_base {
869
+ static styles: CSSResultGroup;
870
+ order: number;
871
+ }
872
+ declare global {
873
+ interface HTMLElementTagNameMap {
874
+ 'qti-hotspot-choice': QtiHotspotChoice;
875
+ }
876
+ }
877
+
878
+ declare const QtiHottext_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
879
+ /**
880
+ * A selectable span of text inside `qti-hottext-interaction`.
881
+ *
882
+ * @customElement qti-hottext
883
+ *
884
+ * @attr {string} identifier - Required. Value recorded in the response when this span is
885
+ * selected.
886
+ * @attr {string} template-identifier - Not implemented. Identifier of a template variable
887
+ * controlling this span's visibility.
888
+ * @attr {'show'|'hide'} [show-hide=show] - Not implemented. How `template-identifier` controls
889
+ * visibility.
890
+ */
891
+ declare class QtiHottext extends QtiHottext_base {
892
+ static styles: CSSResultGroup;
893
+ render(): lit.TemplateResult<1>;
894
+ }
895
+ declare global {
896
+ interface HTMLElementTagNameMap {
897
+ 'qti-hottext': QtiHottext;
898
+ }
899
+ }
900
+
901
+ declare class QtiPrompt extends LitElement {
902
+ static styles: CSSResultGroup;
903
+ render(): lit.TemplateResult<1>;
904
+ connectedCallback(): void;
905
+ }
906
+ declare global {
907
+ interface HTMLElementTagNameMap {
908
+ 'qti-prompt': QtiPrompt;
909
+ }
910
+ }
911
+
912
+ declare const QtiSimpleAssociableChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
913
+ /**
914
+ * A choice in one of the two match sets of `qti-match-interaction`, or in
915
+ * `qti-associate-interaction`.
916
+ *
917
+ * @customElement qti-simple-associable-choice
918
+ *
919
+ * @attr {string} identifier - Required. Value recorded in the response pair when this choice
920
+ * participates in an association.
921
+ * @attr {number} [match-max=1] - How many associations this choice may take part in; `0` means
922
+ * unlimited. On a target this is its capacity — the bucket size in a sorting item.
923
+ * @attr {number} [match-min=0] - Minimum associations this choice must take part in.
924
+ * @attr {boolean} [fixed=false] - Pins this choice in place when the enclosing interaction is
925
+ * shuffled.
926
+ * @attr {string} template-identifier - Not implemented. Identifier of a template variable
927
+ * controlling this choice's visibility.
928
+ * @attr {'show'|'hide'} [show-hide=show] - Not implemented. How `template-identifier` controls
929
+ * visibility.
930
+ */
931
+ declare class QtiSimpleAssociableChoice extends QtiSimpleAssociableChoice_base {
932
+ static styles: CSSResultGroup;
933
+ /** the minimal number of selections a candidate must make */
934
+ matchMin: number;
935
+ /** the maximum number of selections a candidate must make, the other options will be disabled when max options is checked */
936
+ matchMax: number;
937
+ fixed: boolean;
938
+ connectedCallback(): void;
939
+ /** Opt-in marker read by `DragDropSlottedMixin`; see qti-gap. */
940
+ readonly acceptsDeclarativeDrops = true;
941
+ private _dragDrop?;
942
+ /** The chips this choice holds when it acts as a drop target (match-interaction's second set). */
943
+ get drags(): readonly HTMLElement[];
944
+ render(): lit.TemplateResult<1>;
945
+ }
946
+ declare global {
947
+ interface HTMLElementTagNameMap {
948
+ 'qti-simple-associable-choice': QtiSimpleAssociableChoice;
949
+ }
950
+ }
951
+
952
+ declare const QtiSimpleChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
953
+ /**
954
+ * A choice, used by `qti-choice-interaction` and `qti-order-interaction`.
955
+ *
956
+ * The `control` part is one box whose *role* is carried by state, not by its name: a radio
957
+ * circle under `:state(radio)`, a checkbox square under `:state(checkbox)`, and a drag grip
958
+ * when the choice is draggable. Style it as `qti-simple-choice::part(control)`.
959
+ *
960
+ * @customElement qti-simple-choice
961
+ *
962
+ * @attr {string} identifier - Required. Value recorded in the response when this choice is
963
+ * selected, or its position when used for ordering.
964
+ * @attr {boolean} [fixed=false] - Pins this choice in place when the enclosing interaction is
965
+ * shuffled.
966
+ * @attr {string} template-identifier - Identifier of a template variable controlling this
967
+ * choice's visibility.
968
+ * @attr {'show'|'hide'} [show-hide=show] - How `template-identifier` controls visibility.
969
+ *
970
+ * @csspart control - The box before the label (radio / checkbox / drag grip).
971
+ * @csspart control-mark - The mark inside the box (inner dot / checkmark).
972
+ * @csspart label - The default slot holding the choice content.
973
+ * @csspart marker - The order-number badge, when `marker` is set.
974
+ */
975
+ declare class QtiSimpleChoice extends QtiSimpleChoice_base {
976
+ static styles: CSSResultGroup;
977
+ static shadowRootOptions: ShadowRootInit;
978
+ templateIdentifier: string | null;
979
+ showHide: string | null;
980
+ fixed: boolean;
981
+ marker: string;
982
+ get checked(): boolean;
983
+ render(): lit.TemplateResult<1>;
984
+ }
985
+ declare global {
986
+ interface HTMLElementTagNameMap {
987
+ 'qti-simple-choice': QtiSimpleChoice;
988
+ }
989
+ }
990
+
991
+ /**
992
+ * A mixin that adds choice functionality to a LitElement-based class.
993
+ * It dispatches events with a custom `type` and handles selection logic.
994
+ *
995
+ * @param Base - The base class to extend.
996
+ * @param type - The type of the choice, used in event names.
997
+ * @returns A new class extending the base class with choice functionality.
998
+ */
999
+ interface ActiveElementMixinInterface {
1000
+ identifier: string;
1001
+ tabIndex: number;
1002
+ disabled: boolean;
1003
+ readonly: boolean;
1004
+ internals: ElementInternals;
1005
+ }
1006
+
1007
+ interface ChoicesInterface extends ValidatableInteraction {
1008
+ minChoices: number;
1009
+ maxChoices: number;
1010
+ value: string | null;
1011
+ response: string | string[] | null;
1012
+ }
1013
+
1014
+ declare const QtiInlineChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
1015
+ /**
1016
+ * An option in the dropdown of `qti-inline-choice-interaction`.
1017
+ *
1018
+ * @customElement qti-inline-choice
1019
+ *
1020
+ * @attr {string} identifier - Required. Value recorded in the response when this option is
1021
+ * selected.
1022
+ * @attr {boolean} [fixed=false] - Pins this option in place when the interaction is shuffled.
1023
+ * @attr {string} template-identifier - Not implemented. Identifier of a template variable
1024
+ * controlling this option's visibility.
1025
+ * @attr {'show'|'hide'} [show-hide=show] - Not implemented. How `template-identifier` controls
1026
+ * visibility.
1027
+ */
1028
+ declare class QtiInlineChoice extends QtiInlineChoice_base {
735
1029
  #private;
736
1030
  static styles: CSSResultGroup;
737
- private _rail;
738
- min: number;
739
- max: number;
740
- step: number;
741
- validate(): boolean;
1031
+ identifier: string;
1032
+ connectedCallback(): void;
1033
+ disconnectedCallback(): void;
1034
+ render(): lit.TemplateResult<1>;
1035
+ }
1036
+ declare global {
1037
+ interface HTMLElementTagNameMap {
1038
+ 'qti-inline-choice': QtiInlineChoice;
1039
+ }
1040
+ }
1041
+
1042
+ declare const QtiGapText_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
1043
+ /**
1044
+ * A draggable text token that fills a `qti-gap` inside `qti-gap-match-interaction`.
1045
+ *
1046
+ * @customElement qti-gap-text
1047
+ *
1048
+ * @attr {string} identifier - Required. Value recorded in the response pair when this token is
1049
+ * placed into a gap.
1050
+ * @attr {number} [match-max=1] - How many gaps this token may fill; `0` means unlimited.
1051
+ * Read from the DOM by the drag-drop mixin.
1052
+ * @attr {number} [match-min=0] - Minimum gaps this token must fill.
1053
+ * @attr {boolean} [fixed=false] - Pins this token in place when the interaction is shuffled.
1054
+ * @attr {string} template-identifier - Not implemented. Identifier of a template variable
1055
+ * controlling this token's visibility.
1056
+ * @attr {'show'|'hide'} [show-hide=show] - Not implemented. How `template-identifier` controls
1057
+ * visibility.
1058
+ */
1059
+ declare class QtiGapText extends QtiGapText_base {
1060
+ static styles: CSSResultGroup;
1061
+ tabindex: number | undefined;
742
1062
  connectedCallback(): void;
743
- get response(): string;
744
- set response(val: string);
745
- toggleCorrectResponse(show: boolean): void;
746
1063
  render(): lit.TemplateResult<1>;
747
1064
  }
748
1065
  declare global {
749
1066
  interface HTMLElementTagNameMap {
750
- 'qti-slider-interaction': QtiSliderInteraction;
1067
+ 'qti-gap-text': QtiGapText;
751
1068
  }
752
1069
  }
753
1070
 
754
- declare class QtiTextEntryInteraction extends Interaction {
1071
+ declare const QtiHotspotInteraction_base: (abstract new (...args: any[]) => ChoicesInterface) & typeof Interaction;
1072
+ /**
1073
+ * Hotspot interaction: candidates select one or more hotspots on an image.
1074
+ *
1075
+ * @slot prompt - The prompt shown above the image.
1076
+ * @slot - Default slot for the image and hotspot choices.
1077
+ */
1078
+ declare class QtiHotspotInteraction extends QtiHotspotInteraction_base {
755
1079
  #private;
756
1080
  static styles: CSSResultGroup;
757
- inputRef: lit_directives_ref_js.Ref<HTMLInputElement>;
758
- expectedLength: number;
759
- patternMask: string;
760
- placeholderText: string;
761
- dataPatternmaskMessage: string;
762
- response: string | null;
763
- private _input;
764
- protected _handleValueChange: () => void;
765
- get value(): string | null;
766
- set value(val: string | null);
767
- get correctness(): Readonly<Correctness | null>;
768
- get isInline(): boolean;
769
- validate(): boolean;
770
- toggleInternalCorrectResponse(show: boolean): void;
771
1081
  render(): lit.TemplateResult<1>;
772
- protected textChanged(event: Event): void;
773
- reportValidity(): boolean;
774
- reset(): void;
1082
+ connectedCallback(): void;
1083
+ disconnectedCallback(): void;
775
1084
  }
776
1085
  declare global {
777
1086
  interface HTMLElementTagNameMap {
778
- 'qti-text-entry-interaction': QtiTextEntryInteraction;
1087
+ 'qti-hotspot-interaction': QtiHotspotInteraction;
779
1088
  }
780
1089
  }
781
1090
 
782
- declare class QtiUploadInteraction extends Interaction {
1091
+ type HotspotChoice = Choice & {
1092
+ order: number;
1093
+ };
1094
+ declare const QtiGraphicOrderInteraction_base: (abstract new (...args: any[]) => ChoicesInterface) & typeof Interaction;
1095
+ /**
1096
+ * Graphic order interaction: candidates order hotspots on an image.
1097
+ *
1098
+ * @slot prompt - The prompt shown above the image.
1099
+ * @slot - Default slot for the image and hotspot choices.
1100
+ *
1101
+ * @csspart message - Live validation message region (role="alert").
1102
+ */
1103
+ declare class QtiGraphicOrderInteraction extends QtiGraphicOrderInteraction_base {
783
1104
  #private;
784
1105
  static styles: CSSResultGroup;
785
- reset(): void;
786
- validate(): boolean;
787
- get response(): string | null;
788
- set response(base64: string | null);
789
- static get properties(): {
790
- [key: string]: lit.PropertyDeclaration<unknown, unknown>;
791
- };
1106
+ protected choiceOrdering: boolean;
1107
+ protected _choiceElements: Choice[];
792
1108
  render(): lit.TemplateResult<1>;
1109
+ /** Extension hook for packages that add semantic color states to locator pins. */
1110
+ protected resolvePinColor(_choice: HotspotChoice): string;
1111
+ protected refreshLocatorPins(): void;
1112
+ connectedCallback(): void;
1113
+ disconnectedCallback(): void;
793
1114
  }
794
1115
  declare global {
795
1116
  interface HTMLElementTagNameMap {
796
- 'qti-upload-interaction': QtiUploadInteraction;
1117
+ 'qti-graphic-order-interaction': QtiGraphicOrderInteraction;
797
1118
  }
798
1119
  }
799
1120
 
800
- declare class QtiGapImg extends LitElement {
1121
+ declare const QtiGraphicGapMatchInteraction_base: (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlottedSortable) & (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlotted) & typeof Interaction;
1122
+ /**
1123
+ * Graphic gap-match interaction: candidates drag choices onto image hotspots.
1124
+ *
1125
+ * @slot prompt - The prompt shown above the image.
1126
+ * @slot drags - The draggable choice sources.
1127
+ * @slot - Default slot for the base image and hotspots.
1128
+ *
1129
+ * @csspart image - Wrapper around the image slot.
1130
+ * @csspart drags - Wrapper around the drag sources slot.
1131
+ * @csspart message - Live validation message region (role="alert").
1132
+ */
1133
+ declare class QtiGraphicGapMatchInteraction extends QtiGraphicGapMatchInteraction_base {
1134
+ #private;
801
1135
  static styles: CSSResultGroup;
802
- tabindex: number | undefined;
1136
+ render(): lit.TemplateResult<1>;
1137
+ shouldReturnToInventoryOnInventoryDrop(): boolean;
803
1138
  connectedCallback(): void;
1139
+ disconnectedCallback(): void;
804
1140
  }
805
1141
  declare global {
806
1142
  interface HTMLElementTagNameMap {
807
- 'qti-gap-img': QtiGapImg;
1143
+ 'qti-graphic-gap-match-interaction': QtiGraphicGapMatchInteraction;
808
1144
  }
809
1145
  }
810
1146
 
811
- declare const QtiGapText_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
812
- declare class QtiGapText extends QtiGapText_base {
1147
+ /**
1148
+ * Graphic associate interaction: candidates connect points/hotspots on an image with lines.
1149
+ *
1150
+ * @slot prompt - The prompt shown above the image.
1151
+ * @slot - Default slot for hotspot choices layered over the image.
1152
+ *
1153
+ * @csspart line - Each line drawn by the candidate.
1154
+ * @csspart correct-line - Each line displayed as part of the correct response.
1155
+ * @csspart point - Each in-progress endpoint indicator.
1156
+ * @csspart message - Live validation message region (role="alert").
1157
+ */
1158
+ declare class QtiGraphicAssociateInteraction extends Interaction {
1159
+ #private;
813
1160
  static styles: CSSResultGroup;
814
- tabindex: number | undefined;
815
- connectedCallback(): void;
1161
+ private startCoord;
1162
+ private mouseCoord;
1163
+ grImage: any[];
1164
+ private _response;
1165
+ constructor();
1166
+ reset(): void;
1167
+ validate(): boolean;
1168
+ set response(val: string | string[] | null);
1169
+ get response(): string[] | null;
1170
+ /** Extension hook for optional SVG lines rendered above the candidate response. */
1171
+ protected renderSupplementalLines(): unknown;
816
1172
  render(): lit.TemplateResult<1>;
1173
+ firstUpdated(): void;
1174
+ disconnectedCallback(): void;
817
1175
  }
818
1176
  declare global {
819
1177
  interface HTMLElementTagNameMap {
820
- 'qti-gap-text': QtiGapText;
1178
+ 'qti-graphic-associate-interaction': QtiGraphicAssociateInteraction;
821
1179
  }
822
1180
  }
823
1181
 
824
- declare class QtiGap extends LitElement {
1182
+ declare const QtiGapMatchInteraction_base: (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlottedSortable) & (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlotted) & typeof Interaction;
1183
+ /**
1184
+ * Drag-and-drop gap-match interaction: candidates drag choices into gap targets.
1185
+ *
1186
+ * @customElement qti-gap-match-interaction
1187
+ *
1188
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
1189
+ * @attr {number} [max-associations=1] - Maximum gaps that may be filled across the whole
1190
+ * interaction; `0` means unlimited.
1191
+ * @attr {number} [min-associations=1] - Minimum filled gaps for a valid response.
1192
+ * @attr {boolean} [shuffle=false] - Requests shuffling of the `qti-gap-text` sources. Applied
1193
+ * by the transform pipeline (`qti-transformers`), not by this element.
1194
+ * @attr {'qti-choices-top'|'qti-choices-bottom'|'qti-choices-left'|'qti-choices-right'} class -
1195
+ * QTI shared presentation vocabulary positioning the gap-choices container.
1196
+ * @attr {boolean} [auto-size-dropzones=true] - Extension, not QTI. Sizes every gap to the
1197
+ * widest chip so placement does not reflow the prose. On by default: a gap is a slot, and a slot
1198
+ * that is already the size of the chip it will hold does not resize when one lands in it.
1199
+ * @attr {boolean} [disable-animations=false] - Extension, not QTI. Disables the FLIP move
1200
+ * animation.
1201
+ *
1202
+ * @slot prompt - The prompt shown above the interaction.
1203
+ * @slot drags - The draggable choice sources.
1204
+ * @slot - Default slot for the drop targets (gaps).
1205
+ *
1206
+ * @csspart drags - Wrapper around the drag sources slot.
1207
+ * @csspart drops - Wrapper around the drop targets slot.
1208
+ * @csspart message - Live validation message region (role="alert").
1209
+ */
1210
+ declare class QtiGapMatchInteraction extends QtiGapMatchInteraction_base {
825
1211
  static styles: CSSResultGroup;
826
- tabindex: number | undefined;
827
1212
  render(): lit.TemplateResult<1>;
828
1213
  }
829
1214
  declare global {
830
1215
  interface HTMLElementTagNameMap {
831
- 'qti-gap': QtiGap;
1216
+ 'qti-gap-match-interaction': QtiGapMatchInteraction;
832
1217
  }
833
1218
  }
834
1219
 
835
- declare const QtiInlineChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
836
- declare class QtiInlineChoice extends QtiInlineChoice_base {
1220
+ /**
1221
+ * A multi-line text-entry interaction.
1222
+ *
1223
+ * @customElement qti-extended-text-interaction
1224
+ *
1225
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
1226
+ * @attr {number} expected-length - Hint at the expected answer length in characters; sets the
1227
+ * textarea's `maxlength`. Also the last-resort row count, used only when neither a
1228
+ * `qti-height-lines-*` class nor `expected-lines` is present.
1229
+ * @attr {string} pattern-mask - Regular expression the value must match to be valid.
1230
+ * @attr {string} placeholder-text - Placeholder shown while the textarea is empty.
1231
+ * @attr {string} data-patternmask-message - Custom validation message shown when
1232
+ * `pattern-mask` fails. Part of the QTI shared interaction vocabulary.
1233
+ * @attr {'qti-height-lines-3'|'qti-height-lines-6'|'qti-height-lines-15'} class - QTI shared
1234
+ * presentation vocabulary controlling the rendered height. Outranks both `expected-lines`
1235
+ * and `expected-length`.
1236
+ * @attr {number} expected-lines - Expected number of lines of response, and the rendered row
1237
+ * count unless a `qti-height-lines-*` class is present.
1238
+ * @attr {number} [base=10] - Not implemented. Numeric base used when recording the value.
1239
+ * @attr {string} string-identifier - Not implemented. Identifier of a second, string-typed
1240
+ * response variable that also receives the raw entry.
1241
+ * @attr {number} max-strings - Not implemented. Maximum number of separate string responses. QTI
1242
+ * defines these for a multi-string response — several bound variables, one field each. This
1243
+ * element renders a single textarea bound to one variable, so there is nothing for the bounds
1244
+ * to count: reading them as a word or paragraph limit would invent a rule QTI does not state.
1245
+ * Implement alongside multi-string rendering, not before it.
1246
+ * @attr {number} min-strings - Not implemented. See `max-strings`.
1247
+ * @attr {'plain'|'preformatted'|'xhtml'} [format=plain] - How the response is presented.
1248
+ * `preformatted` renders the field monospaced; `xhtml` is accepted but downgraded to plain,
1249
+ * because the field is a textarea with no rich-text editor behind it.
1250
+ *
1251
+ * @slot prompt - The prompt shown above the textarea.
1252
+ *
1253
+ * @csspart textarea - The textarea input element.
1254
+ */
1255
+ declare class QtiExtendedTextInteraction extends Interaction {
837
1256
  #private;
838
1257
  static styles: CSSResultGroup;
839
- identifier: string;
840
- connectedCallback(): void;
841
- disconnectedCallback(): void;
1258
+ protected _rows: number;
1259
+ /** expected length is mapped to the property maxlength on the textarea */
1260
+ expectedLength: number;
1261
+ /** QTI's own hint at the response height. Outranked by `qti-height-lines-*`; see `#resolveRows`. */
1262
+ expectedLines: number;
1263
+ /**
1264
+ * How the response text is presented. Reflected so themes can key off
1265
+ * `:host([format='preformatted'])`.
1266
+ *
1267
+ * `xhtml` is accepted and recorded but renders as `plain`: the field is a `<textarea>`, and
1268
+ * there is no rich-text editor behind it. Downgrading loudly beats either refusing valid QTI
1269
+ * or pretending to support formatting the candidate cannot actually produce.
1270
+ */
1271
+ format: 'plain' | 'preformatted' | 'xhtml';
1272
+ protected _handleFormatChange: () => void;
1273
+ patternMask: string;
1274
+ /** text appearing in the extended-text-interaction if it is empty */
1275
+ placeholderText: string;
1276
+ dataPatternmaskMessage: string;
1277
+ classNames: string;
1278
+ protected _handleRowsInputChange(): void;
1279
+ response: string | null;
1280
+ protected _handleResponseChange: () => void;
1281
+ get value(): string | null;
1282
+ set value(val: string | null);
1283
+ validate(): boolean;
1284
+ reportValidity(): boolean;
1285
+ /** The prompt, above the field. */
1286
+ protected renderPrompt(): unknown;
1287
+ /** The field itself. */
1288
+ protected renderTextarea(): unknown;
1289
+ /** Hidden until `Interaction.reportValidity` shows it. */
1290
+ protected renderValidationMessage(): unknown;
842
1291
  render(): lit.TemplateResult<1>;
1292
+ protected textChanged(event: Event): void;
843
1293
  }
844
1294
  declare global {
845
1295
  interface HTMLElementTagNameMap {
846
- 'qti-inline-choice': QtiInlineChoice;
1296
+ 'qti-extended-text-interaction': QtiExtendedTextInteraction;
847
1297
  }
848
1298
  }
849
1299
 
850
- declare const QtiHottext_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
851
- declare class QtiHottext extends QtiHottext_base {
1300
+ /**
1301
+ * A button that ends the current attempt.
1302
+ *
1303
+ * @csspart button - The end-attempt button element.
1304
+ */
1305
+ declare class QtiEndAttemptInteraction extends LitElement {
852
1306
  static styles: CSSResultGroup;
1307
+ responseIdentifier: string;
1308
+ disabled: boolean;
1309
+ /** 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) */
1310
+ countAttempt: 'true' | 'false' | null;
1311
+ title: string;
853
1312
  render(): lit.TemplateResult<1>;
1313
+ endAttempt(_: Event): void;
854
1314
  }
855
1315
  declare global {
856
1316
  interface HTMLElementTagNameMap {
857
- 'qti-hottext': QtiHottext;
1317
+ 'qti-end-attempt-interaction': QtiEndAttemptInteraction;
858
1318
  }
859
1319
  }
860
1320
 
861
- declare const QtiSimpleChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
862
1321
  /**
863
- * qti-order-interaction
864
- * qti-choice-interaction
1322
+ * QTI Custom Interaction component for legacy CES-based interactions.
1323
+ *
1324
+ * This component implements support for custom interactions originally built for the CES
1325
+ * (Custom Element Standard) player - the predecessor to FACET and the Trifork QTI Player.
1326
+ *
1327
+ * @remarks
1328
+ * The interaction workflow:
1329
+ * 1. Fetch the CI manifest (JSON file with script, style, media references)
1330
+ * 2. Check if bootstrap.js uses the CES API
1331
+ * 3. If CES is used:
1332
+ * - Fetch index.html from main window (where service worker/fetch works)
1333
+ * - Inject registerCES proxy script for postMessage-based communication
1334
+ * - Create blob URL and pass it to ciBootstrap
1335
+ * 4. Create pciContainer iframe with style and bootstrap script
1336
+ * 5. Handle postMessage events for getMedia, getResponse, setResponse, getBlobUrl
1337
+ *
1338
+ * The postMessage bridge is necessary because:
1339
+ * - Iframes created via document.write() have about:blank origin
1340
+ * - They cannot access the parent's global CES object (cross-origin)
1341
+ * - Service workers don't control about:blank documents
1342
+ *
1343
+ * Messages are sent to all parent windows to support embedding scenarios like Storybook
1344
+ * where window.top might not be the actual host application.
865
1345
  */
866
- declare class QtiSimpleChoice extends QtiSimpleChoice_base {
1346
+ declare class QtiCustomInteraction extends Interaction {
1347
+ #private;
867
1348
  static styles: CSSResultGroup;
868
- templateIdentifier: string | null;
869
- showHide: string | null;
870
- fixed: boolean;
871
- marker: string;
872
- get checked(): boolean;
1349
+ constructor();
1350
+ data: string;
1351
+ baseItemUrl: string;
1352
+ baseRefUrl: string;
1353
+ id: string;
1354
+ private _errorMessage;
1355
+ manifest: {
1356
+ script: string[];
1357
+ style: string[];
1358
+ media: string[];
1359
+ };
1360
+ connectedCallback(): void;
1361
+ /**
1362
+ * Sets up the CES custom interaction by creating the iframe structure and
1363
+ * handling the CES API communication via postMessage.
1364
+ *
1365
+ * For interactions that use CES, this method:
1366
+ * 1. Fetches the original bootstrap.js and checks if it uses CES
1367
+ * 2. If CES is used, fetches index.html and injects the registerCES proxy
1368
+ * 3. Creates a blob URL for the modified HTML (stored in _contentBlobUrl)
1369
+ * 4. Replaces bootstrap.js with ciBootstrap that loads the blob URL
1370
+ * 5. Sets up postMessage listeners for CES API calls
1371
+ */
1372
+ setupCES(): Promise<void>;
1373
+ handlePostMessage(event: MessageEvent): void;
1374
+ validate(): boolean;
1375
+ get response(): string | string[] | null;
1376
+ set response(val: string | string[] | null);
1377
+ disconnectedCallback(): void;
873
1378
  render(): lit.TemplateResult<1>;
874
1379
  }
875
1380
  declare global {
876
1381
  interface HTMLElementTagNameMap {
877
- 'qti-simple-choice': QtiSimpleChoice;
878
- }
879
- }
880
-
881
- declare const QtiHotspotChoice_base: (abstract new (...args: any[]) => ActiveElementMixinInterface) & typeof LitElement;
882
- declare class QtiHotspotChoice extends QtiHotspotChoice_base {
883
- static styles: CSSResultGroup;
884
- order: number;
885
- orderCorrect: number;
886
- }
887
- declare global {
888
- interface HTMLElementTagNameMap {
889
- 'qti-hotspot-choice': QtiHotspotChoice;
1382
+ 'qti-custom-interaction': QtiCustomInteraction;
890
1383
  }
891
1384
  }
892
1385
 
893
- declare class QtiAssociableHotspot extends LitElement {
1386
+ type Orientation = 'horizontal' | 'vertical' | undefined;
1387
+ declare const QtiChoiceInteraction_base: (abstract new (...args: any[]) => {}) & (abstract new (...args: any[]) => ChoicesInterface$1) & typeof Interaction;
1388
+ /**
1389
+ * A single-response or multiple-response choice interaction.
1390
+ *
1391
+ * @customElement qti-choice-interaction
1392
+ *
1393
+ * @attr {string} response-identifier - Required. Identifier of the bound response variable.
1394
+ * @attr {number} [max-choices=1] - Maximum selectable choices. `1` is a single-response
1395
+ * item; `0` means unlimited and makes it a multiple-response item.
1396
+ * @attr {number} [min-choices=0] - Minimum selectable choices for a valid response.
1397
+ * @attr {'horizontal'|'vertical'} [orientation=vertical] - Deprecated by QTI in favour of
1398
+ * the `qti-orientation-*` class vocabulary.
1399
+ * @attr {boolean} [shuffle=false] - Requests choice shuffling. Applied by the transform
1400
+ * pipeline (`qti-transformers`), not by this element.
1401
+ * @attr {'qti-orientation-horizontal'|'qti-orientation-vertical'|'qti-choices-stacking-1'|'qti-choices-stacking-2'|'qti-choices-stacking-3'|'qti-choices-stacking-4'|'qti-choices-stacking-5'|'qti-labels-none'|'qti-labels-decimal'|'qti-labels-lower-alpha'|'qti-labels-upper-alpha'|'qti-labels-suffix-none'|'qti-labels-suffix-period'|'qti-labels-suffix-parenthesis'|'qti-input-control-hidden'} class - QTI shared presentation vocabulary. Space-separated; takes precedence over `orientation`.
1402
+ *
1403
+ * @slot prompt - The prompt shown above the choices.
1404
+ * @slot - Default slot for `qti-simple-choice` elements.
1405
+ *
1406
+ * @csspart prompt - Wrapper around the prompt slot.
1407
+ * @csspart slot - Wrapper around the default slot containing the choices.
1408
+ * @csspart message - Live validation message region (role="alert").
1409
+ */
1410
+ declare class QtiChoiceInteraction extends QtiChoiceInteraction_base implements ChoicesInterface$1 {
1411
+ #private;
894
1412
  static styles: CSSResultGroup;
895
- connectedCallback(): void;
1413
+ /** @deprecated, use 'qti-orientation-horizontal' or 'qti-orientation-vertical' instead */
1414
+ orientation: Orientation;
896
1415
  render(): lit.TemplateResult<1>;
897
1416
  }
898
1417
  declare global {
899
1418
  interface HTMLElementTagNameMap {
900
- 'qti-associable-hotspot': QtiAssociableHotspot;
1419
+ 'qti-choice-interaction': QtiChoiceInteraction;
901
1420
  }
902
1421
  }
903
1422
 
904
- declare class QtiPrompt extends LitElement {
1423
+ declare const QtiAssociateInteraction_base: (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlottedSortable) & (abstract new (...args: any[]) => _qti_components_interactions_core_mixins_drag_drop_observables.DragDropSlotted) & typeof Interaction;
1424
+ /**
1425
+ * Drag-and-drop associate interaction: candidates pair associable choices.
1426
+ *
1427
+ * @slot prompt - The prompt shown above the choices.
1428
+ * @slot qti-simple-associable-choice - The associable choice sources.
1429
+ *
1430
+ * @csspart drags - Wrapper around the associable choice slot.
1431
+ * @csspart drops - The container holding all drop targets.
1432
+ * @csspart drop-row - Container for one left/right drop pair.
1433
+ * @csspart drop - Each individual drop target.
1434
+ * @csspart message - Live validation message region (role="alert").
1435
+ */
1436
+ declare class QtiAssociateInteraction extends QtiAssociateInteraction_base {
1437
+ #private;
905
1438
  static styles: CSSResultGroup;
1439
+ protected _childrenMap: Element[];
1440
+ protected _registerChoiceHandler: (event: CustomEvent) => void;
1441
+ constructor();
1442
+ protected _registerChoice(event: CustomEvent): void;
1443
+ protected getResponse(): string[];
1444
+ /**
1445
+ * How many associations the candidate has made.
1446
+ *
1447
+ * The mixin counts placed chips, which is right for gap-match — one chip in one gap is one
1448
+ * association — and wrong here. An association is a *pair*, so three associations are six chips,
1449
+ * and `max-associations="3"` compared 6 against 3 and declared the item invalid the moment it was
1450
+ * correctly filled in.
1451
+ *
1452
+ * A half-filled row is not an association yet, and `getResponse()` already knows that: it emits a
1453
+ * pair only when both sides hold a chip. Counting its entries counts associations by definition,
1454
+ * and keeps the number validation sees equal to the number the response reports.
1455
+ */
1456
+ totalAssociationsFromState(): number;
1457
+ getValue(val: string[]): string[];
906
1458
  render(): lit.TemplateResult<1>;
907
- connectedCallback(): void;
1459
+ protected updated(changedProperties: Map<string, unknown>): void;
1460
+ disconnectedCallback(): void;
908
1461
  }
909
1462
  declare global {
910
1463
  interface HTMLElementTagNameMap {
911
- 'qti-prompt': QtiPrompt;
1464
+ 'qti-associate-interaction': QtiAssociateInteraction;
912
1465
  }
913
1466
  }
914
1467
 
915
- export { type Orientation, QtiAssociableHotspot, QtiAssociateInteraction, QtiChoiceInteraction, QtiCustomInteraction, QtiEndAttemptInteraction, QtiExtendedTextInteraction, QtiGap, QtiGapImg, QtiGapMatchInteraction, QtiGapText, QtiGraphicAssociateInteraction, QtiGraphicGapMatchInteraction, QtiGraphicOrderInteraction, QtiHotspotChoice, QtiHotspotInteraction, QtiHottext, QtiHottextInteraction, QtiInlineChoice, QtiInlineChoiceInteraction, QtiMatchInteraction, QtiMediaInteraction, QtiOrderInteraction, QtiPortableCustomInteraction, QtiPositionObjectInteraction, QtiPositionObjectStage, QtiPrompt, QtiSelectPointInteraction, QtiSimpleAssociableChoice, QtiSimpleChoice, QtiSliderInteraction, QtiTextEntryInteraction, QtiUploadInteraction };
1468
+ declare const qtiInteractionElements: readonly [{
1469
+ readonly tag: "qti-associable-hotspot";
1470
+ readonly ctor: typeof QtiAssociableHotspot;
1471
+ }, {
1472
+ readonly tag: "qti-gap";
1473
+ readonly ctor: typeof QtiGap;
1474
+ }, {
1475
+ readonly tag: "qti-gap-img";
1476
+ readonly ctor: typeof QtiGapImg;
1477
+ }, {
1478
+ readonly tag: "qti-gap-text";
1479
+ readonly ctor: typeof QtiGapText;
1480
+ }, {
1481
+ readonly tag: "qti-hotspot-choice";
1482
+ readonly ctor: typeof QtiHotspotChoice;
1483
+ }, {
1484
+ readonly tag: "qti-hottext";
1485
+ readonly ctor: typeof QtiHottext;
1486
+ }, {
1487
+ readonly tag: "qti-inline-choice";
1488
+ readonly ctor: typeof QtiInlineChoice;
1489
+ }, {
1490
+ readonly tag: "qti-prompt";
1491
+ readonly ctor: typeof QtiPrompt;
1492
+ }, {
1493
+ readonly tag: "qti-simple-associable-choice";
1494
+ readonly ctor: typeof QtiSimpleAssociableChoice;
1495
+ }, {
1496
+ readonly tag: "qti-simple-choice";
1497
+ readonly ctor: typeof QtiSimpleChoice;
1498
+ }, {
1499
+ readonly tag: "qti-associate-interaction";
1500
+ readonly ctor: typeof QtiAssociateInteraction;
1501
+ }, {
1502
+ readonly tag: "qti-choice-interaction";
1503
+ readonly ctor: typeof QtiChoiceInteraction;
1504
+ }, {
1505
+ readonly tag: "qti-custom-interaction";
1506
+ readonly ctor: typeof QtiCustomInteraction;
1507
+ }, {
1508
+ readonly tag: "qti-end-attempt-interaction";
1509
+ readonly ctor: typeof QtiEndAttemptInteraction;
1510
+ }, {
1511
+ readonly tag: "qti-extended-text-interaction";
1512
+ readonly ctor: typeof QtiExtendedTextInteraction;
1513
+ }, {
1514
+ readonly tag: "qti-gap-match-interaction";
1515
+ readonly ctor: typeof QtiGapMatchInteraction;
1516
+ }, {
1517
+ readonly tag: "qti-graphic-associate-interaction";
1518
+ readonly ctor: typeof QtiGraphicAssociateInteraction;
1519
+ }, {
1520
+ readonly tag: "qti-graphic-gap-match-interaction";
1521
+ readonly ctor: typeof QtiGraphicGapMatchInteraction;
1522
+ }, {
1523
+ readonly tag: "qti-graphic-order-interaction";
1524
+ readonly ctor: typeof QtiGraphicOrderInteraction;
1525
+ }, {
1526
+ readonly tag: "qti-hotspot-interaction";
1527
+ readonly ctor: typeof QtiHotspotInteraction;
1528
+ }, {
1529
+ readonly tag: "qti-hottext-interaction";
1530
+ readonly ctor: typeof QtiHottextInteraction;
1531
+ }, {
1532
+ readonly tag: "qti-inline-choice-interaction";
1533
+ readonly ctor: typeof QtiInlineChoiceInteraction;
1534
+ }, {
1535
+ readonly tag: "qti-match-interaction";
1536
+ readonly ctor: typeof QtiMatchInteraction;
1537
+ }, {
1538
+ readonly tag: "qti-media-interaction";
1539
+ readonly ctor: typeof QtiMediaInteraction;
1540
+ }, {
1541
+ readonly tag: "qti-order-interaction";
1542
+ readonly ctor: typeof QtiOrderInteraction;
1543
+ }, {
1544
+ readonly tag: "qti-portable-custom-interaction";
1545
+ readonly ctor: typeof QtiPortableCustomInteraction;
1546
+ }, {
1547
+ readonly tag: "qti-portable-custom-interaction-test";
1548
+ readonly ctor: typeof _qti_components_portable_custom_interaction_qti_portable_custom_test_interaction_js.QtiPortableCustomInteractionTest;
1549
+ }, {
1550
+ readonly tag: "qti-position-object-interaction";
1551
+ readonly ctor: typeof QtiPositionObjectInteraction;
1552
+ }, {
1553
+ readonly tag: "qti-position-object-stage";
1554
+ readonly ctor: typeof QtiPositionObjectStage;
1555
+ }, {
1556
+ readonly tag: "qti-select-point-interaction";
1557
+ readonly ctor: typeof QtiSelectPointInteraction;
1558
+ }, {
1559
+ readonly tag: "qti-slider-interaction";
1560
+ readonly ctor: typeof QtiSliderInteraction;
1561
+ }, {
1562
+ readonly tag: "qti-text-entry-interaction";
1563
+ readonly ctor: typeof QtiTextEntryInteraction;
1564
+ }, {
1565
+ readonly tag: "qti-upload-interaction";
1566
+ readonly ctor: typeof QtiUploadInteraction;
1567
+ }];
1568
+
1569
+ export { type Orientation, QtiAssociateInteraction, QtiChoiceInteraction, QtiCustomInteraction, QtiEndAttemptInteraction, QtiExtendedTextInteraction, QtiGapMatchInteraction, QtiGraphicAssociateInteraction, QtiGraphicGapMatchInteraction, QtiGraphicOrderInteraction, QtiHotspotInteraction, QtiHottextInteraction, QtiInlineChoiceInteraction, QtiMatchInteraction, QtiMediaInteraction, QtiOrderInteraction, QtiPortableCustomInteraction, QtiPositionObjectInteraction, QtiPositionObjectStage, QtiSelectPointInteraction, QtiSliderInteraction, QtiTextEntryInteraction, QtiUploadInteraction, qtiInteractionElements };