@citolab/qti-components 7.27.2 → 7.27.4

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 (51) hide show
  1. package/cdn/index.global.js +1 -1
  2. package/cdn/index.js +230 -212
  3. package/custom-elements.json +4214 -1176
  4. package/dist/base.d.ts +3 -2
  5. package/dist/base.js +1 -1
  6. package/dist/{chunk-TZMDZQFG.js → chunk-3HJE3KRM.js} +469 -221
  7. package/dist/chunk-3HJE3KRM.js.map +1 -0
  8. package/dist/{chunk-75ME6QG5.js → chunk-424AWLRU.js} +18 -18
  9. package/dist/{chunk-QUWFDFGZ.js → chunk-FFESMKSD.js} +277 -21
  10. package/dist/chunk-FFESMKSD.js.map +1 -0
  11. package/dist/{chunk-G5ZUC3OT.js → chunk-LQZCSHN5.js} +23 -23
  12. package/dist/chunk-LQZCSHN5.js.map +1 -0
  13. package/dist/{chunk-DG5TP35K.js → chunk-N7S3GNUP.js} +5 -5
  14. package/dist/{chunk-DG5TP35K.js.map → chunk-N7S3GNUP.js.map} +1 -1
  15. package/dist/{chunk-RXRKP6P7.js → chunk-SX63OCDZ.js} +2 -2
  16. package/dist/{chunk-K7HR6ZAY.js → chunk-UKPCQKPF.js} +2 -2
  17. package/dist/chunk-UKPCQKPF.js.map +1 -0
  18. package/dist/{chunk-KY3II5OX.js → chunk-XYTJOQRZ.js} +240 -202
  19. package/dist/chunk-XYTJOQRZ.js.map +1 -0
  20. package/dist/{chunk-GG36UR7F.js → chunk-YLIYPNMK.js} +1004 -12
  21. package/dist/chunk-YLIYPNMK.js.map +1 -0
  22. package/dist/{chunk-TORB5UN2.js → chunk-Z2SUBRH5.js} +304 -243
  23. package/dist/chunk-Z2SUBRH5.js.map +1 -0
  24. package/dist/elements.d.ts +67 -2
  25. package/dist/elements.js +10 -6
  26. package/dist/index.d.ts +5 -4
  27. package/dist/index.js +55 -11
  28. package/dist/interactions.d.ts +8 -7
  29. package/dist/interactions.js +3 -3
  30. package/dist/item.js +4 -4
  31. package/dist/loader.d.ts +2 -1
  32. package/dist/loader.js +2 -2
  33. package/dist/processing.d.ts +374 -17
  34. package/dist/processing.js +42 -2
  35. package/dist/qti-components-jsx.d.ts +1183 -126
  36. package/dist/{qti-rule-base-DGhWN-as.d.ts → qti-condition-expression-B1BYmCcq.d.ts} +1 -14
  37. package/dist/{qti-feedback-BZjWNyxP.d.ts → qti-feedback-ChmXhZuf.d.ts} +1 -1
  38. package/dist/qti-rule-base-ajOnfGXY.d.ts +16 -0
  39. package/dist/test.d.ts +2 -1
  40. package/dist/test.js +6 -6
  41. package/dist/transformers.js +1 -1
  42. package/package.json +11 -11
  43. package/dist/chunk-G5ZUC3OT.js.map +0 -1
  44. package/dist/chunk-GG36UR7F.js.map +0 -1
  45. package/dist/chunk-K7HR6ZAY.js.map +0 -1
  46. package/dist/chunk-KY3II5OX.js.map +0 -1
  47. package/dist/chunk-QUWFDFGZ.js.map +0 -1
  48. package/dist/chunk-TORB5UN2.js.map +0 -1
  49. package/dist/chunk-TZMDZQFG.js.map +0 -1
  50. /package/dist/{chunk-75ME6QG5.js.map → chunk-424AWLRU.js.map} +0 -0
  51. /package/dist/{chunk-RXRKP6P7.js.map → chunk-SX63OCDZ.js.map} +0 -0
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  item_default,
3
3
  m
