@examplary/qti 0.0.1 → 1.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 (86) hide show
  1. package/README.md +6 -1
  2. package/dist/ims/ims-package.d.ts +1 -1
  3. package/dist/ims/ims-package.js +2 -2
  4. package/dist/ims/ims-package.js.map +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/qti/interactions/associate-interaction.d.ts +36 -0
  9. package/dist/qti/interactions/associate-interaction.js +46 -0
  10. package/dist/qti/interactions/associate-interaction.js.map +1 -0
  11. package/dist/qti/interactions/choice-interaction.d.ts +36 -0
  12. package/dist/qti/interactions/choice-interaction.js +43 -0
  13. package/dist/qti/interactions/choice-interaction.js.map +1 -0
  14. package/dist/qti/interactions/drawing-interaction.d.ts +25 -0
  15. package/dist/qti/interactions/drawing-interaction.js +30 -0
  16. package/dist/qti/interactions/drawing-interaction.js.map +1 -0
  17. package/dist/qti/interactions/end-attempt-interaction.d.ts +21 -0
  18. package/dist/qti/interactions/end-attempt-interaction.js +27 -0
  19. package/dist/qti/interactions/end-attempt-interaction.js.map +1 -0
  20. package/dist/qti/interactions/extended-text-interaction.d.ts +28 -0
  21. package/dist/qti/interactions/extended-text-interaction.js +34 -0
  22. package/dist/qti/interactions/extended-text-interaction.js.map +1 -0
  23. package/dist/qti/interactions/gap-match-interaction.d.ts +34 -0
  24. package/dist/qti/interactions/gap-match-interaction.js +46 -0
  25. package/dist/qti/interactions/gap-match-interaction.js.map +1 -0
  26. package/dist/qti/interactions/graphic-associate-interaction.d.ts +37 -0
  27. package/dist/qti/interactions/graphic-associate-interaction.js +47 -0
  28. package/dist/qti/interactions/graphic-associate-interaction.js.map +1 -0
  29. package/dist/qti/interactions/graphic-gap-match-interaction.d.ts +42 -0
  30. package/dist/qti/interactions/graphic-gap-match-interaction.js +64 -0
  31. package/dist/qti/interactions/graphic-gap-match-interaction.js.map +1 -0
  32. package/dist/qti/interactions/graphic-order-interaction.d.ts +28 -0
  33. package/dist/qti/interactions/graphic-order-interaction.js +46 -0
  34. package/dist/qti/interactions/graphic-order-interaction.js.map +1 -0
  35. package/dist/qti/interactions/hotspot-interaction.d.ts +41 -0
  36. package/dist/qti/interactions/hotspot-interaction.js +46 -0
  37. package/dist/qti/interactions/hotspot-interaction.js.map +1 -0
  38. package/dist/qti/interactions/hottext-interaction.d.ts +22 -0
  39. package/dist/qti/interactions/hottext-interaction.js +31 -0
  40. package/dist/qti/interactions/hottext-interaction.js.map +1 -0
  41. package/dist/qti/interactions/index.d.ts +63 -0
  42. package/dist/qti/interactions/index.js +64 -0
  43. package/dist/qti/interactions/index.js.map +1 -0
  44. package/dist/qti/interactions/inline-choice-interaction.d.ts +30 -0
  45. package/dist/qti/interactions/inline-choice-interaction.js +40 -0
  46. package/dist/qti/interactions/inline-choice-interaction.js.map +1 -0
  47. package/dist/qti/interactions/interaction.d.ts +20 -0
  48. package/dist/qti/interactions/interaction.js +24 -0
  49. package/dist/qti/interactions/interaction.js.map +1 -0
  50. package/dist/qti/interactions/match-interaction.d.ts +31 -0
  51. package/dist/qti/interactions/match-interaction.js +63 -0
  52. package/dist/qti/interactions/match-interaction.js.map +1 -0
  53. package/dist/qti/interactions/media-interaction.d.ts +31 -0
  54. package/dist/qti/interactions/media-interaction.js +36 -0
  55. package/dist/qti/interactions/media-interaction.js.map +1 -0
  56. package/dist/qti/interactions/order-interaction.d.ts +28 -0
  57. package/dist/qti/interactions/order-interaction.js +43 -0
  58. package/dist/qti/interactions/order-interaction.js.map +1 -0
  59. package/dist/qti/interactions/position-object-interaction.d.ts +36 -0
  60. package/dist/qti/interactions/position-object-interaction.js +43 -0
  61. package/dist/qti/interactions/position-object-interaction.js.map +1 -0
  62. package/dist/qti/interactions/select-point-interaction.d.ts +28 -0
  63. package/dist/qti/interactions/select-point-interaction.js +33 -0
  64. package/dist/qti/interactions/select-point-interaction.js.map +1 -0
  65. package/dist/qti/interactions/slider-interaction.d.ts +26 -0
  66. package/dist/qti/interactions/slider-interaction.js +32 -0
  67. package/dist/qti/interactions/slider-interaction.js.map +1 -0
  68. package/dist/qti/interactions/text-entry-interaction.d.ts +25 -0
  69. package/dist/qti/interactions/text-entry-interaction.js +31 -0
  70. package/dist/qti/interactions/text-entry-interaction.js.map +1 -0
  71. package/dist/qti/interactions/upload-interaction.d.ts +19 -0
  72. package/dist/qti/interactions/upload-interaction.js +25 -0
  73. package/dist/qti/interactions/upload-interaction.js.map +1 -0
  74. package/dist/qti/qti-element.d.ts +11 -0
  75. package/dist/qti/qti-element.js +29 -0
  76. package/dist/qti/qti-element.js.map +1 -0
  77. package/dist/qti/qti-item.d.ts +7 -3
  78. package/dist/qti/qti-item.js +18 -21
  79. package/dist/qti/qti-item.js.map +1 -1
  80. package/dist/qti/qti-test.d.ts +5 -3
  81. package/dist/qti/qti-test.js +8 -6
  82. package/dist/qti/qti-test.js.map +1 -1
  83. package/dist/utils/html.d.ts +2 -0
  84. package/dist/utils/html.js +15 -0
  85. package/dist/utils/html.js.map +1 -0
  86. package/package.json +1 -1
