@citolab/qti-components 8.1.0 → 9.0.0

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 (63) hide show
  1. package/cdn/index.global.js +1 -1
  2. package/cdn/index.js +288 -182
  3. package/dist/base.d.ts +5 -5
  4. package/dist/base.js +1 -1
  5. package/dist/{chunk-TXIB3SKC.js → chunk-3MQNPN7A.js} +3 -3
  6. package/dist/{chunk-6V3A7NQP.js → chunk-3NPCS4IT.js} +2 -2
  7. package/dist/{chunk-MK2I3MQB.js → chunk-3VQSUWCK.js} +175 -15
  8. package/dist/chunk-3VQSUWCK.js.map +1 -0
  9. package/dist/{chunk-4XR2JHCP.js → chunk-5BXJRO5O.js} +1816 -551
  10. package/dist/chunk-5BXJRO5O.js.map +1 -0
  11. package/dist/{chunk-NZLW6EX7.js → chunk-DXEWBTJB.js} +2 -2
  12. package/dist/{chunk-Q52IJELT.js → chunk-GBDTBHUQ.js} +602 -263
  13. package/dist/chunk-GBDTBHUQ.js.map +1 -0
  14. package/dist/chunk-KCK27QBP.js +11 -0
  15. package/dist/chunk-KCK27QBP.js.map +1 -0
  16. package/dist/chunk-MKZ374OJ.js +179 -0
  17. package/dist/chunk-MKZ374OJ.js.map +1 -0
  18. package/dist/{chunk-3IACYIU2.js → chunk-RT6WZ3P7.js} +2 -2
  19. package/dist/chunk-TLTYXWW7.js +7 -0
  20. package/dist/chunk-TLTYXWW7.js.map +1 -0
  21. package/dist/{chunk-EKXZI26R.js → chunk-WCWJPIUQ.js} +58 -6
  22. package/dist/chunk-WCWJPIUQ.js.map +1 -0
  23. package/dist/{chunk-6XJUP55A.js → chunk-WKWCOV5P.js} +3 -3
  24. package/dist/chunk-WKWCOV5P.js.map +1 -0
  25. package/dist/{chunk-CF3DXJWM.js → chunk-WTV7NQHO.js} +731 -715
  26. package/dist/chunk-WTV7NQHO.js.map +1 -0
  27. package/dist/{computed.types.d-DpKIYO6e.d.ts → computed.types.d-CJarqC6s.d.ts} +12 -0
  28. package/dist/corrections.d.ts +14 -4
  29. package/dist/corrections.js +82 -7
  30. package/dist/corrections.js.map +1 -1
  31. package/dist/elements.d.ts +1 -1
  32. package/dist/elements.js +3 -3
  33. package/dist/index.d.ts +5 -5
  34. package/dist/index.js +26 -24
  35. package/dist/interactions.js +14 -15
  36. package/dist/item.css +81 -0
  37. package/dist/item.d.ts +1 -1
  38. package/dist/item.js +4 -4
  39. package/dist/loader.d.ts +1 -1
  40. package/dist/processing.d.ts +29 -3
  41. package/dist/processing.js +3 -2
  42. package/dist/qti-components-jsx.d.ts +7883 -7250
  43. package/dist/{qti-condition-expression.d-aMvBvpc6.d.ts → qti-condition-expression.d-CYwXOUb1.d.ts} +1 -1
  44. package/dist/{qti-expression.d-BietT_8b.d.ts → qti-expression.d-B_-m9emA.d.ts} +11 -1
  45. package/dist/{qti-feedback.d-DZbad0RN.d.ts → qti-feedback.d-B1EIF-fU.d.ts} +1 -0
  46. package/dist/{qti-test.d-_YAlhDbt.d.ts → qti-test.d-C6lCEMRB.d.ts} +38 -3
  47. package/dist/test.d.ts +5 -5
  48. package/dist/test.js +7 -5
  49. package/package.json +9 -9
  50. package/dist/chunk-4XR2JHCP.js.map +0 -1
  51. package/dist/chunk-6XJUP55A.js.map +0 -1
  52. package/dist/chunk-CF3DXJWM.js.map +0 -1
  53. package/dist/chunk-EKXZI26R.js.map +0 -1
  54. package/dist/chunk-IXPDMYKH.js +0 -1420
  55. package/dist/chunk-IXPDMYKH.js.map +0 -1
  56. package/dist/chunk-IYC7LZV6.js +0 -7
  57. package/dist/chunk-IYC7LZV6.js.map +0 -1
  58. package/dist/chunk-MK2I3MQB.js.map +0 -1
  59. package/dist/chunk-Q52IJELT.js.map +0 -1
  60. /package/dist/{chunk-TXIB3SKC.js.map → chunk-3MQNPN7A.js.map} +0 -0
  61. /package/dist/{chunk-6V3A7NQP.js.map → chunk-3NPCS4IT.js.map} +0 -0
  62. /package/dist/{chunk-NZLW6EX7.js.map → chunk-DXEWBTJB.js.map} +0 -0
  63. /package/dist/{chunk-3IACYIU2.js.map → chunk-RT6WZ3P7.js.map} +0 -0
@@ -2,10 +2,10 @@ import {
2
2
  QtiTest,
3
3
  TestCheckItem,
4
4
  TestNavigation
5
- } from "./chunk-Q52IJELT.js";
5
+ } from "./chunk-GBDTBHUQ.js";
6
6
  import {
7
7
  QtiAssessmentItem
8
- } from "./chunk-6XJUP55A.js";
8
+ } from "./chunk-WKWCOV5P.js";
9
9
  import {
10
10
  QtiAssociateInteraction,
11
11
  QtiChoiceInteraction,
@@ -28,10 +28,10 @@ import {
28
28
  QtiSimpleChoice,
29
29
  QtiSliderInteraction,
30
30
  QtiTextEntryInteraction
31
- } from "./chunk-4XR2JHCP.js";
31
+ } from "./chunk-5BXJRO5O.js";
32
32
  import {
33
33
  QtiItem
34
- } from "./chunk-TXIB3SKC.js";
34
+ } from "./chunk-3MQNPN7A.js";
35
35
  import {
36
36
  watch
37
37
  } from "./chunk-4DB4SC5K.js";