4
- } from "./chunk-G5ZUC3OT.js";
4
+ } from "./chunk-LQZCSHN5.js";
5
5
  import {
6
6
  qtiTransformItem
7
- } from "./chunk-K7HR6ZAY.js";
7
+ } from "./chunk-UKPCQKPF.js";
8
8
  import {
9
+ T,
9
10
  c,
10
11
  computedItemContext,
11
12
  configContext,
@@ -15,9 +16,8 @@ import {
15
16
  n,
16
17
  r,
17
18
  t,
18
- watch,
19
- x
20
- } from "./chunk-TORB5UN2.js";
19
+ watch
20
+ } from "./chunk-Z2SUBRH5.js";
21
21
  import {
22
22
  __decorateClass,
23
23
  __privateAdd,
@@ -67,10 +67,10 @@ var ItemContainer = class extends i2 {
67
67
  }
68
68
  }
69
69
  render() {
70
- return x`
70
+ return T`
71
71
  ${__privateGet(this, _templateContent)}
72
72
  <slot></slot>
73
- ${m(this.itemDoc, x`<span>Loading...</span>`)}
73
+ ${m(this.itemDoc, T`<span>Loading...</span>`)}
74
74
  `;
75
75
  }
76
76
  };
@@ -78,7 +78,7 @@ _templateContent = new WeakMap();
78
78
  _ItemContainer_instances = new WeakSet();
79
79
  initializeTemplateContent_fn = function() {
80
80
  const template = this.querySelector("template");
81
- __privateSet(this, _templateContent, template ? template.content : x``);
81
+ __privateSet(this, _templateContent, template ? template.content : T``);
82
82
  };
83
83
  applyStyles_fn = function() {
84
84
  const sheet = new CSSStyleSheet();
@@ -117,7 +117,7 @@ var ItemCorrectResponseMode = class extends i2 {
117
117
  };
118
118
  }
119
119
  render() {
120
- return x`
120
+ return T`
121
121
  <label part="label" for="modeSelect">${this.label}</label>
122
122
  <select
123
123
  part="select"
@@ -128,7 +128,7 @@ var ItemCorrectResponseMode = class extends i2 {
128
128
  }}
129
129
  >
130
130
  ${Object.keys(this._options).map(
131
- (value) => x`<option value="${value}" ?selected=${value === this.itemContext?.correctResponseMode}>
131
+ (value) => T`<option value="${value}" ?selected=${value === this.itemContext?.correctResponseMode}>
132
132
  ${this._options[value]}
133
133
  </option>`
134
134
  )}
@@ -208,7 +208,7 @@ var ItemShowCandidateCorrection = class extends i2 {
208
208
  this.disabled = !__privateGet(this, _hasCorrectResponse);
209
209
  }
210
210
  render() {
211
- return x` <div @click="${__privateMethod(this, _ItemShowCandidateCorrection_instances, toggleState_fn)}">${__privateMethod(this, _ItemShowCandidateCorrection_instances, getDisplayedText_fn).call(this)}</div> `;
211
+ return T` <div @click="${__privateMethod(this, _ItemShowCandidateCorrection_instances, toggleState_fn)}">${__privateMethod(this, _ItemShowCandidateCorrection_instances, getDisplayedText_fn).call(this)}</div> `;
212
212
  }
213
213
  };
214
214
  _hasCorrectResponse = new WeakMap();
@@ -284,7 +284,7 @@ var ItemShowCorrectResponse = class extends i2 {
284
284
  this.disabled = !__privateGet(this, _hasCorrectResponse2);
285
285
  }
286
286
  render() {
287
- return x` <div @click="${__privateMethod(this, _ItemShowCorrectResponse_instances, toggleState_fn2)}">${__privateMethod(this, _ItemShowCorrectResponse_instances, getDisplayedText_fn2).call(this)}</div> `;
287
+ return T` <div @click="${__privateMethod(this, _ItemShowCorrectResponse_instances, toggleState_fn2)}">${__privateMethod(this, _ItemShowCorrectResponse_instances, getDisplayedText_fn2).call(this)}</div> `;
288
288
  }
289
289
  };
290
290
  _hasCorrectResponse2 = new WeakMap();