package/README.md CHANGED
@@ -20,9 +20,14 @@ const item = new QtiItem({
20
20
  title: "Sample Question",
21
21
  });
22
22
 
23
- item.addItemBodyFromHtml("<p>What is 2 + 2?</p>");
24
23
  item.addResponseDeclaration({ identifier: "RESPONSE" });
25
24
  item.addCorrectResponse("RESPONSE", ["4"]);
25
+
26
+ item.addItemBodyFromHtml("<p>What is 2 + 2?</p>");
27
+ item.addInteraction(
28
+ new TextEntryInteraction({ responseIdentifier: "RESPONSE" }),
29
+ );
30
+
26
31
  item.addResponseProcessing(ResponseProcessingTemplate.MatchCorrect);
27
32
 
28
33
  item.addToTest(test);
@@ -21,7 +21,7 @@ export declare class ImsPackage {
21
21
  /**
22
22
  * Add a resource to the IMS Package, along with its associated files.
23
23
  */
24
- addResource(resource: ImsManifestResourceWithoutFiles, files: ImsPackageFile[]): void;
24
+ addResource(resource: ImsManifestResourceWithoutFiles, files: ImsPackageFile[]): Promise<void>;
25
25
  /**
26
26
  * Add a file directly to the final ZIP, without adding it to the manifest.
27
27
  * Can fetch from URL or add from data.
@@ -11,9 +11,9 @@ export class ImsPackage {
11
11
  /**
12
12
  * Add a resource to the IMS Package, along with its associated files.
13
13
  */
14
- addResource(resource, files) {
14
+ async addResource(resource, files) {
15
15
  for (const file of files) {
16
- this.addFileDirectly(file);
16
+ await this.addFileDirectly(file);
17
17
  }
18
18
  this.manifest.addResource({
19
19
  ...resource,
@@ -1 +1 @@
1
- {"version":3,"file":"ims-package.js","sourceRoot":"","sources":["../../src/ims/ims-package.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AAExB,OAAO,EACL,WAAW,GAGZ,MAAM,gBAAgB,CAAC;AA0BxB,MAAM,OAAO,UAAU;IAIrB;;OAEG;IACH,YAAY,eAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,WAAW,CAAC,eAAe,CAAC,CAAC;QACjD,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,WAAW,CACT,QAAyC,EACzC,KAAuB;QAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YACxB,GAAG,QAAQ;YACX,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;SACtD,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,IAAoB;QACxC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACb,iCAAiC,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,UAAU,EAAE,CACpE,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;YAE1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAE3D,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IACzD,CAAC;CACF"}
1
+ {"version":3,"file":"ims-package.js","sourceRoot":"","sources":["../../src/ims/ims-package.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AAExB,OAAO,EACL,WAAW,GAGZ,MAAM,gBAAgB,CAAC;AA0BxB,MAAM,OAAO,UAAU;IAIrB;;OAEG;IACH,YAAY,eAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,WAAW,CAAC,eAAe,CAAC,CAAC;QACjD,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CACf,QAAyC,EACzC,KAAuB;QAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YACxB,GAAG,QAAQ;YACX,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;SACtD,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,IAAoB;QACxC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACb,iCAAiC,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,UAAU,EAAE,CACpE,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;YAE1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAE3D,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IACzD,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from "./ims/ims-manifest";
2
2
  export * from "./ims/ims-package";
3
+ export * from "./qti/qti-element";
3
4
  export * from "./qti/qti-test";
4
5
  export * from "./qti/qti-item";
6
+ export * from "./qti/interactions";
5
7
  export * from "./qti/types";
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  export * from "./ims/ims-manifest";
2
2
  export * from "./ims/ims-package";
3
+ export * from "./qti/qti-element";
3
4
  export * from "./qti/qti-test";
4
5
  export * from "./qti/qti-item";
6
+ export * from "./qti/interactions";
5
7
  export * from "./qti/types";
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
2
+ export type SimpleAssociableChoiceOptions = {
3
+ identifier: string;
4
+ matchMax?: number;
5
+ matchMin?: number;
6
+ matchGroup?: string;
7
+ fixed?: boolean;
8
+ templateIdentifier?: string;
9
+ content?: string;
10
+ };
11
+ export type AssociateInteractionOptions = QtiPromptInteractionOptions & {
12
+ shuffle?: boolean;
13
+ minAssociations?: number;
14
+ maxAssociations?: number;
15
+ choices?: SimpleAssociableChoiceOptions[];
16
+ };
17
+ /**
18
+ * Presents a set of choices for candidates to pair or associate with each other.
19
+ * Unlike MatchInteraction, choices come from a single set and can be paired freely.
20
+ *
21
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.7cs7637r54vv
22
+ *
23
+ * @example
24
+ * const interaction = new AssociateInteraction({
25
+ * responseIdentifier: "RESPONSE",
26
+ * choices: [
27
+ * { identifier: "A", content: "Cat", matchMax: 1 },
28
+ * { identifier: "B", content: "Dog", matchMax: 1 },
29
+ * { identifier: "C", content: "Meow", matchMax: 1 },
30
+ * { identifier: "D", content: "Bark", matchMax: 1 },
31
+ * ],
32
+ * });
33
+ */
34
+ export declare class AssociateInteraction extends QtiPromptInteraction {
35
+ constructor(options: AssociateInteractionOptions);
36
+ }
@@ -0,0 +1,46 @@
1
+ import { fragment } from "xmlbuilder2";
2
+ import { QtiPromptInteraction, } from "./interaction";
3
+ import { appendHtmlFragment } from "../../utils/html";
4
+ /**
5
+ * Presents a set of choices for candidates to pair or associate with each other.
6
+ * Unlike MatchInteraction, choices come from a single set and can be paired freely.
7
+ *
8
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.7cs7637r54vv
9
+ *
10
+ * @example
11
+ * const interaction = new AssociateInteraction({
12
+ * responseIdentifier: "RESPONSE",
13
+ * choices: [
14
+ * { identifier: "A", content: "Cat", matchMax: 1 },
15
+ * { identifier: "B", content: "Dog", matchMax: 1 },
16
+ * { identifier: "C", content: "Meow", matchMax: 1 },
17
+ * { identifier: "D", content: "Bark", matchMax: 1 },
18
+ * ],
19
+ * });
20
+ */
21
+ export class AssociateInteraction extends QtiPromptInteraction {
22
+ constructor(options) {
23
+ super(options);
24
+ this.item = fragment().ele("qti-associate-interaction", {
25
+ "response-identifier": options.responseIdentifier,
26
+ label: options.label,
27
+ shuffle: options.shuffle ? "true" : "false",
28
+ "min-associations": options.minAssociations?.toString(),
29
+ "max-associations": options.maxAssociations?.toString(),
30
+ });
31
+ for (const choice of options.choices || []) {
32
+ const choiceEl = this.item.ele("qti-simple-associable-choice", {
33
+ identifier: choice.identifier,
34
+ "match-max": choice.matchMax?.toString(),
35
+ "match-min": choice.matchMin?.toString(),
36
+ "match-group": choice.matchGroup,
37
+ fixed: choice.fixed ? "true" : undefined,
38
+ "template-identifier": choice.templateIdentifier,
39
+ });
40
+ if (choice.content) {
41
+ appendHtmlFragment(choice.content, choiceEl);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ //# sourceMappingURL=associate-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"associate-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/associate-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAmBtD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,oBAAqB,SAAQ,oBAAoB;IAC5D,YAAY,OAAoC;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,2BAA2B,EAAE;YACtD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;YAC3C,kBAAkB,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,EAAE;YACvD,kBAAkB,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,EAAE;SACxD,CAAC,CAAC;QAEH,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,8BAA8B,EAAE;gBAC7D,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE;gBACxC,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE;gBACxC,aAAa,EAAE,MAAM,CAAC,UAAU;gBAChC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBACxC,qBAAqB,EAAE,MAAM,CAAC,kBAAkB;aACjD,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,kBAAkB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,36 @@
1
+ import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
2
+ export type SimpleChoiceOptions = {
3
+ identifier: string;
4
+ fixed?: boolean;
5
+ templateIdentifier?: string;
6
+ label?: string;
7
+ content?: string;
8
+ };
9
+ export type ChoiceInteractionOptions = QtiPromptInteractionOptions & {
10
+ shuffle?: boolean;
11
+ maxChoices?: number;
12
+ minChoices?: number;
13
+ orientation?: "horizontal" | "vertical";
14
+ minSelectionsMessage?: string;
15
+ maxSelectionsMessage?: string;
16
+ choices?: SimpleChoiceOptions[];
17
+ };
18
+ /**
19
+ * Presents a set of choices for candidates to select one or more options.
20
+ * Supports single-select (radio) or multi-select (checkbox) modes via maxChoices.
21
+ *
22
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.j9nu1oa1tu3b
23
+ *
24
+ * @example
25
+ * const interaction = new ChoiceInteraction({
26
+ * responseIdentifier: "RESPONSE",
27
+ * maxChoices: 1,
28
+ * choices: [
29
+ * { identifier: "A", content: "Option A" },
30
+ * { identifier: "B", content: "Option B" },
31
+ * ],
32
+ * });
33
+ */
34
+ export declare class ChoiceInteraction extends QtiPromptInteraction {
35
+ constructor(options: ChoiceInteractionOptions);
36
+ }
@@ -0,0 +1,43 @@
1
+ import { fragment } from "xmlbuilder2";
2
+ import { QtiPromptInteraction, } from "./interaction";
3
+ import { appendHtmlFragment } from "../../utils/html";
4
+ /**
5
+ * Presents a set of choices for candidates to select one or more options.
6
+ * Supports single-select (radio) or multi-select (checkbox) modes via maxChoices.
7
+ *
8
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.j9nu1oa1tu3b
9
+ *
10
+ * @example
11
+ * const interaction = new ChoiceInteraction({
12
+ * responseIdentifier: "RESPONSE",
13
+ * maxChoices: 1,
14
+ * choices: [
15
+ * { identifier: "A", content: "Option A" },
16
+ * { identifier: "B", content: "Option B" },
17
+ * ],
18
+ * });
19
+ */
20
+ export class ChoiceInteraction extends QtiPromptInteraction {
21
+ constructor(options) {
22
+ super(options);
23
+ this.item = fragment().ele("qti-choice-interaction", {
24
+ "response-identifier": options.responseIdentifier,
25
+ label: options.label,
26
+ shuffle: options.shuffle ? "true" : "false",
27
+ "max-choices": options.maxChoices?.toString(),
28
+ "min-choices": options.minChoices?.toString(),
29
+ orientation: options.orientation,
30
+ "data-min-selections-message": options.minSelectionsMessage,
31
+ "data-max-selections-message": options.maxSelectionsMessage,
32
+ });
33
+ for (const choice of options.choices || []) {
34
+ appendHtmlFragment(choice.content || "", this.item.ele("qti-simple-choice", {
35
+ identifier: choice.identifier,
36
+ fixed: choice.fixed ? "true" : "false",
37
+ "template-identifier": choice.templateIdentifier,
38
+ label: choice.label,
39
+ }));
40
+ }
41
+ }
42
+ }
43
+ //# sourceMappingURL=choice-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choice-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/choice-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAoBtD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,iBAAkB,SAAQ,oBAAoB;IACzD,YAAY,OAAiC;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,wBAAwB,EAAE;YACnD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;YAC3C,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC7C,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC7C,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,6BAA6B,EAAE,OAAO,CAAC,oBAAoB;YAC3D,6BAA6B,EAAE,OAAO,CAAC,oBAAoB;SAC5D,CAAC,CAAC;QAEH,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC3C,kBAAkB,CAChB,MAAM,CAAC,OAAO,IAAI,EAAE,EACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE;gBACjC,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;gBACtC,qBAAqB,EAAE,MAAM,CAAC,kBAAkB;gBAChD,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
2
+ export type DrawingObjectOptions = {
3
+ data: string;
4
+ type: string;
5
+ width?: number;
6
+ height?: number;
7
+ };
8
+ export type DrawingInteractionOptions = QtiPromptInteractionOptions & {
9
+ object: DrawingObjectOptions;
10
+ };
11
+ /**
12
+ * Presents a canvas where candidates can draw or annotate over a background image.
13
+ * Used for freeform drawing, labeling, or annotation tasks.
14
+ *
15
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.8yrkpwgsrs4b
16
+ *
17
+ * @example
18
+ * const interaction = new DrawingInteraction({
19
+ * responseIdentifier: "RESPONSE",
20
+ * object: { data: "canvas.png", type: "image/png", width: 400, height: 300 },
21
+ * });
22
+ */
23
+ export declare class DrawingInteraction extends QtiPromptInteraction {
24
+ constructor(options: DrawingInteractionOptions);
25
+ }
@@ -0,0 +1,30 @@
1
+ import { fragment } from "xmlbuilder2";
2
+ import { QtiPromptInteraction, } from "./interaction";
3
+ /**
4
+ * Presents a canvas where candidates can draw or annotate over a background image.
5
+ * Used for freeform drawing, labeling, or annotation tasks.
6
+ *
7
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.8yrkpwgsrs4b
8
+ *
9
+ * @example
10
+ * const interaction = new DrawingInteraction({
11
+ * responseIdentifier: "RESPONSE",
12
+ * object: { data: "canvas.png", type: "image/png", width: 400, height: 300 },
13
+ * });
14
+ */
15
+ export class DrawingInteraction extends QtiPromptInteraction {
16
+ constructor(options) {
17
+ super(options);
18
+ this.item = fragment().ele("qti-drawing-interaction", {
19
+ "response-identifier": options.responseIdentifier,
20
+ label: options.label,
21
+ });
22
+ this.item.ele("object", {
23
+ data: options.object.data,
24
+ type: options.object.type,
25
+ width: options.object.width?.toString(),
26
+ height: options.object.height?.toString(),
27
+ });
28
+ }
29
+ }
30
+ //# sourceMappingURL=drawing-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawing-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/drawing-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAavB;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,kBAAmB,SAAQ,oBAAoB;IAC1D,YAAY,OAAkC;QAC5C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,yBAAyB,EAAE;YACpD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE;YACtB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;YACzB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;YACzB,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE;YACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE;SAC1C,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import { QtiInteraction, QtiInteractionOptions } from "./interaction";
2
+ export type EndAttemptInteractionOptions = QtiInteractionOptions & {
3
+ title: string;
4
+ countAttempt?: boolean;
5
+ };
6
+ /**
7
+ * Presents a button that allows candidates to voluntarily end their assessment attempt.
8
+ * Used for "give up" or "submit early" functionality in adaptive testing scenarios.
9
+ *
10
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.b3g8rgbtuwqp
11
+ *
12
+ * @example
13
+ * const interaction = new EndAttemptInteraction({
14
+ * responseIdentifier: "RESPONSE",
15
+ * title: "Give Up",
16
+ * countAttempt: true,
17
+ * });
18
+ */
19
+ export declare class EndAttemptInteraction extends QtiInteraction {
20
+ constructor(options: EndAttemptInteractionOptions);
21
+ }
@@ -0,0 +1,27 @@
1
+ import { fragment } from "xmlbuilder2";
2
+ import { QtiInteraction } from "./interaction";
3
+ /**
4
+ * Presents a button that allows candidates to voluntarily end their assessment attempt.
5
+ * Used for "give up" or "submit early" functionality in adaptive testing scenarios.
6
+ *
7
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.b3g8rgbtuwqp
8
+ *
9
+ * @example
10
+ * const interaction = new EndAttemptInteraction({
11
+ * responseIdentifier: "RESPONSE",
12
+ * title: "Give Up",
13
+ * countAttempt: true,
14
+ * });
15
+ */
16
+ export class EndAttemptInteraction extends QtiInteraction {
17
+ constructor(options) {
18
+ super(options);
19
+ this.item = fragment().ele("qti-end-attempt-interaction", {
20
+ "response-identifier": options.responseIdentifier,
21
+ label: options.label,
22
+ title: options.title,
23
+ "count-attempt": options.countAttempt ? "true" : undefined,
24
+ });
25
+ }
26
+ }
27
+ //# sourceMappingURL=end-attempt-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"end-attempt-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/end-attempt-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAyB,MAAM,eAAe,CAAC;AAOtE;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,qBAAsB,SAAQ,cAAc;IACvD,YAAY,OAAqC;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,6BAA6B,EAAE;YACxD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,eAAe,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SAC3D,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
2
+ export type ExtendedTextInteractionOptions = QtiPromptInteractionOptions & {
3
+ base?: number;
4
+ stringIdentifier?: string;
5
+ expectedLength?: number;
6
+ patternMask?: string;
7
+ placeholderText?: string;
8
+ maxStrings?: number;
9
+ minStrings?: number;
10
+ expectedLines?: number;
11
+ format?: "plain" | "pre-formatted" | "xhtml";
12
+ };
13
+ /**
14
+ * Allows candidates to enter extended text responses, such as essays or paragraphs.
15
+ * Supports configurable length constraints, formatting options, and input validation.
16
+ *
17
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.omuxci3o5dmg
18
+ *
19
+ * @example
20
+ * const interaction = new ExtendedTextInteraction({
21
+ * responseIdentifier: "RESPONSE",
22
+ * expectedLines: 10,
23
+ * format: "plain",
24
+ * });
25
+ */
26
+ export declare class ExtendedTextInteraction extends QtiPromptInteraction {
27
+ constructor(options: ExtendedTextInteractionOptions);
28
+ }
@@ -0,0 +1,34 @@
1
+ import { fragment } from "xmlbuilder2";
2
+ import { QtiPromptInteraction, } from "./interaction";
3
+ /**
4
+ * Allows candidates to enter extended text responses, such as essays or paragraphs.
5
+ * Supports configurable length constraints, formatting options, and input validation.
6
+ *
7
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.omuxci3o5dmg
8
+ *
9
+ * @example
10
+ * const interaction = new ExtendedTextInteraction({
11
+ * responseIdentifier: "RESPONSE",
12
+ * expectedLines: 10,
13
+ * format: "plain",
14
+ * });
15
+ */
16
+ export class ExtendedTextInteraction extends QtiPromptInteraction {
17
+ constructor(options) {
18
+ super(options);
19
+ this.item = fragment().ele("qti-extended-text-interaction", {
20
+ "response-identifier": options.responseIdentifier,
21
+ label: options.label,
22
+ base: options.base?.toString(),
23
+ "string-identifier": options.stringIdentifier,
24
+ "expected-length": options.expectedLength?.toString(),
25
+ "pattern-mask": options.patternMask,
26
+ "placeholder-text": options.placeholderText,
27
+ "max-strings": options.maxStrings?.toString(),
28
+ "min-strings": options.minStrings?.toString(),
29
+ "expected-lines": options.expectedLines?.toString(),
30
+ format: options.format,
31
+ });
32
+ }
33
+ }
34
+ //# sourceMappingURL=extended-text-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-text-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/extended-text-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAcvB;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,uBAAwB,SAAQ,oBAAoB;IAC/D,YAAY,OAAuC;QACjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,+BAA+B,EAAE;YAC1D,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE;YAC9B,mBAAmB,EAAE,OAAO,CAAC,gBAAgB;YAC7C,iBAAiB,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE;YACrD,cAAc,EAAE,OAAO,CAAC,WAAW;YACnC,kBAAkB,EAAE,OAAO,CAAC,eAAe;YAC3C,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC7C,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC7C,gBAAgB,EAAE,OAAO,CAAC,aAAa,EAAE,QAAQ,EAAE;YACnD,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
2
+ export type GapTextOptions = {
3
+ identifier: string;
4
+ matchMax?: number;
5
+ matchMin?: number;
6
+ matchGroup?: string;
7
+ content?: string;
8
+ };
9
+ export type GapMatchInteractionOptions = QtiPromptInteractionOptions & {
10
+ shuffle?: boolean;
11
+ minAssociations?: number;
12
+ maxAssociations?: number;
13
+ gapTexts?: GapTextOptions[];
14
+ content?: string;
15
+ };
16
+ /**
17
+ * Presents candidates with a set of gaps within content and a set of choices to fill them.
18
+ * Candidates drag or select choices to match them with the appropriate gaps.
19
+ *
20
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.7sroqk3xl8e1
21
+ *
22
+ * @example
23
+ * const interaction = new GapMatchInteraction({
24
+ * responseIdentifier: "RESPONSE",
25
+ * gapTexts: [
26
+ * { identifier: "gap-1", content: "Paris" },
27
+ * { identifier: "gap-2", content: "London" },
28
+ * ],
29
+ * content: "<p>The capital of France is <qti-gap identifier='G1'/>.</p>",
30
+ * });
31
+ */
32
+ export declare class GapMatchInteraction extends QtiPromptInteraction {
33
+ constructor(options: GapMatchInteractionOptions);
34
+ }
@@ -0,0 +1,46 @@
1
+ import { fragment } from "xmlbuilder2";
2
+ import { QtiPromptInteraction, } from "./interaction";
3
+ import { appendHtmlFragment } from "../../utils/html";
4
+ /**
5
+ * Presents candidates with a set of gaps within content and a set of choices to fill them.
6
+ * Candidates drag or select choices to match them with the appropriate gaps.
7
+ *
8
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.7sroqk3xl8e1
9
+ *
10
+ * @example
11
+ * const interaction = new GapMatchInteraction({
12
+ * responseIdentifier: "RESPONSE",
13
+ * gapTexts: [
14
+ * { identifier: "gap-1", content: "Paris" },
15
+ * { identifier: "gap-2", content: "London" },
16
+ * ],
17
+ * content: "<p>The capital of France is <qti-gap identifier='G1'/>.</p>",
18
+ * });
19
+ */
20
+ export class GapMatchInteraction extends QtiPromptInteraction {
21
+ constructor(options) {
22
+ super(options);
23
+ this.item = fragment().ele("qti-gap-match-interaction", {
24
+ "response-identifier": options.responseIdentifier,
25
+ label: options.label,
26
+ shuffle: options.shuffle ? "true" : "false",
27
+ "min-associations": options.minAssociations?.toString(),
28
+ "max-associations": options.maxAssociations?.toString(),
29
+ });
30
+ for (const gapText of options.gapTexts || []) {
31
+ const gapTextEl = this.item.ele("qti-gap-text", {
32
+ identifier: gapText.identifier,
33
+ "match-max": gapText.matchMax?.toString(),
34
+ "match-min": gapText.matchMin?.toString(),
35
+ "match-group": gapText.matchGroup,
36
+ });
37
+ if (gapText.content) {
38
+ appendHtmlFragment(gapText.content, gapTextEl);
39
+ }
40
+ }
41
+ if (options.content) {
42
+ appendHtmlFragment(options.content, this.item);
43
+ }
44
+ }
45
+ }
46
+ //# sourceMappingURL=gap-match-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gap-match-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/gap-match-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAkBtD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,mBAAoB,SAAQ,oBAAoB;IAC3D,YAAY,OAAmC;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,2BAA2B,EAAE;YACtD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;YAC3C,kBAAkB,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,EAAE;YACvD,kBAAkB,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,EAAE;SACxD,CAAC,CAAC;QAEH,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE;gBAC9C,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE;gBACzC,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE;gBACzC,aAAa,EAAE,OAAO,CAAC,UAAU;aAClC,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import { HotspotShape, ObjectOptions } from "./hotspot-interaction";
2
+ import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
3
+ export { HotspotShape, ObjectOptions };
4
+ export type AssociableHotspotOptions = {
5
+ identifier: string;
6
+ shape: HotspotShape;
7
+ coords: string;
8
+ matchMax?: number;
9
+ matchMin?: number;
10
+ matchGroup?: string;
11
+ hotspotLabel?: string;
12
+ };
13
+ export type GraphicAssociateInteractionOptions = QtiPromptInteractionOptions & {
14
+ minAssociations?: number;
15
+ maxAssociations?: number;
16
+ object: ObjectOptions;
17
+ associableHotspots?: AssociableHotspotOptions[];
18
+ };
19
+ /**
20
+ * Presents an image with hotspots for candidates to associate or connect with each other.
21
+ * Used for drawing connections between points on a diagram or map.
22
+ *
23
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.acwq9g2z1cwt
24
+ *
25
+ * @example
26
+ * const interaction = new GraphicAssociateInteraction({
27
+ * responseIdentifier: "RESPONSE",
28
+ * object: { data: "circuit.png", type: "image/png", width: 400, height: 300 },
29
+ * associableHotspots: [
30
+ * { identifier: "A", shape: "circle", coords: "100,100,15", matchMax: 1 },
31
+ * { identifier: "B", shape: "circle", coords: "200,100,15", matchMax: 1 },
32
+ * ],
33
+ * });
34
+ */
35
+ export declare class GraphicAssociateInteraction extends QtiPromptInteraction {
36
+ constructor(options: GraphicAssociateInteractionOptions);
37
+ }
@@ -0,0 +1,47 @@
1
+ import { fragment } from "xmlbuilder2";
2
+ import { QtiPromptInteraction, } from "./interaction";
3
+ /**
4
+ * Presents an image with hotspots for candidates to associate or connect with each other.
5
+ * Used for drawing connections between points on a diagram or map.
6
+ *
7
+ * @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.acwq9g2z1cwt
8
+ *
9
+ * @example
10
+ * const interaction = new GraphicAssociateInteraction({
11
+ * responseIdentifier: "RESPONSE",
12
+ * object: { data: "circuit.png", type: "image/png", width: 400, height: 300 },
13
+ * associableHotspots: [
14
+ * { identifier: "A", shape: "circle", coords: "100,100,15", matchMax: 1 },
15
+ * { identifier: "B", shape: "circle", coords: "200,100,15", matchMax: 1 },
16
+ * ],
17
+ * });
18
+ */
19
+ export class GraphicAssociateInteraction extends QtiPromptInteraction {
20
+ constructor(options) {
21
+ super(options);
22
+ this.item = fragment().ele("qti-graphic-associate-interaction", {
23
+ "response-identifier": options.responseIdentifier,
24
+ label: options.label,
25
+ "min-associations": options.minAssociations?.toString(),
26
+ "max-associations": options.maxAssociations?.toString(),
27
+ });
28
+ this.item.ele("object", {
29
+ data: options.object.data,
30
+ type: options.object.type,
31
+ width: options.object.width?.toString(),
32
+ height: options.object.height?.toString(),
33
+ });
34
+ for (const hotspot of options.associableHotspots || []) {
35
+ this.item.ele("qti-associable-hotspot", {
36
+ identifier: hotspot.identifier,
37
+ shape: hotspot.shape,
38
+ coords: hotspot.coords,
39
+ "match-max": hotspot.matchMax?.toString(),
40
+ "match-min": hotspot.matchMin?.toString(),
41
+ "match-group": hotspot.matchGroup,
42
+ "hotspot-label": hotspot.hotspotLabel,
43
+ });
44
+ }
45
+ }
46
+ }
47
+ //# sourceMappingURL=graphic-associate-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphic-associate-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/graphic-associate-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAqBvB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,2BAA4B,SAAQ,oBAAoB;IACnE,YAAY,OAA2C;QACrD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,mCAAmC,EAAE;YAC9D,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,kBAAkB,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,EAAE;YACvD,kBAAkB,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,EAAE;SACxD,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE;YACtB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;YACzB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;YACzB,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE;YACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE;SAC1C,CAAC,CAAC;QAEH,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,kBAAkB,IAAI,EAAE,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE;gBACtC,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE;gBACzC,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE;gBACzC,aAAa,EAAE,OAAO,CAAC,UAAU;gBACjC,eAAe,EAAE,OAAO,CAAC,YAAY;aACtC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}