@@ -41,577 +41,13 @@ import {
41
41
  computedItemContext,
42
42
  configContext,
43
43
  responseAttributeConverter
44
- } from "./chunk-EKXZI26R.js";
45
-
46
- // ../qti-corrections/dist/mixins/correct-response.mixin.js
47
- import { property, state } from "lit/decorators.js";
48
- var __decorate = function(decorators, target, key, desc) {
49
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
50
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
51
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
52
- return c > 3 && r && Object.defineProperty(target, key, r), r;
53
- };
54
- var Correctness;
55
- (function(Correctness2) {
56
- Correctness2["Correct"] = "correct";
57
- Correctness2["PartiallyCorrect"] = "partially-correct";
58
- Correctness2["Incorrect"] = "incorrect";
59
- })(Correctness || (Correctness = {}));
60
- var CorrectResponseMixin = (superClass) => {
61
- class CorrectResponseMixinClass extends superClass {
62
- constructor() {
63
- super(...arguments);
64
- this.showCorrectResponse = false;
65
- this._handleShowCorrectResponseChange = (_, show) => {
66
- this.toggleInternalCorrectResponse(show);
67
- };
68
- this.showFullCorrectResponse = false;
69
- this._handleShowFullCorrectResponseChange = (_, show) => {
70
- this.toggleFullCorrectResponse(show);
71
- };
72
- this.showCandidateCorrection = false;
73
- this._handleShowCandidateCorrectionChange = (_, show) => {
74
- this.toggleCandidateCorrection(show);
75
- };
76
- this._correctResponse = null;
77
- }
78
- /**
79
- * The correct response for this interaction. Can be set as a comma-separated
80
- * string via attribute or as string/string[] via property.
81
- *
82
- * @example
83
- * ```html
84
- * <qti-choice-interaction correct-response="A,B">
85
- * ```
86
- */
87
- set correctResponseAttr(val) {
88
- this._correctResponse = val;
89
- }
90
- get correctResponseAttr() {
91
- return this._correctResponse;
92
- }
93
- get isFullCorrectResponse() {
94
- return this._isFullCorrectResponse;
95
- }
96
- get registersWithItem() {
97
- return !this.isFullCorrectResponse && super.registersWithItem;
98
- }
99
- set isFullCorrectResponse(val) {
100
- this._isFullCorrectResponse = val;
101
- if (val) {
102
- this.setAttribute("inert", "");
103
- this.setAttribute("response-identifier", this.responseIdentifier + "_cr");
104
- this.setAttribute("answer-key", "");
105
- }
106
- }
107
- get correctResponse() {
108
- const responseVariable = this.responseVariable;
109
- if (responseVariable?.correctResponse) {
110
- return responseVariable.correctResponse;
111
- }
112
- return this._correctResponse;
113
- }
114
- set correctResponse(val) {
115
- const oldVal = this._correctResponse;
116
- this._correctResponse = val;
117
- if (val === null || val === void 0) {
118
- this.removeAttribute("correct-response");
119
- } else {
120
- this.setAttribute("correct-response", Array.isArray(val) ? val.join(",") : val);
121
- }
122
- this.requestUpdate("_correctResponse", oldVal);
123
- }
124
- // ─── correctness getter ───────────────────────────────────────────────────
125
- get correctness() {
126
- const correctResponse = this.correctResponse;
127
- if (!correctResponse)
128
- return null;
129
- const currentResponse = this.response;
130
- if (currentResponse === null || currentResponse === void 0 || currentResponse === "" || Array.isArray(currentResponse) && currentResponse.length === 0) {
131
- return null;
132
- }
133
- const correctArr = Array.isArray(correctResponse) ? correctResponse : [correctResponse];
134
- const responseArr = Array.isArray(currentResponse) ? currentResponse : [currentResponse];
135
- const filteredResponseArr = responseArr.filter((r) => r !== "");
136
- if (filteredResponseArr.length === 0)
137
- return null;
138
- const correctCount = filteredResponseArr.filter((r) => correctArr.includes(r)).length;
139
- const incorrectCount = filteredResponseArr.filter((r) => !correctArr.includes(r)).length;
140
- if (correctCount === correctArr.length && incorrectCount === 0 && filteredResponseArr.length === correctArr.length) {
141
- return Correctness.Correct;
142
- }
143
- if (correctCount > 0 && (correctCount < correctArr.length || incorrectCount > 0)) {
144
- return Correctness.PartiallyCorrect;
145
- }
146
- return Correctness.Incorrect;
147
- }
148
- // ─── correctionPart ───────────────────────────────────────────────────────
149
- get correctionPart() {
150
- return "correction";
151
- }
152
- // ─── toggle methods ───────────────────────────────────────────────────────
153
- toggleCorrectResponse(show) {
154
- const correctionConfig = this.configContext;
155
- const correctResponseMode = correctionConfig?.correctResponseMode || "internal";
156
- if (correctResponseMode === "full") {
157
- this.toggleFullCorrectResponse(show);
158
- } else {
159
- this.toggleInternalCorrectResponse(show);
160
- }
161
- }
162
- /**
163
- * Whether the full correct response is withheld from a candidate who is already correct.
164
- *
165
- * Withheld by default, unless the item configures `fullCorrectResponseOnlyWhenIncorrect: false`
166
- * — the behaviour `show-full-correct-response` has always had, on the reasoning that a correct
167
- * answer already *is* the key.
168
- *
169
- * An interaction that routes its internal mode here overrides this to false: there, the caller
170
- * asked to show the correct response, and silently showing nothing is worse than showing the
171
- * candidate the answer they already gave.
172
- */
173
- get withholdsFullCorrectResponseWhenCorrect() {
174
- return this.configContext?.fullCorrectResponseOnlyWhenIncorrect !== false;
175
- }
176
- async toggleFullCorrectResponse(show) {
177
- const nextSibling = this.nextSibling;
178
- const nextSiblingIsFullCorrectResponse = nextSibling instanceof HTMLDivElement && nextSibling?.classList.contains("full-correct-response");
179
- const correctResponse = this.correctResponse;
180
- if (!correctResponse) {
181
- return;
182
- }
183
- const showFullCorrectResponse = show && (!this.withholdsFullCorrectResponseWhenCorrect || this.correctness !== Correctness.Correct);
184
- if (!showFullCorrectResponse) {
185
- if (!nextSiblingIsFullCorrectResponse) {
186
- return;
187
- }
188
- this.parentElement?.removeChild(nextSibling);
189
- return;
190
- }
191
- if (nextSiblingIsFullCorrectResponse) {
192
- return;
193
- }
194
- const clone = this.cloneNode(true);
195
- clone.removeAttribute("show-full-correct-response");
196
- clone.removeAttribute("show-correct-response");
197
- clone.removeAttribute("show-candidate-correction");
198
- const containerDiv = document.createElement("div");
199
- containerDiv.classList.add("full-correct-response");
200
- if (this.isInline) {
201
- containerDiv.classList.add("full-correct-response-inline");
202
- } else {
203
- containerDiv.classList.add("full-correct-response-block");
204
- }
205
- containerDiv.role = "full-correct-response";
206
- containerDiv.appendChild(clone);
207
- clone.isFullCorrectResponse = true;
208
- this.parentElement?.insertBefore(containerDiv, this.nextSibling);
209
- await clone.updateComplete;
210
- clone.response = Array.isArray(correctResponse) ? [...correctResponse] : correctResponse;
211
- }
212
- toggleInternalCorrectResponse(show) {
213
- this._internals.states.delete("show-correct-response");
214
- if (show && this.correctResponse) {
215
- this._internals.states.add("show-correct-response");
216
- }
217
- }
218
- toggleCandidateCorrection(show) {
219
- if (!show) {
220
- return;
221
- }
222
- }
223
- // ─── Lifecycle ────────────────────────────────────────────────────────────
224
- firstUpdated() {
225
- super.firstUpdated();
226
- if (this.isFullCorrectResponse) {
227
- return;
228
- }
229
- if (this.showCorrectResponse) {
230
- this.toggleInternalCorrectResponse(true);
231
- }
232
- if (this.showFullCorrectResponse) {
233
- this.toggleFullCorrectResponse(true);
234
- }
235
- }
236
- }
237
- __decorate([
238
- property({
239
- attribute: "correct-response",
240
- reflect: true,
241
- converter: responseAttributeConverter({ emptyAs: null })
242
- })
243
- ], CorrectResponseMixinClass.prototype, "correctResponseAttr", null);
244
- __decorate([
245
- property({ type: Boolean, attribute: "show-correct-response", reflect: true })
246
- ], CorrectResponseMixinClass.prototype, "showCorrectResponse", void 0);
247
- __decorate([
248
- watch("showCorrectResponse", { waitUntilFirstUpdate: true })
249
- ], CorrectResponseMixinClass.prototype, "_handleShowCorrectResponseChange", void 0);
250
- __decorate([
251
- property({ type: Boolean, attribute: "show-full-correct-response", reflect: true })
252
- ], CorrectResponseMixinClass.prototype, "showFullCorrectResponse", void 0);
253
- __decorate([
254
- watch("showFullCorrectResponse", { waitUntilFirstUpdate: true })
255
- ], CorrectResponseMixinClass.prototype, "_handleShowFullCorrectResponseChange", void 0);
256
- __decorate([
257
- property({ type: Boolean, attribute: "show-candidate-correction", reflect: true })
258
- ], CorrectResponseMixinClass.prototype, "showCandidateCorrection", void 0);
259
- __decorate([
260
- watch("showCandidateCorrection", { waitUntilFirstUpdate: true })
261
- ], CorrectResponseMixinClass.prototype, "_handleShowCandidateCorrectionChange", void 0);
262
- __decorate([
263
- state()
264
- ], CorrectResponseMixinClass.prototype, "_isFullCorrectResponse", void 0);
265
- __decorate([
266
- state()
267
- ], CorrectResponseMixinClass.prototype, "_correctResponse", void 0);
268
- return CorrectResponseMixinClass;
269
- };
270
-
271
- // ../qti-corrections/dist/styles/correction.styles.js
272
- import { css } from "lit";
273
- var correctionPart = css`
274
- /* Nothing at all until the item judges this element. */
275
- [part~='correction'] {
276
- display: none;
277
- }
278
-
279
- [part~='correction-correct'],
280
- [part~='correction-incorrect'],
281
- [part~='correction-partially-correct'] {
282
- display: inline-flex;
283
- flex: 0 0 auto;
284
-
285
- /*
286
- * The badge aligns ITSELF, and that is the whole of the vertical story.
287
- *
288
- * It is a flex item with a definite height, so left alone its cross-axis position is decided by
289
- * whatever its host says — and the hosts disagree: qti-simple-associable-choice defaults to
290
- * align-items: normal, and qti-gap-text gates center behind :not([part~='drag']), so the
291
- * same chip centred its badge in the bank and top-aligned it once placed. align-self settles it
292
- * from the badge's side, in one line, without touching a single container.
293
- *
294
- * This replaces an align-items/justify-content: center pair that had never done anything: the
295
- * badge is empty — a mask painted over a background — so centring its CONTENTS centres nothing.
296
- */
297
- align-self: center;
298
-
299
- box-sizing: border-box;
300
- width: var(--qti-correction-size, 1em);
301
- height: var(--qti-correction-size, 1em);
302
- margin-left: var(--qti-glyph-gap, 0.5em);
303
-
304
- pointer-events: none;
305
- }
306
- `;
307
-
308
- // ../qti-corrections/dist/mixins/candidate-correction.mixin.js
309
- import { state as state2 } from "lit/decorators.js";
310
- var __decorate2 = function(decorators, target, key, desc) {
311
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
312
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
313
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
314
- return c > 3 && r && Object.defineProperty(target, key, r), r;
315
- };
316
- var CandidateCorrectionMixin = (superClass) => {
317
- class CandidateCorrectionMixinClass extends CorrectResponseMixin(superClass) {
318
- constructor() {
319
- super(...arguments);
320
- this._candidateCorrection = null;
321
- }
322
- get correctionPart() {
323
- return this._candidateCorrection ? `correction correction-${this._candidateCorrection}` : "correction";
324
- }
325
- toggleCandidateCorrection(show) {
326
- if (this.showCandidateCorrection !== show) {
327
- this.showCandidateCorrection = show;
328
- }
329
- super.toggleCandidateCorrection(show);
330
- const internals = this._internals;
331
- internals.states.delete("candidate-correct");
332
- internals.states.delete("candidate-partially-correct");
333
- internals.states.delete("candidate-incorrect");
334
- let verdict = null;
335
- if (show) {
336
- if (this.correctness === Correctness.Correct) {
337
- internals.states.add("candidate-correct");
338
- verdict = "correct";
339
- }
340
- if (this.correctness === Correctness.PartiallyCorrect) {
341
- internals.states.add("candidate-partially-correct");
342
- verdict = "partially-correct";
343
- }
344
- if (this.correctness === Correctness.Incorrect) {
345
- internals.states.add("candidate-incorrect");
346
- verdict = "incorrect";
347
- }
348
- }
349
- if (this._candidateCorrection !== verdict) {
350
- this._candidateCorrection = verdict;
351
- }
352
- }
353
- connectedCallback() {
354
- super.connectedCallback?.();
355
- queueMicrotask(() => {
356
- if (!this.isConnected || this.isFullCorrectResponse) {
357
- return;
358
- }
359
- if (this.showCandidateCorrection) {
360
- this.toggleCandidateCorrection(true);
361
- }
362
- });
363
- }
364
- }
365
- __decorate2([
366
- state2()
367
- ], CandidateCorrectionMixinClass.prototype, "_candidateCorrection", void 0);
368
- return CandidateCorrectionMixinClass;
369
- };
370
-
371
- // ../qti-corrections/dist/mixins/choice-correction.mixin.js
372
- var ChoiceCorrectionMixin = (superClass) => {
373
- class ChoiceCorrectionMixinClass extends CandidateCorrectionMixin(superClass) {
374
- toggleInternalCorrectResponse(show) {
375
- super.toggleInternalCorrectResponse(show);
376
- const correctResponse = this.correctResponse;
377
- const correctResponses = correctResponse ? Array.isArray(correctResponse) ? correctResponse : [correctResponse] : [];
378
- for (const choice of this._choiceElements) {
379
- choice.internals.states.delete("correct-response");
380
- choice.internals.states.delete("incorrect-response");
381
- if (show && correctResponses.length > 0) {
382
- choice.internals.states.add(correctResponses.includes(choice.identifier) ? "correct-response" : "incorrect-response");
383
- }
384
- }
385
- }
386
- toggleCandidateCorrection(show) {
387
- super.toggleCandidateCorrection(show);
388
- for (const choice of this._choiceElements) {
389
- choice.candidateCorrection = null;
390
- }
391
- if (!show || !this.correctResponse) {
392
- return;
393
- }
394
- const correctResponses = Array.isArray(this.correctResponse) ? this.correctResponse : [this.correctResponse];
395
- const candidateResponses = Array.isArray(this.response) ? this.response : this.response ? [this.response] : [];
396
- for (const choice of this._choiceElements) {
397
- if (!candidateResponses.includes(choice.identifier)) {
398
- continue;
399
- }
400
- choice.candidateCorrection = correctResponses.includes(choice.identifier) ? "correct" : "incorrect";
401
- }
402
- }
403
- }
404
- return ChoiceCorrectionMixinClass;
405
- };
406
-
407
- // ../qti-corrections/dist/elements/qti-gap-text-correction.js
408
- import { html } from "lit";
409
-
410
- // ../qti-corrections/dist/mixins/active-element-correction.mixin.js
411
- var ActiveElementCorrectionMixin = (superClass) => {
412
- class ActiveElementCorrectionMixinClass extends superClass {
413
- #candidateCorrection = null;
414
- get candidateCorrection() {
415
- return this.#candidateCorrection;
416
- }
417
- set candidateCorrection(value) {
418
- if (this.#candidateCorrection === value)
419
- return;
420
- const previous = this.#candidateCorrection;
421
- this.#candidateCorrection = value;
422
- const states = this.internals.states;
423
- states.delete("candidate-correct");
424
- states.delete("candidate-incorrect");
425
- states.delete("candidate-partially-correct");
426
- if (value)
427
- states.add(`candidate-${value}`);
428
- this.requestUpdate("candidateCorrection", previous);
429
- }
430
- get correctionPart() {
431
- return this.#candidateCorrection ? `correction correction-${this.#candidateCorrection}` : "correction";
432
- }
433
- }
434
- return ActiveElementCorrectionMixinClass;
435
- };
436
-
437
- // ../qti-corrections/dist/elements/qti-gap-text-correction.js
438
- var QtiGapTextCorrection = class extends ActiveElementCorrectionMixin(QtiGapText) {
439
- static {
440
- this.styles = [QtiGapText.styles, correctionPart];
441
- }
442
- render() {
443
- return html`<div part="control"></div>
444
- <slot part="label"></slot>
445
- <span part=${this.correctionPart} aria-hidden="true"></span>`;
446
- }
447
- };
448
-
449
- // ../qti-corrections/dist/elements/qti-hotspot-choice-correction.js
450
- import { property as property2 } from "lit/decorators.js";
451
- var __decorate3 = function(decorators, target, key, desc) {
452
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
453
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
454
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
455
- return c > 3 && r && Object.defineProperty(target, key, r), r;
456
- };
457
- var QtiHotspotChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiHotspotChoice) {
458
- constructor() {
459
- super(...arguments);
460
- this.orderCorrect = null;
461
- }
462
- };
463
- __decorate3([
464
- property2({ attribute: "aria-ordercorrectvalue", type: Number, reflect: true })
465
- ], QtiHotspotChoiceCorrection.prototype, "orderCorrect", void 0);
466
-
467
- // ../qti-corrections/dist/elements/qti-hottext-correction.js
468
- import { html as html2 } from "lit";
469
- var QtiHottextCorrection = class extends ActiveElementCorrectionMixin(QtiHottext) {
470
- static {
471
- this.styles = [QtiHottext.styles, correctionPart];
472
- }
473
- render() {
474
- return html2`<div part="control"><div part="control-mark"></div></div>
475
- <slot part="label"></slot>
476
- <span part=${this.correctionPart} aria-hidden="true"></span>`;
477
- }
478
- };
479
-
480
- // ../qti-corrections/dist/elements/qti-simple-associable-choice-correction.js
481
- import { html as html3 } from "lit";
482
- import { repeat } from "lit/directives/repeat.js";
483
- var QtiSimpleAssociableChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiSimpleAssociableChoice) {
484
- static {
485
- this.styles = [QtiSimpleAssociableChoice.styles, correctionPart];
486
- }
487
- render() {
488
- return html3`
489
- <div part="control"></div>
490
- <slot part="label"></slot>
491
- <span part=${this.correctionPart} aria-hidden="true"></span>
492
- <div part="drop">
493
- ${repeat(this.drags, (node) => node.getAttribute("identifier"), (node) => node)}
494
- </div>
495
- `;
496
- }
497
- };
498
-
499
- // ../qti-corrections/dist/elements/qti-simple-choice-correction.js
500
- import { html as html4, nothing } from "lit";
501
- var QtiSimpleChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiSimpleChoice) {
502
- static {
503
- this.styles = [QtiSimpleChoice.styles, correctionPart];
504
- }
505
- render() {
506
- return html4`<div part="control" tabindex="0"><div part="control-mark"></div></div>
507
- ${this.marker ? html4`<div id="label" part="marker">${this.marker}</div>` : nothing}
508
- <slot part="label"></slot>
509
- <span part=${this.correctionPart} aria-hidden="true"></span>`;
510
- }
511
- };
512
-
513
- // ../qti-corrections/dist/components/qti-assessment-item-correction.js
514
- var QtiAssessmentItemCorrection = class extends QtiAssessmentItem {
515
- showCorrectResponse(show) {
516
- for (const interaction of this.interactionElements) {
517
- interaction.toggleCorrectResponse?.(show);
518
- }
519
- this.updateControlState("item-show-correct-response", show);
520
- }
521
- showCandidateCorrection(show) {
522
- for (const interaction of this.interactionElements) {
523
- interaction.toggleCandidateCorrection?.(show);
524
- }
525
- this.updateControlState("item-show-candidate-correction", show);
526
- }
527
- afterResponseVariableUpdated() {
528
- this.showCandidateCorrection(false);
529
- }
530
- updateControlState(selector, shown) {
531
- let root = this.getRootNode();
532
- while (true) {
533
- root.querySelectorAll(selector).forEach((control) => control.shown = shown);
534
- if (!(root instanceof ShadowRoot))
535
- return;
536
- root = root.host.getRootNode();
537
- }
538
- }
539
- };
540
-
541
- // ../qti-corrections/dist/components/qti-item-correction.js
542
- var QtiItemCorrection = class extends QtiItem {
543
- #onShowCorrectResponse = (event) => {
544
- const show = event.detail;
545
- this.assessmentItem?.showCorrectResponse?.(show);
546
- this.updateControlState("item-show-correct-response", show);
547
- };
548
- #onShowCandidateCorrection = (event) => {
549
- const show = event.detail;
550
- this.assessmentItem?.showCandidateCorrection?.(show);
551
- this.updateControlState("item-show-candidate-correction", show);
552
- };
553
- #onSwitchCorrectResponseMode = (event) => {
554
- this.assessmentItem?.showCorrectResponse?.(false);
555
- this.configContext = {
556
- ...this.configContext,
557
- correctResponseMode: event.detail
558
- };
559
- };
560
- constructor() {
561
- super();
562
- this.addEventListener("item-show-correct-response", this.#onShowCorrectResponse);
563
- this.addEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
564
- this.addEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
565
- }
566
- updateControlState(selector, shown) {
567
- this.querySelectorAll(selector).forEach((control) => control.shown = shown);
568
- }
569
- disconnectedCallback() {
570
- this.removeEventListener("item-show-correct-response", this.#onShowCorrectResponse);
571
- this.removeEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
572
- this.removeEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
573
- super.disconnectedCallback();
574
- }
575
- };
576
-
577
- // ../qti-corrections/dist/components/test-correction-elements.js
578
- var TestNavigationCorrection = class extends TestNavigation {
579
- #onShowCorrectResponse = (event) => {
580
- this.activeAssessmentItem?.showCorrectResponse?.(event.detail);
581
- };
582
- #onShowCandidateCorrection = (event) => {
583
- this.activeAssessmentItem?.showCandidateCorrection?.(event.detail);
584
- };
585
- constructor() {
586
- super();
587
- this.addEventListener("test-show-correct-response", this.#onShowCorrectResponse);
588
- this.addEventListener("test-show-candidate-correction", this.#onShowCandidateCorrection);
589
- }
590
- disconnectedCallback() {
591
- this.removeEventListener("test-show-correct-response", this.#onShowCorrectResponse);
592
- this.removeEventListener("test-show-candidate-correction", this.#onShowCandidateCorrection);
593
- super.disconnectedCallback();
594
- }
595
- };
596
- var QtiTestCorrection = class extends QtiTest {
597
- updateAssessmentItemView(assessmentItem, view) {
598
- assessmentItem.showCorrectResponse?.(view === "scorer");
599
- }
600
- };
601
- var TestCheckItemCorrection = class extends TestCheckItem {
602
- constructor() {
603
- super();
604
- this.addEventListener("click", () => {
605
- this.dispatchEvent(new CustomEvent("test-show-correct-response", { detail: true, bubbles: true }));
606
- });
607
- }
608
- };
44
+ } from "./chunk-WCWJPIUQ.js";
609
45
 
610
46
  // ../qti-corrections/dist/components/item-correct-response-mode/item-correct-response-mode.js
611
- import { html as html5, LitElement } from "lit";
612
- import { property as property3, state as state3 } from "lit/decorators.js";
47
+ import { html, LitElement } from "lit";
48
+ import { property, state } from "lit/decorators.js";
613
49
  import { consume } from "@lit/context";
614
- var __decorate4 = function(decorators, target, key, desc) {
50
+ var __decorate = function(decorators, target, key, desc) {
615
51
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
616
52
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
617
53
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -633,7 +69,7 @@ var ItemCorrectResponseMode = class extends LitElement {
633
69
  }));
634
70
  }
635
71
  render() {
636
- return html5`
72
+ return html`
637
73
  <label part="label" for="modeSelect">${this.label}</label>
638
74
  <select
639
75
  part="select"
@@ -643,31 +79,31 @@ var ItemCorrectResponseMode = class extends LitElement {
643
79
  this.#switchMode(el.value);
644
80
  }}
645
81
  >
646
- ${Object.keys(this._options).map((value) => html5`<option value="${value}" ?selected=${value === this.itemContext?.correctResponseMode}>
82
+ ${Object.keys(this._options).map((value) => html`<option value="${value}" ?selected=${value === this.itemContext?.correctResponseMode}>
647
83
  ${this._options[value]}
648
84
  </option>`)}
649
85
  </select>
650
86
  `;
651
87
  }
652
88
  };
653
- __decorate4([
89
+ __decorate([
654
90
  consume({ context: configContext, subscribe: true })
655
91
  ], ItemCorrectResponseMode.prototype, "itemContext", void 0);
656
- __decorate4([
657
- property3({ type: String })
92
+ __decorate([
93
+ property({ type: String })
658
94
  ], ItemCorrectResponseMode.prototype, "label", void 0);
659
- __decorate4([
660
- state3()
95
+ __decorate([
96
+ state()
661
97
  ], ItemCorrectResponseMode.prototype, "_options", void 0);
662
98
 
663
99
  // ../qti-corrections/dist/components/item-show-candidate-correction/item-show-candidate-correction.js
664
- import { css as css3, html as html6, LitElement as LitElement2 } from "lit";
665
- import { property as property4 } from "lit/decorators.js";
100
+ import { css as css2, html as html2, LitElement as LitElement2 } from "lit";
101
+ import { property as property2 } from "lit/decorators.js";
666
102
  import { consume as consume2 } from "@lit/context";
667
103
 
668
104
  // ../qti-corrections/dist/components/styles.js
669
- import { css as css2 } from "lit";
670
- var form = css2`
105
+ import { css } from "lit";
106
+ var form = css`
671
107
  display: inline-flex;
672
108
  align-items: center;
673
109
  cursor: pointer;
@@ -675,21 +111,21 @@ var form = css2`
675
111
  border-radius: 0.25rem;
676
112
  user-select: none;
677
113
  `;
678
- var btn = css2`
114
+ var btn = css`
679
115
  background-color: lightgray;
680
116
  ${form};
681
117
  `;
682
- var dis = css2`
118
+ var dis = css`
683
119
  cursor: not-allowed;
684
120
  opacity: 0.8;
685
121
  `;
686
- var ind = css2`
122
+ var ind = css`
687
123
  ${form};
688
124
  border: 1px solid gray;
689
125
  `;
690
126
 
691
127
  // ../qti-corrections/dist/components/item-show-candidate-correction/item-show-candidate-correction.js
692
- var __decorate5 = function(decorators, target, key, desc) {
128
+ var __decorate2 = function(decorators, target, key, desc) {
693
129
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
694
130
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
695
131
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -697,7 +133,7 @@ var __decorate5 = function(decorators, target, key, desc) {
697
133
  };
698
134
  var ItemShowCandidateCorrection = class extends LitElement2 {
699
135
  static {
700
- this.styles = css3`
136
+ this.styles = css2`
701
137
  :host {
702
138
  ${btn};
703
139
  }
@@ -743,33 +179,33 @@ var ItemShowCandidateCorrection = class extends LitElement2 {
743
179
  return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCandidateCorrectionText : this.showCandidateCorrectionText;
744
180
  }
745
181
  render() {
746
- return html6` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
182
+ return html2` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
747
183
  }
748
184
  };
749
- __decorate5([
185
+ __decorate2([
750
186
  consume2({ context: computedItemContext, subscribe: true })
751
187
  ], ItemShowCandidateCorrection.prototype, "computedContext", void 0);
752
- __decorate5([
753
- property4({ type: Boolean, reflect: true })
188
+ __decorate2([
189
+ property2({ type: Boolean, reflect: true })
754
190
  ], ItemShowCandidateCorrection.prototype, "shown", void 0);
755
- __decorate5([
756
- property4({ type: Boolean, reflect: true })
191
+ __decorate2([
192
+ property2({ type: Boolean, reflect: true })
757
193
  ], ItemShowCandidateCorrection.prototype, "disabled", void 0);
758
- __decorate5([
759
- property4({ type: String })
194
+ __decorate2([
195
+ property2({ type: String })
760
196
  ], ItemShowCandidateCorrection.prototype, "showCandidateCorrectionText", void 0);
761
- __decorate5([
762
- property4({ type: String })
197
+ __decorate2([
198
+ property2({ type: String })
763
199
  ], ItemShowCandidateCorrection.prototype, "hideCandidateCorrectionText", void 0);
764
- __decorate5([
765
- property4({ type: String })
200
+ __decorate2([
201
+ property2({ type: String })
766
202
  ], ItemShowCandidateCorrection.prototype, "noCorrectResponseText", void 0);
767
203
 
768
204
  // ../qti-corrections/dist/components/item-show-correct-response/item-show-correct-response.js
769
- import { css as css4, html as html7, LitElement as LitElement3 } from "lit";
770
- import { property as property5 } from "lit/decorators.js";
205
+ import { css as css3, html as html3, LitElement as LitElement3 } from "lit";
206
+ import { property as property3 } from "lit/decorators.js";
771
207
  import { consume as consume3 } from "@lit/context";
772
- var __decorate6 = function(decorators, target, key, desc) {
208
+ var __decorate3 = function(decorators, target, key, desc) {
773
209
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
774
210
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
775
211
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -787,7 +223,7 @@ var ItemShowCorrectResponse = class extends LitElement3 {
787
223
  this.#previousActiveItem = "";
788
224
  }
789
225
  static {
790
- this.styles = css4`
226
+ this.styles = css3`
791
227
  :host {
792
228
  ${btn};
793
229
  }
@@ -811,121 +247,552 @@ var ItemShowCorrectResponse = class extends LitElement3 {
811
247
  }
812
248
  this.disabled = !this.#hasCorrectResponse;
813
249
  }
814
- #toggleState() {
815
- if (this.disabled)
816
- return;
817
- this.dispatchEvent(new CustomEvent("item-show-correct-response", {
818
- detail: !this.shown,
819
- bubbles: true
820
- }));
250
+ #toggleState() {
251
+ if (this.disabled)
252
+ return;
253
+ this.dispatchEvent(new CustomEvent("item-show-correct-response", {
254
+ detail: !this.shown,
255
+ bubbles: true
256
+ }));
257
+ }
258
+ #getDisplayedText() {
259
+ return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
260
+ }
261
+ render() {
262
+ return html3` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
263
+ }
264
+ };
265
+ __decorate3([
266
+ consume3({ context: computedItemContext, subscribe: true })
267
+ ], ItemShowCorrectResponse.prototype, "computedContext", void 0);
268
+ __decorate3([
269
+ property3({ type: Boolean, reflect: true })
270
+ ], ItemShowCorrectResponse.prototype, "shown", void 0);
271
+ __decorate3([
272
+ property3({ type: Boolean, reflect: true })
273
+ ], ItemShowCorrectResponse.prototype, "disabled", void 0);
274
+ __decorate3([
275
+ property3({ type: String })
276
+ ], ItemShowCorrectResponse.prototype, "showCorrectText", void 0);
277
+ __decorate3([
278
+ property3({ type: String })
279
+ ], ItemShowCorrectResponse.prototype, "hideCorrectText", void 0);
280
+ __decorate3([
281
+ property3({ type: String })
282
+ ], ItemShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
283
+
284
+ // ../qti-corrections/dist/components/test-show-correct-response/test-show-correct-response.js
285
+ import { css as css4, html as html4, LitElement as LitElement4 } from "lit";
286
+ import { property as property4 } from "lit/decorators.js";
287
+ import { consume as consume4 } from "@lit/context";
288
+ var __decorate4 = function(decorators, target, key, desc) {
289
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
290
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
291
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
292
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
293
+ };
294
+ var TestShowCorrectResponse = class extends LitElement4 {
295
+ constructor() {
296
+ super(...arguments);
297
+ this.shown = false;
298
+ this.disabled = false;
299
+ this.showCorrectText = "Show correct response";
300
+ this.hideCorrectText = "Hide correct response";
301
+ this.noCorrectResponseText = "No correct response specified";
302
+ }
303
+ static {
304
+ this.styles = css4`
305
+ :host {
306
+ ${btn};
307
+ }
308
+ :host([disabled]) {
309
+ ${dis};
310
+ }
311
+ `;
312
+ }
313
+ #previousActiveItem;
314
+ // Store previous active item reference
315
+ willUpdate(_changedProperties) {
316
+ const activeItem = this.computedContext?.testParts.flatMap((testPart) => testPart.sections.flatMap((section) => section.items)).find((item) => item.active);
317
+ if (this.#previousActiveItem !== activeItem) {
318
+ this.shown = false;
319
+ this.#previousActiveItem = activeItem;
320
+ }
321
+ if (activeItem) {
322
+ const containsCorrectResponse = !!activeItem?.variables?.some((v) => v["correctResponse"]);
323
+ const containsMapping = !!activeItem?.variables?.some((v) => {
324
+ return v["mapping"]?.mapEntries?.length > 0 || v["areaMapping"]?.areaMapEntries?.length > 0;
325
+ });
326
+ this.disabled = !containsCorrectResponse && !containsMapping;
327
+ } else {
328
+ this.disabled = true;
329
+ }
330
+ }
331
+ #toggleState() {
332
+ if (this.disabled)
333
+ return;
334
+ this.shown = !this.shown;
335
+ this.dispatchEvent(new CustomEvent("test-show-correct-response", {
336
+ detail: this.shown,
337
+ bubbles: true
338
+ }));
339
+ }
340
+ #getDisplayedText() {
341
+ return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
342
+ }
343
+ render() {
344
+ return html4` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
345
+ }
346
+ };
347
+ __decorate4([
348
+ consume4({ context: computedContext, subscribe: true })
349
+ ], TestShowCorrectResponse.prototype, "computedContext", void 0);
350
+ __decorate4([
351
+ property4({ type: Boolean, reflect: true })
352
+ ], TestShowCorrectResponse.prototype, "shown", void 0);
353
+ __decorate4([
354
+ property4({ type: Boolean, reflect: true })
355
+ ], TestShowCorrectResponse.prototype, "disabled", void 0);
356
+ __decorate4([
357
+ property4({ type: String })
358
+ ], TestShowCorrectResponse.prototype, "showCorrectText", void 0);
359
+ __decorate4([
360
+ property4({ type: String })
361
+ ], TestShowCorrectResponse.prototype, "hideCorrectText", void 0);
362
+ __decorate4([
363
+ property4({ type: String })
364
+ ], TestShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
365
+
366
+ // ../qti-corrections/dist/styles/correction.styles.js
367
+ import { css as css5 } from "lit";
368
+ var correctionPart = css5`
369
+ /* Nothing at all until the item judges this element. */
370
+ [part~='correction'] {
371
+ display: none;
372
+ }
373
+
374
+ [part~='correction-correct'],
375
+ [part~='correction-incorrect'],
376
+ [part~='correction-partially-correct'] {
377
+ display: inline-flex;
378
+ flex: 0 0 auto;
379
+
380
+ /*
381
+ * The badge aligns ITSELF, and that is the whole of the vertical story.
382
+ *
383
+ * It is a flex item with a definite height, so left alone its cross-axis position is decided by
384
+ * whatever its host says — and the hosts disagree: qti-simple-associable-choice defaults to
385
+ * align-items: normal, and qti-gap-text gates center behind :not([part~='drag']), so the
386
+ * same chip centred its badge in the bank and top-aligned it once placed. align-self settles it
387
+ * from the badge's side, in one line, without touching a single container.
388
+ *
389
+ * This replaces an align-items/justify-content: center pair that had never done anything: the
390
+ * badge is empty — a mask painted over a background — so centring its CONTENTS centres nothing.
391
+ */
392
+ align-self: center;
393
+
394
+ box-sizing: border-box;
395
+ width: var(--qti-correction-size, 1em);
396
+ height: var(--qti-correction-size, 1em);
397
+ margin-left: var(--qti-glyph-gap, 0.5em);
398
+
399
+ pointer-events: none;
400
+ }
401
+ `;
402
+
403
+ // ../qti-corrections/dist/elements/qti-gap-text-correction.js
404
+ import { html as html5 } from "lit";
405
+
406
+ // ../qti-corrections/dist/mixins/active-element-correction.mixin.js
407
+ var ActiveElementCorrectionMixin = (superClass) => {
408
+ class ActiveElementCorrectionMixinClass extends superClass {
409
+ #candidateCorrection = null;
410
+ get candidateCorrection() {
411
+ return this.#candidateCorrection;
412
+ }
413
+ set candidateCorrection(value) {
414
+ if (this.#candidateCorrection === value)
415
+ return;
416
+ const previous = this.#candidateCorrection;
417
+ this.#candidateCorrection = value;
418
+ const states = this.internals.states;
419
+ states.delete("candidate-correct");
420
+ states.delete("candidate-incorrect");
421
+ states.delete("candidate-partially-correct");
422
+ if (value)
423
+ states.add(`candidate-${value}`);
424
+ this.requestUpdate("candidateCorrection", previous);
425
+ }
426
+ get correctionPart() {
427
+ return this.#candidateCorrection ? `correction correction-${this.#candidateCorrection}` : "correction";
428
+ }
429
+ }
430
+ return ActiveElementCorrectionMixinClass;
431
+ };
432
+
433
+ // ../qti-corrections/dist/elements/qti-gap-text-correction.js
434
+ var QtiGapTextCorrection = class extends ActiveElementCorrectionMixin(QtiGapText) {
435
+ static {
436
+ this.styles = [QtiGapText.styles, correctionPart];
437
+ }
438
+ render() {
439
+ return html5`<div part="control"></div>
440
+ <slot part="label"></slot>
441
+ <span part=${this.correctionPart} aria-hidden="true"></span>`;
442
+ }
443
+ };
444
+
445
+ // ../qti-corrections/dist/elements/qti-hotspot-choice-correction.js
446
+ import { property as property5 } from "lit/decorators.js";
447
+ var __decorate5 = function(decorators, target, key, desc) {
448
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
449
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
450
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
451
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
452
+ };
453
+ var QtiHotspotChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiHotspotChoice) {
454
+ constructor() {
455
+ super(...arguments);
456
+ this.orderCorrect = null;
457
+ }
458
+ };
459
+ __decorate5([
460
+ property5({ attribute: "aria-ordercorrectvalue", type: Number, reflect: true })
461
+ ], QtiHotspotChoiceCorrection.prototype, "orderCorrect", void 0);
462
+
463
+ // ../qti-corrections/dist/elements/qti-hottext-correction.js
464
+ import { html as html6 } from "lit";
465
+ var QtiHottextCorrection = class extends ActiveElementCorrectionMixin(QtiHottext) {
466
+ static {
467
+ this.styles = [QtiHottext.styles, correctionPart];
468
+ }
469
+ render() {
470
+ return html6`<div part="control"><div part="control-mark"></div></div>
471
+ <slot part="label"></slot>
472
+ <span part=${this.correctionPart} aria-hidden="true"></span>`;
473
+ }
474
+ };
475
+
476
+ // ../qti-corrections/dist/elements/qti-simple-associable-choice-correction.js
477
+ import { html as html7 } from "lit";
478
+ import { repeat } from "lit/directives/repeat.js";
479
+ var QtiSimpleAssociableChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiSimpleAssociableChoice) {
480
+ static {
481
+ this.styles = [QtiSimpleAssociableChoice.styles, correctionPart];
821
482
  }
822
- #getDisplayedText() {
823
- return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
483
+ render() {
484
+ return html7`
485
+ <div part="control"></div>
486
+ <slot part="label"></slot>
487
+ <span part=${this.correctionPart} aria-hidden="true"></span>
488
+ <div part="drop">
489
+ ${repeat(this.drags, (node) => node.getAttribute("identifier"), (node) => node)}
490
+ </div>
491
+ `;
492
+ }
493
+ };
494
+
495
+ // ../qti-corrections/dist/elements/qti-simple-choice-correction.js
496
+ import { html as html8, nothing } from "lit";
497
+ var QtiSimpleChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiSimpleChoice) {
498
+ static {
499
+ this.styles = [QtiSimpleChoice.styles, correctionPart];
824
500
  }
825
501
  render() {
826
- return html7` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
502
+ return html8`<div part="control" tabindex="0"><div part="control-mark"></div></div>
503
+ ${this.marker ? html8`<div id="label" part="marker">${this.marker}</div>` : nothing}
504
+ <slot part="label"></slot>
505
+ <span part=${this.correctionPart} aria-hidden="true"></span>`;
827
506
  }
828
507
  };
829
- __decorate6([
830
- consume3({ context: computedItemContext, subscribe: true })
831
- ], ItemShowCorrectResponse.prototype, "computedContext", void 0);
832
- __decorate6([
833
- property5({ type: Boolean, reflect: true })
834
- ], ItemShowCorrectResponse.prototype, "shown", void 0);
835
- __decorate6([
836
- property5({ type: Boolean, reflect: true })
837
- ], ItemShowCorrectResponse.prototype, "disabled", void 0);
838
- __decorate6([
839
- property5({ type: String })
840
- ], ItemShowCorrectResponse.prototype, "showCorrectText", void 0);
841
- __decorate6([
842
- property5({ type: String })
843
- ], ItemShowCorrectResponse.prototype, "hideCorrectText", void 0);
844
- __decorate6([
845
- property5({ type: String })
846
- ], ItemShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
847
508
 
848
- // ../qti-corrections/dist/components/test-show-correct-response/test-show-correct-response.js
849
- import { css as css5, html as html8, LitElement as LitElement4 } from "lit";
850
- import { property as property6 } from "lit/decorators.js";
851
- import { consume as consume4 } from "@lit/context";
852
- var __decorate7 = function(decorators, target, key, desc) {
509
+ // ../qti-corrections/dist/mixins/correct-response.mixin.js
510
+ import { property as property6, state as state2 } from "lit/decorators.js";
511
+ var __decorate6 = function(decorators, target, key, desc) {
853
512
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
854
513
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
855
514
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
856
515
  return c > 3 && r && Object.defineProperty(target, key, r), r;
857
516
  };
858
- var TestShowCorrectResponse = class extends LitElement4 {
859
- constructor() {
860
- super(...arguments);
861
- this.shown = false;
862
- this.disabled = false;
863
- this.showCorrectText = "Show correct response";
864
- this.hideCorrectText = "Hide correct response";
865
- this.noCorrectResponseText = "No correct response specified";
517
+ var Correctness;
518
+ (function(Correctness2) {
519
+ Correctness2["Correct"] = "correct";
520
+ Correctness2["PartiallyCorrect"] = "partially-correct";
521
+ Correctness2["Incorrect"] = "incorrect";
522
+ })(Correctness || (Correctness = {}));
523
+ var CorrectResponseMixin = (superClass) => {
524
+ class CorrectResponseMixinClass extends superClass {
525
+ constructor() {
526
+ super(...arguments);
527
+ this.showCorrectResponse = false;
528
+ this._handleShowCorrectResponseChange = (_, show) => {
529
+ this.toggleInternalCorrectResponse(show);
530
+ };
531
+ this.showFullCorrectResponse = false;
532
+ this._handleShowFullCorrectResponseChange = (_, show) => {
533
+ this.toggleFullCorrectResponse(show);
534
+ };
535
+ this.showCandidateCorrection = false;
536
+ this._handleShowCandidateCorrectionChange = (_, show) => {
537
+ this.toggleCandidateCorrection(show);
538
+ };
539
+ this._correctResponse = null;
540
+ }
541
+ /**
542
+ * The correct response for this interaction. Can be set as a comma-separated
543
+ * string via attribute or as string/string[] via property.
544
+ *
545
+ * @example
546
+ * ```html
547
+ * <qti-choice-interaction correct-response="A,B">
548
+ * ```
549
+ */
550
+ set correctResponseAttr(val) {
551
+ this._correctResponse = val;
552
+ }
553
+ get correctResponseAttr() {
554
+ return this._correctResponse;
555
+ }
556
+ get isFullCorrectResponse() {
557
+ return this._isFullCorrectResponse;
558
+ }
559
+ get registersWithItem() {
560
+ return !this.isFullCorrectResponse && super.registersWithItem;
561
+ }
562
+ set isFullCorrectResponse(val) {
563
+ this._isFullCorrectResponse = val;
564
+ if (val) {
565
+ this.setAttribute("inert", "");
566
+ this.setAttribute("response-identifier", this.responseIdentifier + "_cr");
567
+ this.setAttribute("answer-key", "");
568
+ }
569
+ }
570
+ get correctResponse() {
571
+ const responseVariable = this.responseVariable;
572
+ if (responseVariable?.correctResponse) {
573
+ return responseVariable.correctResponse;
574
+ }
575
+ return this._correctResponse;
576
+ }
577
+ set correctResponse(val) {
578
+ const oldVal = this._correctResponse;
579
+ this._correctResponse = val;
580
+ if (val === null || val === void 0) {
581
+ this.removeAttribute("correct-response");
582
+ } else {
583
+ this.setAttribute("correct-response", Array.isArray(val) ? val.join(",") : val);
584
+ }
585
+ this.requestUpdate("_correctResponse", oldVal);
586
+ }
587
+ // ─── correctness getter ───────────────────────────────────────────────────
588
+ get correctness() {
589
+ const correctResponse = this.correctResponse;
590
+ if (!correctResponse)
591
+ return null;
592
+ const currentResponse = this.response;
593
+ if (currentResponse === null || currentResponse === void 0 || currentResponse === "" || Array.isArray(currentResponse) && currentResponse.length === 0) {
594
+ return null;
595
+ }
596
+ const correctArr = Array.isArray(correctResponse) ? correctResponse : [correctResponse];
597
+ const responseArr = Array.isArray(currentResponse) ? currentResponse : [currentResponse];
598
+ const filteredResponseArr = responseArr.filter((r) => r !== "");
599
+ if (filteredResponseArr.length === 0)
600
+ return null;
601
+ const correctCount = filteredResponseArr.filter((r) => correctArr.includes(r)).length;
602
+ const incorrectCount = filteredResponseArr.filter((r) => !correctArr.includes(r)).length;
603
+ if (correctCount === correctArr.length && incorrectCount === 0 && filteredResponseArr.length === correctArr.length) {
604
+ return Correctness.Correct;
605
+ }
606
+ if (correctCount > 0 && (correctCount < correctArr.length || incorrectCount > 0)) {
607
+ return Correctness.PartiallyCorrect;
608
+ }
609
+ return Correctness.Incorrect;
610
+ }
611
+ // ─── correctionPart ───────────────────────────────────────────────────────
612
+ get correctionPart() {
613
+ return "correction";
614
+ }
615
+ // ─── toggle methods ───────────────────────────────────────────────────────
616
+ toggleCorrectResponse(show) {
617
+ const correctionConfig = this.configContext;
618
+ const correctResponseMode = correctionConfig?.correctResponseMode || "internal";
619
+ if (correctResponseMode === "full") {
620
+ this.toggleFullCorrectResponse(show);
621
+ } else {
622
+ this.toggleInternalCorrectResponse(show);
623
+ }
624
+ }
625
+ /**
626
+ * Whether the full correct response is withheld from a candidate who is already correct.
627
+ *
628
+ * Withheld by default, unless the item configures `fullCorrectResponseOnlyWhenIncorrect: false`
629
+ * — the behaviour `show-full-correct-response` has always had, on the reasoning that a correct
630
+ * answer already *is* the key.
631
+ *
632
+ * An interaction that routes its internal mode here overrides this to false: there, the caller
633
+ * asked to show the correct response, and silently showing nothing is worse than showing the
634
+ * candidate the answer they already gave.
635
+ */
636
+ get withholdsFullCorrectResponseWhenCorrect() {
637
+ return this.configContext?.fullCorrectResponseOnlyWhenIncorrect !== false;
638
+ }
639
+ async toggleFullCorrectResponse(show) {
640
+ const nextSibling = this.nextSibling;
641
+ const nextSiblingIsFullCorrectResponse = nextSibling instanceof HTMLDivElement && nextSibling?.classList.contains("full-correct-response");
642
+ const correctResponse = this.correctResponse;
643
+ if (!correctResponse) {
644
+ return;
645
+ }
646
+ const showFullCorrectResponse = show && (!this.withholdsFullCorrectResponseWhenCorrect || this.correctness !== Correctness.Correct);
647
+ if (!showFullCorrectResponse) {
648
+ if (!nextSiblingIsFullCorrectResponse) {
649
+ return;
650
+ }
651
+ this.parentElement?.removeChild(nextSibling);
652
+ return;
653
+ }
654
+ if (nextSiblingIsFullCorrectResponse) {
655
+ return;
656
+ }
657
+ const clone = this.cloneNode(true);
658
+ clone.removeAttribute("show-full-correct-response");
659
+ clone.removeAttribute("show-correct-response");
660
+ clone.removeAttribute("show-candidate-correction");
661
+ const containerDiv = document.createElement("div");
662
+ containerDiv.classList.add("full-correct-response");
663
+ if (this.isInline) {
664
+ containerDiv.classList.add("full-correct-response-inline");
665
+ } else {
666
+ containerDiv.classList.add("full-correct-response-block");
667
+ }
668
+ containerDiv.role = "full-correct-response";
669
+ containerDiv.appendChild(clone);
670
+ clone.isFullCorrectResponse = true;
671
+ this.parentElement?.insertBefore(containerDiv, this.nextSibling);
672
+ await clone.updateComplete;
673
+ clone.response = Array.isArray(correctResponse) ? [...correctResponse] : correctResponse;
674
+ }
675
+ toggleInternalCorrectResponse(show) {
676
+ this._internals.states.delete("show-correct-response");
677
+ if (show && this.correctResponse) {
678
+ this._internals.states.add("show-correct-response");
679
+ }
680
+ }
681
+ toggleCandidateCorrection(show) {
682
+ if (!show) {
683
+ return;
684
+ }
685
+ }
686
+ // ─── Lifecycle ────────────────────────────────────────────────────────────
687
+ firstUpdated() {
688
+ super.firstUpdated();
689
+ if (this.isFullCorrectResponse) {
690
+ return;
691
+ }
692
+ if (this.showCorrectResponse) {
693
+ this.toggleInternalCorrectResponse(true);
694
+ }
695
+ if (this.showFullCorrectResponse) {
696
+ this.toggleFullCorrectResponse(true);
697
+ }
698
+ }
866
699
  }
867
- static {
868
- this.styles = css5`
869
- :host {
870
- ${btn};
700
+ __decorate6([
701
+ property6({
702
+ attribute: "correct-response",
703
+ reflect: true,
704
+ converter: responseAttributeConverter({ emptyAs: null })
705
+ })
706
+ ], CorrectResponseMixinClass.prototype, "correctResponseAttr", null);
707
+ __decorate6([
708
+ property6({ type: Boolean, attribute: "show-correct-response", reflect: true })
709
+ ], CorrectResponseMixinClass.prototype, "showCorrectResponse", void 0);
710
+ __decorate6([
711
+ watch("showCorrectResponse", { waitUntilFirstUpdate: true })
712
+ ], CorrectResponseMixinClass.prototype, "_handleShowCorrectResponseChange", void 0);
713
+ __decorate6([
714
+ property6({ type: Boolean, attribute: "show-full-correct-response", reflect: true })
715
+ ], CorrectResponseMixinClass.prototype, "showFullCorrectResponse", void 0);
716
+ __decorate6([
717
+ watch("showFullCorrectResponse", { waitUntilFirstUpdate: true })
718
+ ], CorrectResponseMixinClass.prototype, "_handleShowFullCorrectResponseChange", void 0);
719
+ __decorate6([
720
+ property6({ type: Boolean, attribute: "show-candidate-correction", reflect: true })
721
+ ], CorrectResponseMixinClass.prototype, "showCandidateCorrection", void 0);
722
+ __decorate6([
723
+ watch("showCandidateCorrection", { waitUntilFirstUpdate: true })
724
+ ], CorrectResponseMixinClass.prototype, "_handleShowCandidateCorrectionChange", void 0);
725
+ __decorate6([
726
+ state2()
727
+ ], CorrectResponseMixinClass.prototype, "_isFullCorrectResponse", void 0);
728
+ __decorate6([
729
+ state2()
730
+ ], CorrectResponseMixinClass.prototype, "_correctResponse", void 0);
731
+ return CorrectResponseMixinClass;
732
+ };
733
+
734
+ // ../qti-corrections/dist/mixins/candidate-correction.mixin.js
735
+ import { state as state3 } from "lit/decorators.js";
736
+ var __decorate7 = function(decorators, target, key, desc) {
737
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
738
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
739
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
740
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
741
+ };
742
+ var CandidateCorrectionMixin = (superClass) => {
743
+ class CandidateCorrectionMixinClass extends CorrectResponseMixin(superClass) {
744
+ constructor() {
745
+ super(...arguments);
746
+ this._candidateCorrection = null;
871
747
  }
872
- :host([disabled]) {
873
- ${dis};
748
+ get correctionPart() {
749
+ return this._candidateCorrection ? `correction correction-${this._candidateCorrection}` : "correction";
874
750
  }
875
- `;
876
- }
877
- #previousActiveItem;
878
- // Store previous active item reference
879
- willUpdate(_changedProperties) {
880
- const activeItem = this.computedContext?.testParts.flatMap((testPart) => testPart.sections.flatMap((section) => section.items)).find((item) => item.active);
881
- if (this.#previousActiveItem !== activeItem) {
882
- this.shown = false;
883
- this.#previousActiveItem = activeItem;
751
+ toggleCandidateCorrection(show) {
752
+ if (this.showCandidateCorrection !== show) {
753
+ this.showCandidateCorrection = show;
754
+ }
755
+ super.toggleCandidateCorrection(show);
756
+ const internals = this._internals;
757
+ internals.states.delete("candidate-correct");
758
+ internals.states.delete("candidate-partially-correct");
759
+ internals.states.delete("candidate-incorrect");
760
+ let verdict = null;
761
+ if (show) {
762
+ if (this.correctness === Correctness.Correct) {
763
+ internals.states.add("candidate-correct");
764
+ verdict = "correct";
765
+ }
766
+ if (this.correctness === Correctness.PartiallyCorrect) {
767
+ internals.states.add("candidate-partially-correct");
768
+ verdict = "partially-correct";
769
+ }
770
+ if (this.correctness === Correctness.Incorrect) {
771
+ internals.states.add("candidate-incorrect");
772
+ verdict = "incorrect";
773
+ }
774
+ }
775
+ if (this._candidateCorrection !== verdict) {
776
+ this._candidateCorrection = verdict;
777
+ }
884
778
  }
885
- if (activeItem) {
886
- const containsCorrectResponse = !!activeItem?.variables?.some((v) => v["correctResponse"]);
887
- const containsMapping = !!activeItem?.variables?.some((v) => {
888
- return v["mapping"]?.mapEntries?.length > 0 || v["areaMapping"]?.areaMapEntries?.length > 0;
779
+ connectedCallback() {
780
+ super.connectedCallback?.();
781
+ queueMicrotask(() => {
782
+ if (!this.isConnected || this.isFullCorrectResponse) {
783
+ return;
784
+ }
785
+ if (this.showCandidateCorrection) {
786
+ this.toggleCandidateCorrection(true);
787
+ }
889
788
  });
890
- this.disabled = !containsCorrectResponse && !containsMapping;
891
- } else {
892
- this.disabled = true;
893
789
  }
894
790
  }
895
- #toggleState() {
896
- if (this.disabled)
897
- return;
898
- this.shown = !this.shown;
899
- this.dispatchEvent(new CustomEvent("test-show-correct-response", {
900
- detail: this.shown,
901
- bubbles: true
902
- }));
903
- }
904
- #getDisplayedText() {
905
- return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
906
- }
907
- render() {
908
- return html8` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
909
- }
791
+ __decorate7([
792
+ state3()
793
+ ], CandidateCorrectionMixinClass.prototype, "_candidateCorrection", void 0);
794
+ return CandidateCorrectionMixinClass;
910
795
  };
911
- __decorate7([
912
- consume4({ context: computedContext, subscribe: true })
913
- ], TestShowCorrectResponse.prototype, "computedContext", void 0);
914
- __decorate7([
915
- property6({ type: Boolean, reflect: true })
916
- ], TestShowCorrectResponse.prototype, "shown", void 0);
917
- __decorate7([
918
- property6({ type: Boolean, reflect: true })
919
- ], TestShowCorrectResponse.prototype, "disabled", void 0);
920
- __decorate7([
921
- property6({ type: String })
922
- ], TestShowCorrectResponse.prototype, "showCorrectText", void 0);
923
- __decorate7([
924
- property6({ type: String })
925
- ], TestShowCorrectResponse.prototype, "hideCorrectText", void 0);
926
- __decorate7([
927
- property6({ type: String })
928
- ], TestShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
929
796
 
930
797
  // ../qti-corrections/dist/mixins/drag-drop-correction.mixin.js
931
798
  var DragDropCorrectionMixin = (superClass) => {
@@ -952,6 +819,42 @@ var DragDropCorrectionMixin = (superClass) => {
952
819
  var QtiAssociateInteractionCorrection = class extends DragDropCorrectionMixin(QtiAssociateInteraction) {
953
820
  };
954
821
 
822
+ // ../qti-corrections/dist/mixins/choice-correction.mixin.js
823
+ var ChoiceCorrectionMixin = (superClass) => {
824
+ class ChoiceCorrectionMixinClass extends CandidateCorrectionMixin(superClass) {
825
+ toggleInternalCorrectResponse(show) {
826
+ super.toggleInternalCorrectResponse(show);
827
+ const correctResponse = this.correctResponse;
828
+ const correctResponses = correctResponse ? Array.isArray(correctResponse) ? correctResponse : [correctResponse] : [];
829
+ for (const choice of this._choiceElements) {
830
+ choice.internals.states.delete("correct-response");
831
+ choice.internals.states.delete("incorrect-response");
832
+ if (show && correctResponses.length > 0) {
833
+ choice.internals.states.add(correctResponses.includes(choice.identifier) ? "correct-response" : "incorrect-response");
834
+ }
835
+ }
836
+ }
837
+ toggleCandidateCorrection(show) {
838
+ super.toggleCandidateCorrection(show);
839
+ for (const choice of this._choiceElements) {
840
+ choice.candidateCorrection = null;
841
+ }
842
+ if (!show || !this.correctResponse) {
843
+ return;
844
+ }
845
+ const correctResponses = Array.isArray(this.correctResponse) ? this.correctResponse : [this.correctResponse];
846
+ const candidateResponses = Array.isArray(this.response) ? this.response : this.response ? [this.response] : [];
847
+ for (const choice of this._choiceElements) {
848
+ if (!candidateResponses.includes(choice.identifier)) {
849
+ continue;
850
+ }
851
+ choice.candidateCorrection = correctResponses.includes(choice.identifier) ? "correct" : "incorrect";
852
+ }
853
+ }
854
+ }
855
+ return ChoiceCorrectionMixinClass;
856
+ };
857
+
955
858
  // ../qti-corrections/dist/interactions/qti-choice-interaction-correction.js
956
859
  var QtiChoiceInteractionCorrection = class extends ChoiceCorrectionMixin(QtiChoiceInteraction) {
957
860
  };
@@ -1594,27 +1497,135 @@ var QtiTextEntryInteractionCorrection = class extends CandidateCorrectionMixin(Q
1594
1497
  }
1595
1498
  };
1596
1499
 
1500
+ // ../qti-corrections/dist/components/qti-assessment-item-correction.js
1501
+ var QtiAssessmentItemCorrection = class extends QtiAssessmentItem {
1502
+ showCorrectResponse(show) {
1503
+ for (const interaction of this.interactionElements) {
1504
+ interaction.toggleCorrectResponse?.(show);
1505
+ }
1506
+ this.updateControlState("item-show-correct-response", show);
1507
+ }
1508
+ showCandidateCorrection(show) {
1509
+ for (const interaction of this.interactionElements) {
1510
+ interaction.toggleCandidateCorrection?.(show);
1511
+ }
1512
+ this.updateControlState("item-show-candidate-correction", show);
1513
+ }
1514
+ afterResponseVariableUpdated() {
1515
+ this.showCandidateCorrection(false);
1516
+ }
1517
+ updateControlState(selector, shown) {
1518
+ let root = this.getRootNode();
1519
+ while (true) {
1520
+ root.querySelectorAll(selector).forEach((control) => control.shown = shown);
1521
+ if (!(root instanceof ShadowRoot))
1522
+ return;
1523
+ root = root.host.getRootNode();
1524
+ }
1525
+ }
1526
+ };
1527
+
1528
+ // ../qti-corrections/dist/components/qti-item-correction.js
1529
+ var QtiItemCorrection = class extends QtiItem {
1530
+ #onShowCorrectResponse = (event) => {
1531
+ const show = event.detail;
1532
+ this.assessmentItem?.showCorrectResponse?.(show);
1533
+ this.updateControlState("item-show-correct-response", show);
1534
+ };
1535
+ #onShowCandidateCorrection = (event) => {
1536
+ const show = event.detail;
1537
+ this.assessmentItem?.showCandidateCorrection?.(show);
1538
+ this.updateControlState("item-show-candidate-correction", show);
1539
+ };
1540
+ #onSwitchCorrectResponseMode = (event) => {
1541
+ this.assessmentItem?.showCorrectResponse?.(false);
1542
+ this.configContext = {
1543
+ ...this.configContext,
1544
+ correctResponseMode: event.detail
1545
+ };
1546
+ };
1547
+ constructor() {
1548
+ super();
1549
+ this.addEventListener("item-show-correct-response", this.#onShowCorrectResponse);
1550
+ this.addEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
1551
+ this.addEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
1552
+ }
1553
+ updateControlState(selector, shown) {
1554
+ this.querySelectorAll(selector).forEach((control) => control.shown = shown);
1555
+ }
1556
+ disconnectedCallback() {
1557
+ this.removeEventListener("item-show-correct-response", this.#onShowCorrectResponse);
1558
+ this.removeEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
1559
+ this.removeEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
1560
+ super.disconnectedCallback();
1561
+ }
1562
+ };
1563
+
1564
+ // ../qti-corrections/dist/components/test-correction-elements.js
1565
+ var TestNavigationCorrection = class extends TestNavigation {
1566
+ #onShowCorrectResponse = (event) => {
1567
+ this.activeAssessmentItem?.showCorrectResponse?.(event.detail);
1568
+ };
1569
+ #onShowCandidateCorrection = (event) => {
1570
+ this.activeAssessmentItem?.showCandidateCorrection?.(event.detail);
1571
+ };
1572
+ constructor() {
1573
+ super();
1574
+ this.addEventListener("test-show-correct-response", this.#onShowCorrectResponse);
1575
+ this.addEventListener("test-show-candidate-correction", this.#onShowCandidateCorrection);
1576
+ }
1577
+ disconnectedCallback() {
1578
+ this.removeEventListener("test-show-correct-response", this.#onShowCorrectResponse);
1579
+ this.removeEventListener("test-show-candidate-correction", this.#onShowCandidateCorrection);
1580
+ super.disconnectedCallback();
1581
+ }
1582
+ /**
1583
+ * Reflect correctness back to the candidate after an ended attempt, for items
1584
+ * the assessment opted in via the standard `qti-item-session-control
1585
+ * show-solution` (QTI 3.0 ItemSessionControl.show-solution) — the player takes
1586
+ * no opinion of its own:
1587
+ * - candidate correction (a mark on the learner's selection) after every attempt;
1588
+ * - the correct response (a mark on the right answer) once the item is done —
1589
+ * the candidate reached the optimal outcome, or ran out of attempts.
1590
+ */
1591
+ afterAttemptEnded(assessmentItem, computedItem, done) {
1592
+ if (!assessmentItem || !computedItem?.showSolution)
1593
+ return;
1594
+ const correctable = assessmentItem;
1595
+ correctable.showCandidateCorrection?.(true);
1596
+ correctable.showCorrectResponse?.(done);
1597
+ }
1598
+ };
1599
+ var QtiTestCorrection = class extends QtiTest {
1600
+ updateAssessmentItemView(assessmentItem, view) {
1601
+ assessmentItem.showCorrectResponse?.(view === "scorer");
1602
+ }
1603
+ };
1604
+ var TestCheckItemCorrection = class extends TestCheckItem {
1605
+ constructor() {
1606
+ super();
1607
+ this.addEventListener("click", () => {
1608
+ this.dispatchEvent(new CustomEvent("test-show-correct-response", { detail: true, bubbles: true }));
1609
+ });
1610
+ }
1611
+ };
1612
+
1597
1613
  export {
1598
- Correctness,
1599
- CorrectResponseMixin,
1614
+ ItemCorrectResponseMode,
1615
+ ItemShowCandidateCorrection,
1616
+ ItemShowCorrectResponse,
1617
+ TestShowCorrectResponse,
1600
1618
  correctionPart,
1601
- CandidateCorrectionMixin,
1602
- ChoiceCorrectionMixin,
1603
1619
  QtiGapTextCorrection,
1604
1620
  QtiHotspotChoiceCorrection,
1605
1621
  QtiHottextCorrection,
1606
1622
  QtiSimpleAssociableChoiceCorrection,
1607
1623
  QtiSimpleChoiceCorrection,
1608
- QtiAssessmentItemCorrection,
1609
- QtiItemCorrection,
1610
- TestNavigationCorrection,
1611
- QtiTestCorrection,
1612
- TestCheckItemCorrection,
1613
- ItemCorrectResponseMode,
1614
- ItemShowCandidateCorrection,
1615
- ItemShowCorrectResponse,
1616
- TestShowCorrectResponse,
1624
+ Correctness,
1625
+ CorrectResponseMixin,
1626
+ CandidateCorrectionMixin,
1617
1627
  QtiAssociateInteractionCorrection,
1628
+ ChoiceCorrectionMixin,
1618
1629
  QtiChoiceInteractionCorrection,
1619
1630
  QtiExtendedTextInteractionCorrection,
1620
1631
  QtiGapMatchInteractionCorrection,
@@ -1629,6 +1640,11 @@ export {
1629
1640
  QtiPortableCustomInteractionCorrection,
1630
1641
  QtiSelectPointInteractionCorrection,
1631
1642
  QtiSliderInteractionCorrection,
1632
- QtiTextEntryInteractionCorrection
1643
+ QtiTextEntryInteractionCorrection,
1644
+ QtiAssessmentItemCorrection,
1645
+ QtiItemCorrection,
1646
+ TestNavigationCorrection,
1647
+ QtiTestCorrection,
1648
+ TestCheckItemCorrection
1633
1649
  };
1634
- //# sourceMappingURL=chunk-CF3DXJWM.js.map
1650
+ //# sourceMappingURL=chunk-WTV7NQHO.js.map