@@ -336,10 +336,10 @@ ItemShowCorrectResponse = __decorateClass([
336
336
  var ItemPrintVariables = class extends i2 {
337
337
  render() {
338
338
  const activeItem = this.computedContext;
339
- if (!activeItem || !activeItem.variables) return x``;
339
+ if (!activeItem || !activeItem.variables) return T``;
340
340
  const responseVariables = activeItem.variables.filter((v) => v.type === "response");
341
341
  const outcomeVariables = activeItem.variables.filter((v) => v.type === "outcome");
342
- const renderTable = (variables, title) => x`
342
+ const renderTable = (variables, title) => T`
343
343
  <h3>${title}</h3>
344
344
  <table>
345
345
  <thead>
@@ -356,7 +356,7 @@ var ItemPrintVariables = class extends i2 {
356
356
  const correctResponse = v.correctResponse ? Array.isArray(v.correctResponse) ? v.correctResponse.join(", ") : v.correctResponse : "";
357
357
  const mapEntries = v.mapping?.mapEntries?.map((m2) => `${m2.mapKey}=${m2.mappedValue}pt`).join(", ") || "";
358
358
  const areaMapEntries = v.areaMapping?.areaMapEntries?.map((m2) => `${m2.shape}(${m2.coords})=${m2.mappedValue}pt`).join(", ") || "";
359
- return x`
359
+ return T`
360
360
  <tr>
361
361
  <td>${v.identifier}</td>
362
362
  <td>${Array.isArray(v.value) ? v.value.join(", ") : v.value}</td>
@@ -369,7 +369,7 @@ var ItemPrintVariables = class extends i2 {
369
369
  </tbody>
370
370
  </table>
371
371
  `;
372
- return x`
372
+ return T`
373
373
  ${renderTable(responseVariables, "Response Variables")} ${renderTable(outcomeVariables, "Outcome Variables")}
374
374
  `;
375
375
  }
@@ -424,7 +424,7 @@ var QtiItem = class extends i2 {
424
424
  this.addEventListener("item-switch-correct-response-mode", __privateGet(this, _onHandleSwitchCorrectResponseMode));
425
425
  }
426
426
  render() {
427
- return x`<slot></slot>`;
427
+ return T`<slot></slot>`;
428
428
  }
429
429
  disconnectedCallback() {
430
430
  super.disconnectedCallback();
@@ -507,4 +507,4 @@ export {
507
507
  ItemPrintVariables,
508
508
  QtiItem
509
509
  };
510
- //# sourceMappingURL=chunk-75ME6QG5.js.map
510
+ //# sourceMappingURL=chunk-424AWLRU.js.map
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  o
3
- } from "./chunk-DG5TP35K.js";
3
+ } from "./chunk-N7S3GNUP.js";
4
4
  import {
5
5
  qtiTransformItem
6
- } from "./chunk-K7HR6ZAY.js";
6
+ } from "./chunk-UKPCQKPF.js";
7
7
  import {
8
8
  QtiFeedback,
9
9
  QtiVariableDeclaration,
10
+ T,
10
11
  c,
11
12
  e,
12
13
  i,
@@ -16,9 +17,8 @@ import {
16
17
  n,
17
18
  r,
18
19
  t,
19
- watch,
20
- x
21
- } from "./chunk-TORB5UN2.js";
20
+ watch
21
+ } from "./chunk-Z2SUBRH5.js";
22
22
  import {
23
23
  __decorateClass,
24
24
  __privateAdd,
@@ -28,7 +28,7 @@ import {
28
28
  } from "./chunk-QXBXORM3.js";
29
29
 
30
30
  // ../qti-elements/src/components/qti-assessment-item/qti-assessment-item.ts
31
- var _itemTitle, _templateProcessing, _initialContext, _feedbackElements, _interactionElements, _QtiAssessmentItem_instances, attachEventListeners_fn, removeEventListeners_fn, _handleRegisterVariable, _handleRegisterFeedback, _handleRegisterInteraction, _handleEndAttempt, _handleSetOutcomeValue, _handleUpdateResponseVariable, processTemplates_fn, getCompletionStatus_fn, resetOutcomeVariablesBeforeResponseProcessing_fn;
31
+ var _itemTitle, _templateProcessing, _initialContext, _feedbackElements, _interactionElements, _QtiAssessmentItem_instances, attachEventListeners_fn, removeEventListeners_fn, _handleRegisterVariable, _handleRegisterFeedback, _handleRegisterInteraction, _handleEndAttempt, _handleSetOutcomeValue, _handleSetTemplateValue, _handleSetCorrectResponse, _handleUpdateResponseVariable, processTemplates_fn, getCompletionStatus_fn, resetOutcomeVariablesBeforeResponseProcessing_fn;
32
32
  var QtiAssessmentItem = class extends i2 {
33
33
  constructor() {
34
34
  super(...arguments);
@@ -80,6 +80,18 @@ var QtiAssessmentItem = class extends i2 {
80
80
  this.updateOutcomeVariable(outcomeIdentifier, value);
81
81
  e2.stopPropagation();
82
82
  });
83
+ __privateAdd(this, _handleSetTemplateValue, (e2) => {
84
+ e2.stopImmediatePropagation();
85
+ const { templateIdentifier, value } = e2.detail;
86
+ this.updateTemplateVariable(templateIdentifier, value ?? void 0);
87
+ e2.stopPropagation();
88
+ });
89
+ __privateAdd(this, _handleSetCorrectResponse, (e2) => {
90
+ e2.stopImmediatePropagation();
91
+ const { responseIdentifier, value } = e2.detail;
92
+ this.updateCorrectResponse(responseIdentifier, value ?? void 0);
93
+ e2.stopPropagation();
94
+ });
83
95
  __privateAdd(this, _handleUpdateResponseVariable, (e2) => {
84
96
  e2.stopImmediatePropagation();
85
97
  const { responseIdentifier, response, state } = e2.detail;
@@ -192,7 +204,7 @@ var QtiAssessmentItem = class extends i2 {
192
204
  }
193
205
  }
194
206
  render() {
195
- return x`<slot></slot>`;
207
+ return T`<slot></slot>`;
196
208
  }
197
209
  connectedCallback() {
198
210
  __privateMethod(this, _QtiAssessmentItem_instances, attachEventListeners_fn).call(this);
@@ -309,6 +321,60 @@ var QtiAssessmentItem = class extends i2 {
309
321
  this.updateOutcomeVariable("completionStatus", __privateMethod(this, _QtiAssessmentItem_instances, getCompletionStatus_fn).call(this));
310
322
  }
311
323
  }
324
+ /**
325
+ * Updates the template variable with the specified identifier to the given value.
326
+ */
327
+ updateTemplateVariable(identifier, value) {
328
+ const templateVariable = this._context.variables.find((v) => v.identifier === identifier && v.type === "template");
329
+ if (!templateVariable) {
330
+ console.warn(`Can not set qti-template-identifier: ${identifier}, it is not available`);
331
+ return;
332
+ }
333
+ const normalizedValue = templateVariable.cardinality === "single" ? Array.isArray(value) ? value[0] : value ?? null : value === void 0 || value === null ? null : Array.isArray(value) ? value : [value];
334
+ this._context = {
335
+ ...this._context,
336
+ variables: this._context.variables.map(
337
+ (v) => v.identifier !== identifier ? v : {
338
+ ...v,
339
+ value: normalizedValue
340
+ }
341
+ )
342
+ };
343
+ this.dispatchEvent(
344
+ new CustomEvent("qti-item-context-updated", {
345
+ bubbles: true,
346
+ composed: true,
347
+ detail: { itemContext: this._context }
348
+ })
349
+ );
350
+ }
351
+ /**
352
+ * Updates the correct response for the specified response variable.
353
+ */
354
+ updateCorrectResponse(identifier, value) {
355
+ const responseVariable = this.getResponse(identifier);
356
+ if (!responseVariable) {
357
+ console.warn(`Can not set correct response for identifier: ${identifier}, it is not available`);
358
+ return;
359
+ }
360
+ const normalizedValue = responseVariable.cardinality === "single" ? Array.isArray(value) ? value[0] : value ?? null : value === void 0 || value === null ? null : Array.isArray(value) ? value : [value];
361
+ this._context = {
362
+ ...this._context,
363
+ variables: this._context.variables.map(
364
+ (v) => v.identifier !== identifier ? v : {
365
+ ...v,
366
+ correctResponse: normalizedValue
367
+ }
368
+ )
369
+ };
370
+ this.dispatchEvent(
371
+ new CustomEvent("qti-item-context-updated", {
372
+ bubbles: true,
373
+ composed: true,
374
+ detail: { itemContext: this._context }
375
+ })
376
+ );
377
+ }
312
378
  setOutcomeVariable(identifier, value) {
313
379
  this.updateOutcomeVariable(identifier, value);
314
380
  this.dispatchEvent(
@@ -386,6 +452,8 @@ attachEventListeners_fn = function() {
386
452
  this.addEventListener("qti-register-interaction", __privateGet(this, _handleRegisterInteraction));
387
453
  this.addEventListener("end-attempt", __privateGet(this, _handleEndAttempt));
388
454
  this.addEventListener("qti-set-outcome-value", __privateGet(this, _handleSetOutcomeValue));
455
+ this.addEventListener("qti-set-template-value", __privateGet(this, _handleSetTemplateValue));
456
+ this.addEventListener("qti-set-correct-response", __privateGet(this, _handleSetCorrectResponse));
389
457
  this.addEventListener("qti-interaction-response", __privateGet(this, _handleUpdateResponseVariable));
390
458
  };
391
459
  removeEventListeners_fn = function() {
@@ -394,6 +462,8 @@ removeEventListeners_fn = function() {
394
462
  this.removeEventListener("qti-register-interaction", __privateGet(this, _handleRegisterInteraction));
395
463
  this.removeEventListener("end-attempt", __privateGet(this, _handleEndAttempt));
396
464
  this.removeEventListener("qti-set-outcome-value", __privateGet(this, _handleSetOutcomeValue));
465
+ this.removeEventListener("qti-set-template-value", __privateGet(this, _handleSetTemplateValue));
466
+ this.removeEventListener("qti-set-correct-response", __privateGet(this, _handleSetCorrectResponse));
397
467
  this.removeEventListener("qti-interaction-response", __privateGet(this, _handleUpdateResponseVariable));
398
468
  };
399
469
  _handleRegisterVariable = new WeakMap();
@@ -401,11 +471,19 @@ _handleRegisterFeedback = new WeakMap();
401
471
  _handleRegisterInteraction = new WeakMap();
402
472
  _handleEndAttempt = new WeakMap();
403
473
  _handleSetOutcomeValue = new WeakMap();
474
+ _handleSetTemplateValue = new WeakMap();
475
+ _handleSetCorrectResponse = new WeakMap();
404
476
  _handleUpdateResponseVariable = new WeakMap();
405
- processTemplates_fn = function() {
477
+ processTemplates_fn = async function() {
478
+ const templateDeclarations = Array.from(this.querySelectorAll("qti-template-declaration"));
479
+ if (templateDeclarations.length > 0) {
480
+ await Promise.all(templateDeclarations.map((declaration) => declaration.updateComplete));
481
+ await Promise.resolve();
482
+ }
406
483
  __privateSet(this, _templateProcessing, this.querySelector("qti-template-processing"));
407
484
  if (__privateGet(this, _templateProcessing)) {
408
485
  __privateGet(this, _templateProcessing).process();
486
+ __privateSet(this, _initialContext, { ...this._context, variables: this._context.variables });
409
487
  }
410
488
  };
411
489
  getCompletionStatus_fn = function() {
@@ -545,7 +623,7 @@ var QtiCustomOperator = class extends i2 {
545
623
  __privateAdd(this, _operatorFunction);
546
624
  }
547
625
  render() {
548
- return x`<slot @slotchange=${this.handleSlotChange}></slot>`;
626
+ return T`<slot @slotchange=${this.handleSlotChange}></slot>`;
549
627
  }
550
628
  handleSlotChange() {
551
629
  const commentNode = Array.from(this.firstElementChild?.childNodes ?? []).find(
@@ -604,7 +682,7 @@ QtiCustomOperator = __decorateClass([
604
682
  // ../qti-elements/src/components/qti-feedback-block/qti-feedback-block.ts
605
683
  var QtiFeedbackBlock = class extends QtiFeedback {
606
684
  render() {
607
- return x` <slot part="feedback" class="feedback ${this.showStatus}"></slot> `;
685
+ return T` <slot part="feedback" class="feedback ${this.showStatus}"></slot> `;
608
686
  }
609
687
  connectedCallback() {
610
688
  super.connectedCallback();
@@ -630,7 +708,7 @@ QtiFeedbackBlock = __decorateClass([
630
708
  var QtiFeedbackInline = class extends QtiFeedback {
631
709
  constructor() {
632
710
  super(...arguments);
633
- this.render = () => x` <slot part="feedback" class="${o(this.showStatus)}"></slot> `;
711
+ this.render = () => T` <slot part="feedback" class="${o(this.showStatus)}"></slot> `;
634
712
  }
635
713
  connectedCallback() {
636
714
  super.connectedCallback();
@@ -652,7 +730,7 @@ QtiFeedbackInline = __decorateClass([
652
730
  // ../qti-elements/src/components/qti-modal-feedback/qti-modal-feedback.ts
653
731
  var QtiModalFeedback = class extends QtiFeedback {
654
732
  render() {
655
- return x`
733
+ return T`
656
734
  <dialog class="qti-dialog" part="feedback" ?open="${this.showStatus === "on"}">
657
735
  <slot></slot>
658
736
  <div style="margin-top: var(--qti-gap-size); text-align: center;">
@@ -744,7 +822,7 @@ var qti_item_body_styles_default = i`
744
822
  // ../qti-elements/src/components/qti-item-body/qti-item-body.ts
745
823
  var QtiItemBody = class extends i2 {
746
824
  render() {
747
- return x`<slot part="qti-rubric-blocks" name="qti-rubric-block"></slot><slot></slot>`;
825
+ return T`<slot part="qti-rubric-blocks" name="qti-rubric-block"></slot><slot></slot>`;
748
826
  }
749
827
  };
750
828
  QtiItemBody.styles = qti_item_body_styles_default;
@@ -753,11 +831,69 @@ QtiItemBody = __decorateClass([
753
831
  ], QtiItemBody);
754
832
 
755
833
  // ../qti-elements/src/components/qti-content-body/qti-content-body.ts
834
+ var _QtiContentBody_instances, expandMathVariables_fn, stringifyValue_fn;
756
835
  var QtiContentBody = class extends i2 {
836
+ constructor() {
837
+ super(...arguments);
838
+ __privateAdd(this, _QtiContentBody_instances);
839
+ }
757
840
  render() {
758
- return x`<slot></slot>`;
841
+ return T`<slot @slotchange=${__privateMethod(this, _QtiContentBody_instances, expandMathVariables_fn)}></slot>`;
842
+ }
843
+ connectedCallback() {
844
+ super.connectedCallback();
845
+ this.updateComplete.then(() => __privateMethod(this, _QtiContentBody_instances, expandMathVariables_fn).call(this));
846
+ }
847
+ updated(changedProperties) {
848
+ if (changedProperties.has("context")) {
849
+ __privateMethod(this, _QtiContentBody_instances, expandMathVariables_fn).call(this);
850
+ }
759
851
  }
760
852
  };
853
+ _QtiContentBody_instances = new WeakSet();
854
+ expandMathVariables_fn = function() {
855
+ const mathVariables = /* @__PURE__ */ new Map();
856
+ const templateVariables = (this.context?.variables ?? []).filter((variable) => variable.type === "template");
857
+ for (const variable of templateVariables) {
858
+ const templateVariable = variable;
859
+ if (templateVariable.mathVariable !== true || templateVariable.value === null || templateVariable.value === void 0) {
860
+ continue;
861
+ }
862
+ mathVariables.set(templateVariable.identifier, __privateMethod(this, _QtiContentBody_instances, stringifyValue_fn).call(this, templateVariable.value));
863
+ }
864
+ if (mathVariables.size === 0) {
865
+ return;
866
+ }
867
+ const mathIdentifiers = Array.from(this.querySelectorAll("*")).filter(
868
+ (element) => element.localName.toLowerCase() === "mi" || element.localName.toLowerCase() === "mn"
869
+ );
870
+ for (const element of mathIdentifiers) {
871
+ const identifier = element.getAttribute("data-qti-math-variable-source") ?? element.textContent?.trim() ?? "";
872
+ const value = mathVariables.get(identifier);
873
+ if (!value) {
874
+ continue;
875
+ }
876
+ if (element.localName.toLowerCase() === "mn") {
877
+ element.textContent = value;
878
+ element.setAttribute("data-qti-math-variable-source", identifier);
879
+ continue;
880
+ }
881
+ const replacement = document.createElement("mn");
882
+ replacement.textContent = value;
883
+ replacement.setAttribute("data-qti-math-variable-source", identifier);
884
+ element.replaceWith(replacement);
885
+ }
886
+ };
887
+ stringifyValue_fn = function(value) {
888
+ if (Array.isArray(value)) {
889
+ return value.join(" ");
890
+ }
891
+ return value?.toString() ?? "";
892
+ };
893
+ __decorateClass([
894
+ c({ context: itemContext, subscribe: true }),
895
+ r()
896
+ ], QtiContentBody.prototype, "context", 2);
761
897
  QtiContentBody = __decorateClass([
762
898
  t("qti-content-body")
763
899
  ], QtiContentBody);
@@ -790,7 +926,7 @@ var QtiRubricBlock = class extends i2 {
790
926
  });
791
927
  }
792
928
  render() {
793
- return x`<slot></slot>`;
929
+ return T`<slot></slot>`;
794
930
  }
795
931
  };
796
932
  QtiRubricBlock.styles = i`
@@ -884,7 +1020,7 @@ var QtiResponseDeclaration = class extends QtiVariableDeclaration {
884
1020
  }
885
1021
  render() {
886
1022
  const value = this.itemContext?.variables.find((v) => v.identifier === this.identifier)?.value;
887
- return x`${JSON.stringify(value, null, 2)}`;
1023
+ return T`${JSON.stringify(value, null, 2)}`;
888
1024
  }
889
1025
  connectedCallback() {
890
1026
  super.connectedCallback();
@@ -998,7 +1134,7 @@ var QtiOutcomeDeclaration = class extends QtiVariableDeclaration {
998
1134
  }
999
1135
  render() {
1000
1136
  const value = this.itemContext?.variables.find((v) => v.identifier === this.identifier)?.value;
1001
- return x`${JSON.stringify(value, null, 2)}`;
1137
+ return T`${JSON.stringify(value, null, 2)}`;
1002
1138
  }
1003
1139
  get interpolationTable() {
1004
1140
  const table = this.querySelector("qti-interpolation-table");
@@ -1134,7 +1270,7 @@ var QtiResponseProcessing = class extends i2 {
1134
1270
  __privateAdd(this, _QtiResponseProcessing_instances);
1135
1271
  }
1136
1272
  render() {
1137
- return x`<slot></slot>`;
1273
+ return T`<slot></slot>`;
1138
1274
  }
1139
1275
  process() {
1140
1276
  const assessmentItem = this.closest("qti-assessment-item");
@@ -1194,7 +1330,7 @@ var QtiTemplateDeclaration = class extends i2 {
1194
1330
  __privateAdd(this, _defaultValue, null);
1195
1331
  }
1196
1332
  render() {
1197
- return x`<slot></slot>`;
1333
+ return T`<slot></slot>`;
1198
1334
  }
1199
1335
  connectedCallback() {
1200
1336
  super.connectedCallback();
@@ -1298,6 +1434,124 @@ QtiTemplateDeclaration = __decorateClass([
1298
1434
  t("qti-template-declaration")
1299
1435
  ], QtiTemplateDeclaration);
1300
1436
 
1437
+ // ../qti-elements/src/components/qti-template-processing/qti-template-processing.ts
1438
+ var _maxIterations;
1439
+ var QtiTemplateProcessing = class extends i2 {
1440
+ constructor() {
1441
+ super(...arguments);
1442
+ __privateAdd(this, _maxIterations, 100);
1443
+ }
1444
+ // Prevent infinite loops in template constraints
1445
+ render() {
1446
+ return T`<slot></slot>`;
1447
+ }
1448
+ /**
1449
+ * Process template rules to set template variable values
1450
+ */
1451
+ process() {
1452
+ const assessmentItem = this.closest("qti-assessment-item");
1453
+ if (!assessmentItem) {
1454
+ console.warn("qti-template-processing must be inside qti-assessment-item");
1455
+ return;
1456
+ }
1457
+ let iterations = 0;
1458
+ let shouldReprocess = false;
1459
+ do {
1460
+ shouldReprocess = false;
1461
+ iterations++;
1462
+ if (iterations > __privateGet(this, _maxIterations)) {
1463
+ console.error("Template processing exceeded maximum iterations. Possible infinite loop.");
1464
+ break;
1465
+ }
1466
+ try {
1467
+ const rules = [...this.children];
1468
+ for (const rule of rules) {
1469
+ if (rule.tagName.toLowerCase() === "qti-template-constraint") {
1470
+ const constraintResult = rule.calculate();
1471
+ if (constraintResult === false) {
1472
+ shouldReprocess = true;
1473
+ break;
1474
+ }
1475
+ } else {
1476
+ rule.process();
1477
+ }
1478
+ }
1479
+ } catch (error) {
1480
+ console.error("Error during template processing:", error);
1481
+ break;
1482
+ }
1483
+ } while (shouldReprocess);
1484
+ this.dispatchEvent(
1485
+ new CustomEvent("qti-template-processing-complete", {
1486
+ bubbles: true,
1487
+ composed: true,
1488
+ detail: { iterations }
1489
+ })
1490
+ );
1491
+ }
1492
+ firstUpdated(_changedProperties) {
1493
+ if (this.getAttribute("template")) {
1494
+ console.info("Template processing with external template not yet implemented");
1495
+ }
1496
+ }
1497
+ };
1498
+ _maxIterations = new WeakMap();
1499
+ QtiTemplateProcessing.styles = [
1500
+ i`
1501
+ :host {
1502
+ display: none;
1503
+ }
1504
+ `
1505
+ ];
1506
+ QtiTemplateProcessing = __decorateClass([
1507
+ t("qti-template-processing")
1508
+ ], QtiTemplateProcessing);
1509
+
1510
+ // ../qti-elements/src/components/qti-template-constraint/qti-template-constraint.ts
1511
+ var QtiTemplateConstraint = class extends i2 {
1512
+ render() {
1513
+ return T`<slot></slot>`;
1514
+ }
1515
+ /**
1516
+ * Evaluates the constraint condition
1517
+ * @returns true if constraint is satisfied, false if template processing should restart
1518
+ */
1519
+ calculate() {
1520
+ const expressions = [...this.children];
1521
+ if (expressions.length !== 1) {
1522
+ console.error("qti-template-constraint must have exactly one child expression");
1523
+ return true;
1524
+ }
1525
+ try {
1526
+ const result = expressions[0].calculate();
1527
+ return Boolean(result);
1528
+ } catch (error) {
1529
+ console.error("Error evaluating template constraint:", error);
1530
+ return true;
1531
+ }
1532
+ }
1533
+ /**
1534
+ * Template constraints don't have sub-rules like conditions
1535
+ */
1536
+ getSubRules() {
1537
+ return [];
1538
+ }
1539
+ /**
1540
+ * Process the template constraint
1541
+ * @returns true if constraint is satisfied, false if template processing should restart
1542
+ */
1543
+ process() {
1544
+ const constraintSatisfied = this.calculate();
1545
+ if (!constraintSatisfied) {
1546
+ console.debug("Template constraint not satisfied, restarting template processing");
1547
+ }
1548
+ return constraintSatisfied;
1549
+ }
1550
+ };
1551
+ QtiTemplateConstraint = __decorateClass([
1552
+ t("qti-template-constraint")
1553
+ ], QtiTemplateConstraint);
1554
+
1301
1555
  // ../qti-elements/src/components/qti-context-declaration/qti-context-declaration.ts
1302
1556
  var QtiContextDeclaration = class extends i2 {
1303
1557
  constructor() {
@@ -1306,7 +1560,7 @@ var QtiContextDeclaration = class extends i2 {
1306
1560
  this.cardinality = "record";
1307
1561
  }
1308
1562
  render() {
1309
- return x`<slot></slot>`;
1563
+ return T`<slot></slot>`;
1310
1564
  }
1311
1565
  };
1312
1566
  QtiContextDeclaration.styles = [
@@ -1343,6 +1597,8 @@ export {
1343
1597
  QtiOutcomeDeclaration,
1344
1598
  QtiResponseProcessing,
1345
1599
  QtiTemplateDeclaration,
1600
+ QtiTemplateProcessing,
1601
+ QtiTemplateConstraint,
1346
1602
  QtiContextDeclaration
1347
1603
  };
1348
- //# sourceMappingURL=chunk-QUWFDFGZ.js.map
1604
+ //# sourceMappingURL=chunk-FFESMKSD.js.map