@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.
- package/README.md +6 -1
- package/dist/ims/ims-package.d.ts +1 -1
- package/dist/ims/ims-package.js +2 -2
- package/dist/ims/ims-package.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/qti/interactions/associate-interaction.d.ts +36 -0
- package/dist/qti/interactions/associate-interaction.js +46 -0
- package/dist/qti/interactions/associate-interaction.js.map +1 -0
- package/dist/qti/interactions/choice-interaction.d.ts +36 -0
- package/dist/qti/interactions/choice-interaction.js +43 -0
- package/dist/qti/interactions/choice-interaction.js.map +1 -0
- package/dist/qti/interactions/drawing-interaction.d.ts +25 -0
- package/dist/qti/interactions/drawing-interaction.js +30 -0
- package/dist/qti/interactions/drawing-interaction.js.map +1 -0
- package/dist/qti/interactions/end-attempt-interaction.d.ts +21 -0
- package/dist/qti/interactions/end-attempt-interaction.js +27 -0
- package/dist/qti/interactions/end-attempt-interaction.js.map +1 -0
- package/dist/qti/interactions/extended-text-interaction.d.ts +28 -0
- package/dist/qti/interactions/extended-text-interaction.js +34 -0
- package/dist/qti/interactions/extended-text-interaction.js.map +1 -0
- package/dist/qti/interactions/gap-match-interaction.d.ts +34 -0
- package/dist/qti/interactions/gap-match-interaction.js +46 -0
- package/dist/qti/interactions/gap-match-interaction.js.map +1 -0
- package/dist/qti/interactions/graphic-associate-interaction.d.ts +37 -0
- package/dist/qti/interactions/graphic-associate-interaction.js +47 -0
- package/dist/qti/interactions/graphic-associate-interaction.js.map +1 -0
- package/dist/qti/interactions/graphic-gap-match-interaction.d.ts +42 -0
- package/dist/qti/interactions/graphic-gap-match-interaction.js +64 -0
- package/dist/qti/interactions/graphic-gap-match-interaction.js.map +1 -0
- package/dist/qti/interactions/graphic-order-interaction.d.ts +28 -0
- package/dist/qti/interactions/graphic-order-interaction.js +46 -0
- package/dist/qti/interactions/graphic-order-interaction.js.map +1 -0
- package/dist/qti/interactions/hotspot-interaction.d.ts +41 -0
- package/dist/qti/interactions/hotspot-interaction.js +46 -0
- package/dist/qti/interactions/hotspot-interaction.js.map +1 -0
- package/dist/qti/interactions/hottext-interaction.d.ts +22 -0
- package/dist/qti/interactions/hottext-interaction.js +31 -0
- package/dist/qti/interactions/hottext-interaction.js.map +1 -0
- package/dist/qti/interactions/index.d.ts +63 -0
- package/dist/qti/interactions/index.js +64 -0
- package/dist/qti/interactions/index.js.map +1 -0
- package/dist/qti/interactions/inline-choice-interaction.d.ts +30 -0
- package/dist/qti/interactions/inline-choice-interaction.js +40 -0
- package/dist/qti/interactions/inline-choice-interaction.js.map +1 -0
- package/dist/qti/interactions/interaction.d.ts +20 -0
- package/dist/qti/interactions/interaction.js +24 -0
- package/dist/qti/interactions/interaction.js.map +1 -0
- package/dist/qti/interactions/match-interaction.d.ts +31 -0
- package/dist/qti/interactions/match-interaction.js +63 -0
- package/dist/qti/interactions/match-interaction.js.map +1 -0
- package/dist/qti/interactions/media-interaction.d.ts +31 -0
- package/dist/qti/interactions/media-interaction.js +36 -0
- package/dist/qti/interactions/media-interaction.js.map +1 -0
- package/dist/qti/interactions/order-interaction.d.ts +28 -0
- package/dist/qti/interactions/order-interaction.js +43 -0
- package/dist/qti/interactions/order-interaction.js.map +1 -0
- package/dist/qti/interactions/position-object-interaction.d.ts +36 -0
- package/dist/qti/interactions/position-object-interaction.js +43 -0
- package/dist/qti/interactions/position-object-interaction.js.map +1 -0
- package/dist/qti/interactions/select-point-interaction.d.ts +28 -0
- package/dist/qti/interactions/select-point-interaction.js +33 -0
- package/dist/qti/interactions/select-point-interaction.js.map +1 -0
- package/dist/qti/interactions/slider-interaction.d.ts +26 -0
- package/dist/qti/interactions/slider-interaction.js +32 -0
- package/dist/qti/interactions/slider-interaction.js.map +1 -0
- package/dist/qti/interactions/text-entry-interaction.d.ts +25 -0
- package/dist/qti/interactions/text-entry-interaction.js +31 -0
- package/dist/qti/interactions/text-entry-interaction.js.map +1 -0
- package/dist/qti/interactions/upload-interaction.d.ts +19 -0
- package/dist/qti/interactions/upload-interaction.js +25 -0
- package/dist/qti/interactions/upload-interaction.js.map +1 -0
- package/dist/qti/qti-element.d.ts +11 -0
- package/dist/qti/qti-element.js +29 -0
- package/dist/qti/qti-element.js.map +1 -0
- package/dist/qti/qti-item.d.ts +7 -3
- package/dist/qti/qti-item.js +18 -21
- package/dist/qti/qti-item.js.map +1 -1
- package/dist/qti/qti-test.d.ts +5 -3
- package/dist/qti/qti-test.js +8 -6
- package/dist/qti/qti-test.js.map +1 -1
- package/dist/utils/html.d.ts +2 -0
- package/dist/utils/html.js +15 -0
- package/dist/utils/html.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { fragment } from "xmlbuilder2";
|
|
2
|
+
import { QtiPromptInteraction, } from "./interaction";
|
|
3
|
+
import { appendHtmlFragment } from "../../utils/html";
|
|
4
|
+
/**
|
|
5
|
+
* Presents two sets of choices for candidates to match or associate with each other.
|
|
6
|
+
* Commonly used for matching terms with definitions or pairing related concepts.
|
|
7
|
+
*
|
|
8
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.be4ll1tm4t99
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const interaction = new MatchInteraction({
|
|
12
|
+
* responseIdentifier: "RESPONSE",
|
|
13
|
+
* sourceChoices: [
|
|
14
|
+
* { identifier: "S1", content: "Paris", matchMax: 1 },
|
|
15
|
+
* { identifier: "S2", content: "London", matchMax: 1 },
|
|
16
|
+
* ],
|
|
17
|
+
* targetChoices: [
|
|
18
|
+
* { identifier: "T1", content: "France", matchMax: 1 },
|
|
19
|
+
* { identifier: "T2", content: "England", matchMax: 1 },
|
|
20
|
+
* ],
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export class MatchInteraction extends QtiPromptInteraction {
|
|
24
|
+
constructor(options) {
|
|
25
|
+
super(options);
|
|
26
|
+
this.item = fragment().ele("qti-match-interaction", {
|
|
27
|
+
"response-identifier": options.responseIdentifier,
|
|
28
|
+
label: options.label,
|
|
29
|
+
shuffle: options.shuffle ? "true" : "false",
|
|
30
|
+
"min-associations": options.minAssociations?.toString(),
|
|
31
|
+
"max-associations": options.maxAssociations?.toString(),
|
|
32
|
+
});
|
|
33
|
+
const sourceSet = this.item.ele("qti-simple-match-set");
|
|
34
|
+
for (const choice of options.sourceChoices || []) {
|
|
35
|
+
const choiceEl = sourceSet.ele("qti-simple-associable-choice", {
|
|
36
|
+
identifier: choice.identifier,
|
|
37
|
+
"match-max": choice.matchMax?.toString(),
|
|
38
|
+
"match-min": choice.matchMin?.toString(),
|
|
39
|
+
"match-group": choice.matchGroup,
|
|
40
|
+
fixed: choice.fixed ? "true" : undefined,
|
|
41
|
+
"template-identifier": choice.templateIdentifier,
|
|
42
|
+
});
|
|
43
|
+
if (choice.content) {
|
|
44
|
+
appendHtmlFragment(choice.content, choiceEl);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const targetSet = this.item.ele("qti-simple-match-set");
|
|
48
|
+
for (const choice of options.targetChoices || []) {
|
|
49
|
+
const choiceEl = targetSet.ele("qti-simple-associable-choice", {
|
|
50
|
+
identifier: choice.identifier,
|
|
51
|
+
"match-max": choice.matchMax?.toString(),
|
|
52
|
+
"match-min": choice.matchMin?.toString(),
|
|
53
|
+
"match-group": choice.matchGroup,
|
|
54
|
+
fixed: choice.fixed ? "true" : undefined,
|
|
55
|
+
"template-identifier": choice.templateIdentifier,
|
|
56
|
+
});
|
|
57
|
+
if (choice.content) {
|
|
58
|
+
appendHtmlFragment(choice.content, choiceEl);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=match-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/match-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAUtD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,gBAAiB,SAAQ,oBAAoB;IACxD,YAAY,OAAgC;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,uBAAuB,EAAE;YAClD,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,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACxD,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,SAAS,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;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACxD,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,SAAS,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,31 @@
|
|
|
1
|
+
import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
|
|
2
|
+
export type MediaObjectOptions = {
|
|
3
|
+
data: string;
|
|
4
|
+
type: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
};
|
|
8
|
+
export type MediaInteractionOptions = QtiPromptInteractionOptions & {
|
|
9
|
+
autostart?: boolean;
|
|
10
|
+
minPlays?: number;
|
|
11
|
+
maxPlays?: number;
|
|
12
|
+
loop?: boolean;
|
|
13
|
+
object: MediaObjectOptions;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Presents audio or video content that candidates must engage with before responding.
|
|
17
|
+
* Used for listening comprehension, video analysis, or multimedia-based questions.
|
|
18
|
+
*
|
|
19
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.u9utgghwf8ck
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const interaction = new MediaInteraction({
|
|
23
|
+
* responseIdentifier: "RESPONSE",
|
|
24
|
+
* minPlays: 1,
|
|
25
|
+
* maxPlays: 3,
|
|
26
|
+
* object: { data: "audio.mp3", type: "audio/mpeg" },
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
export declare class MediaInteraction extends QtiPromptInteraction {
|
|
30
|
+
constructor(options: MediaInteractionOptions);
|
|
31
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { fragment } from "xmlbuilder2";
|
|
2
|
+
import { QtiPromptInteraction, } from "./interaction";
|
|
3
|
+
/**
|
|
4
|
+
* Presents audio or video content that candidates must engage with before responding.
|
|
5
|
+
* Used for listening comprehension, video analysis, or multimedia-based questions.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.u9utgghwf8ck
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const interaction = new MediaInteraction({
|
|
11
|
+
* responseIdentifier: "RESPONSE",
|
|
12
|
+
* minPlays: 1,
|
|
13
|
+
* maxPlays: 3,
|
|
14
|
+
* object: { data: "audio.mp3", type: "audio/mpeg" },
|
|
15
|
+
* });
|
|
16
|
+
*/
|
|
17
|
+
export class MediaInteraction extends QtiPromptInteraction {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
super(options);
|
|
20
|
+
this.item = fragment().ele("qti-media-interaction", {
|
|
21
|
+
"response-identifier": options.responseIdentifier,
|
|
22
|
+
label: options.label,
|
|
23
|
+
autostart: options.autostart ? "true" : undefined,
|
|
24
|
+
"min-plays": options.minPlays?.toString(),
|
|
25
|
+
"max-plays": options.maxPlays?.toString(),
|
|
26
|
+
loop: options.loop ? "true" : undefined,
|
|
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
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=media-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/media-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAiBvB;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,gBAAiB,SAAQ,oBAAoB;IACxD,YAAY,OAAgC;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,uBAAuB,EAAE;YAClD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YACjD,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE;YACzC,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE;YACzC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SACxC,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,28 @@
|
|
|
1
|
+
import { SimpleChoiceOptions } from "./choice-interaction";
|
|
2
|
+
import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
|
|
3
|
+
export type OrderInteractionOptions = QtiPromptInteractionOptions & {
|
|
4
|
+
shuffle?: boolean;
|
|
5
|
+
minChoices?: number;
|
|
6
|
+
maxChoices?: number;
|
|
7
|
+
orientation?: "horizontal" | "vertical";
|
|
8
|
+
choices?: SimpleChoiceOptions[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Presents a set of choices for candidates to arrange in a specific order or sequence.
|
|
12
|
+
* Used for ranking, sequencing, or prioritization questions.
|
|
13
|
+
*
|
|
14
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.4n8gips6tlv4
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const interaction = new OrderInteraction({
|
|
18
|
+
* responseIdentifier: "RESPONSE",
|
|
19
|
+
* choices: [
|
|
20
|
+
* { identifier: "A", content: "First step" },
|
|
21
|
+
* { identifier: "B", content: "Second step" },
|
|
22
|
+
* { identifier: "C", content: "Third step" },
|
|
23
|
+
* ],
|
|
24
|
+
* });
|
|
25
|
+
*/
|
|
26
|
+
export declare class OrderInteraction extends QtiPromptInteraction {
|
|
27
|
+
constructor(options: OrderInteractionOptions);
|
|
28
|
+
}
|
|
@@ -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 arrange in a specific order or sequence.
|
|
6
|
+
* Used for ranking, sequencing, or prioritization questions.
|
|
7
|
+
*
|
|
8
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.4n8gips6tlv4
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const interaction = new OrderInteraction({
|
|
12
|
+
* responseIdentifier: "RESPONSE",
|
|
13
|
+
* choices: [
|
|
14
|
+
* { identifier: "A", content: "First step" },
|
|
15
|
+
* { identifier: "B", content: "Second step" },
|
|
16
|
+
* { identifier: "C", content: "Third step" },
|
|
17
|
+
* ],
|
|
18
|
+
* });
|
|
19
|
+
*/
|
|
20
|
+
export class OrderInteraction extends QtiPromptInteraction {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
super(options);
|
|
23
|
+
this.item = fragment().ele("qti-order-interaction", {
|
|
24
|
+
"response-identifier": options.responseIdentifier,
|
|
25
|
+
label: options.label,
|
|
26
|
+
shuffle: options.shuffle ? "true" : "false",
|
|
27
|
+
"min-choices": options.minChoices?.toString(),
|
|
28
|
+
"max-choices": options.maxChoices?.toString(),
|
|
29
|
+
orientation: options.orientation,
|
|
30
|
+
});
|
|
31
|
+
for (const choice of options.choices || []) {
|
|
32
|
+
const choiceEl = this.item.ele("qti-simple-choice", {
|
|
33
|
+
identifier: choice.identifier,
|
|
34
|
+
fixed: choice.fixed ? "true" : undefined,
|
|
35
|
+
"template-identifier": choice.templateIdentifier,
|
|
36
|
+
});
|
|
37
|
+
if (choice.content) {
|
|
38
|
+
appendHtmlFragment(choice.content, choiceEl);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=order-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/order-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAUtD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,gBAAiB,SAAQ,oBAAoB;IACxD,YAAY,OAAgC;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,uBAAuB,EAAE;YAClD,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;SACjC,CAAC,CAAC;QAEH,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE;gBAClD,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,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 PositionObjectStageOptions = {
|
|
3
|
+
data: string;
|
|
4
|
+
type: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
};
|
|
8
|
+
export type PositionObjectOptions = {
|
|
9
|
+
data: string;
|
|
10
|
+
type: string;
|
|
11
|
+
width?: number;
|
|
12
|
+
height?: number;
|
|
13
|
+
};
|
|
14
|
+
export type PositionObjectInteractionOptions = QtiPromptInteractionOptions & {
|
|
15
|
+
centerPoint?: string;
|
|
16
|
+
minChoices?: number;
|
|
17
|
+
maxChoices?: number;
|
|
18
|
+
object: PositionObjectOptions;
|
|
19
|
+
positionObjectStage?: PositionObjectStageOptions;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Presents a movable object that candidates must position on a background stage.
|
|
23
|
+
* Used for placing items at specific coordinates on a canvas or diagram.
|
|
24
|
+
*
|
|
25
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.4jhs37jil26s
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const interaction = new PositionObjectInteraction({
|
|
29
|
+
* responseIdentifier: "RESPONSE",
|
|
30
|
+
* object: { data: "marker.png", type: "image/png", width: 20, height: 20 },
|
|
31
|
+
* positionObjectStage: { data: "map.png", type: "image/png", width: 400, height: 300 },
|
|
32
|
+
* });
|
|
33
|
+
*/
|
|
34
|
+
export declare class PositionObjectInteraction extends QtiPromptInteraction {
|
|
35
|
+
constructor(options: PositionObjectInteractionOptions);
|
|
36
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { fragment } from "xmlbuilder2";
|
|
2
|
+
import { QtiPromptInteraction, } from "./interaction";
|
|
3
|
+
/**
|
|
4
|
+
* Presents a movable object that candidates must position on a background stage.
|
|
5
|
+
* Used for placing items at specific coordinates on a canvas or diagram.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.4jhs37jil26s
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const interaction = new PositionObjectInteraction({
|
|
11
|
+
* responseIdentifier: "RESPONSE",
|
|
12
|
+
* object: { data: "marker.png", type: "image/png", width: 20, height: 20 },
|
|
13
|
+
* positionObjectStage: { data: "map.png", type: "image/png", width: 400, height: 300 },
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
export class PositionObjectInteraction extends QtiPromptInteraction {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super(options);
|
|
19
|
+
this.item = fragment().ele("qti-position-object-interaction", {
|
|
20
|
+
"response-identifier": options.responseIdentifier,
|
|
21
|
+
label: options.label,
|
|
22
|
+
"center-point": options.centerPoint,
|
|
23
|
+
"min-choices": options.minChoices?.toString(),
|
|
24
|
+
"max-choices": options.maxChoices?.toString(),
|
|
25
|
+
});
|
|
26
|
+
this.item.ele("object", {
|
|
27
|
+
data: options.object.data,
|
|
28
|
+
type: options.object.type,
|
|
29
|
+
width: options.object.width?.toString(),
|
|
30
|
+
height: options.object.height?.toString(),
|
|
31
|
+
});
|
|
32
|
+
if (options.positionObjectStage) {
|
|
33
|
+
const stage = this.item.ele("qti-position-object-stage");
|
|
34
|
+
stage.ele("object", {
|
|
35
|
+
data: options.positionObjectStage.data,
|
|
36
|
+
type: options.positionObjectStage.type,
|
|
37
|
+
width: options.positionObjectStage.width?.toString(),
|
|
38
|
+
height: options.positionObjectStage.height?.toString(),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=position-object-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"position-object-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/position-object-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAwBvB;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,yBAA0B,SAAQ,oBAAoB;IACjE,YAAY,OAAyC;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,iCAAiC,EAAE;YAC5D,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,OAAO,CAAC,WAAW;YACnC,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC7C,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;SAC9C,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,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE;gBAClB,IAAI,EAAE,OAAO,CAAC,mBAAmB,CAAC,IAAI;gBACtC,IAAI,EAAE,OAAO,CAAC,mBAAmB,CAAC,IAAI;gBACtC,KAAK,EAAE,OAAO,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE;gBACpD,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE;aACvD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
|
|
2
|
+
export type SelectPointObjectOptions = {
|
|
3
|
+
data: string;
|
|
4
|
+
type: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
};
|
|
8
|
+
export type SelectPointInteractionOptions = QtiPromptInteractionOptions & {
|
|
9
|
+
minChoices?: number;
|
|
10
|
+
maxChoices?: number;
|
|
11
|
+
object: SelectPointObjectOptions;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Presents an image where candidates select specific coordinate points.
|
|
15
|
+
* Used for identifying precise locations on maps, graphs, or diagrams.
|
|
16
|
+
*
|
|
17
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.ev30y6ze263d
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const interaction = new SelectPointInteraction({
|
|
21
|
+
* responseIdentifier: "RESPONSE",
|
|
22
|
+
* maxChoices: 1,
|
|
23
|
+
* object: { data: "graph.png", type: "image/png", width: 400, height: 300 },
|
|
24
|
+
* });
|
|
25
|
+
*/
|
|
26
|
+
export declare class SelectPointInteraction extends QtiPromptInteraction {
|
|
27
|
+
constructor(options: SelectPointInteractionOptions);
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { fragment } from "xmlbuilder2";
|
|
2
|
+
import { QtiPromptInteraction, } from "./interaction";
|
|
3
|
+
/**
|
|
4
|
+
* Presents an image where candidates select specific coordinate points.
|
|
5
|
+
* Used for identifying precise locations on maps, graphs, or diagrams.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.ev30y6ze263d
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const interaction = new SelectPointInteraction({
|
|
11
|
+
* responseIdentifier: "RESPONSE",
|
|
12
|
+
* maxChoices: 1,
|
|
13
|
+
* object: { data: "graph.png", type: "image/png", width: 400, height: 300 },
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
export class SelectPointInteraction extends QtiPromptInteraction {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super(options);
|
|
19
|
+
this.item = fragment().ele("qti-select-point-interaction", {
|
|
20
|
+
"response-identifier": options.responseIdentifier,
|
|
21
|
+
label: options.label,
|
|
22
|
+
"min-choices": options.minChoices?.toString(),
|
|
23
|
+
"max-choices": options.maxChoices?.toString(),
|
|
24
|
+
});
|
|
25
|
+
this.item.ele("object", {
|
|
26
|
+
data: options.object.data,
|
|
27
|
+
type: options.object.type,
|
|
28
|
+
width: options.object.width?.toString(),
|
|
29
|
+
height: options.object.height?.toString(),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=select-point-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-point-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/select-point-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAevB;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,sBAAuB,SAAQ,oBAAoB;IAC9D,YAAY,OAAsC;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,8BAA8B,EAAE;YACzD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC7C,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE;SAC9C,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,26 @@
|
|
|
1
|
+
import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
|
|
2
|
+
export type SliderInteractionOptions = QtiPromptInteractionOptions & {
|
|
3
|
+
lowerBound: number;
|
|
4
|
+
upperBound: number;
|
|
5
|
+
step?: number;
|
|
6
|
+
stepLabel?: boolean;
|
|
7
|
+
orientation?: "horizontal" | "vertical";
|
|
8
|
+
reverse?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Presents a slider control for candidates to select a numeric value within a range.
|
|
12
|
+
* Used for questions requiring numeric input, ratings, or scale-based responses.
|
|
13
|
+
*
|
|
14
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.s61xcrj4qcyj
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const interaction = new SliderInteraction({
|
|
18
|
+
* responseIdentifier: "RESPONSE",
|
|
19
|
+
* lowerBound: 0,
|
|
20
|
+
* upperBound: 100,
|
|
21
|
+
* step: 10,
|
|
22
|
+
* });
|
|
23
|
+
*/
|
|
24
|
+
export declare class SliderInteraction extends QtiPromptInteraction {
|
|
25
|
+
constructor(options: SliderInteractionOptions);
|
|
26
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { fragment } from "xmlbuilder2";
|
|
2
|
+
import { QtiPromptInteraction, } from "./interaction";
|
|
3
|
+
/**
|
|
4
|
+
* Presents a slider control for candidates to select a numeric value within a range.
|
|
5
|
+
* Used for questions requiring numeric input, ratings, or scale-based responses.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.s61xcrj4qcyj
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const interaction = new SliderInteraction({
|
|
11
|
+
* responseIdentifier: "RESPONSE",
|
|
12
|
+
* lowerBound: 0,
|
|
13
|
+
* upperBound: 100,
|
|
14
|
+
* step: 10,
|
|
15
|
+
* });
|
|
16
|
+
*/
|
|
17
|
+
export class SliderInteraction extends QtiPromptInteraction {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
super(options);
|
|
20
|
+
this.item = fragment().ele("qti-slider-interaction", {
|
|
21
|
+
"response-identifier": options.responseIdentifier,
|
|
22
|
+
label: options.label,
|
|
23
|
+
"lower-bound": options.lowerBound.toString(),
|
|
24
|
+
"upper-bound": options.upperBound.toString(),
|
|
25
|
+
step: options.step?.toString(),
|
|
26
|
+
"step-label": options.stepLabel ? "true" : undefined,
|
|
27
|
+
orientation: options.orientation,
|
|
28
|
+
reverse: options.reverse ? "true" : undefined,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=slider-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slider-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/slider-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAWvB;;;;;;;;;;;;;GAaG;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,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE;YAC5C,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE;YAC5C,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE;YAC9B,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YACpD,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { QtiInteraction, QtiInteractionOptions } from "./interaction";
|
|
2
|
+
export type TextEntryInteractionOptions = QtiInteractionOptions & {
|
|
3
|
+
stringIdentifier?: string;
|
|
4
|
+
expectedLength?: number;
|
|
5
|
+
placeholderText?: string;
|
|
6
|
+
format?: string;
|
|
7
|
+
patternMask?: string;
|
|
8
|
+
patternMaskMessage?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Presents a text input field for candidates to enter a short text response.
|
|
12
|
+
* Used for fill-in-the-blank or short answer questions embedded inline.
|
|
13
|
+
*
|
|
14
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.5bw8rpbotrcs
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const interaction = new TextEntryInteraction({
|
|
18
|
+
* responseIdentifier: "RESPONSE",
|
|
19
|
+
* expectedLength: 20,
|
|
20
|
+
* placeholderText: "Enter your answer",
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export declare class TextEntryInteraction extends QtiInteraction {
|
|
24
|
+
constructor(options: TextEntryInteractionOptions);
|
|
25
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { fragment } from "xmlbuilder2";
|
|
2
|
+
import { QtiInteraction } from "./interaction";
|
|
3
|
+
/**
|
|
4
|
+
* Presents a text input field for candidates to enter a short text response.
|
|
5
|
+
* Used for fill-in-the-blank or short answer questions embedded inline.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.5bw8rpbotrcs
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const interaction = new TextEntryInteraction({
|
|
11
|
+
* responseIdentifier: "RESPONSE",
|
|
12
|
+
* expectedLength: 20,
|
|
13
|
+
* placeholderText: "Enter your answer",
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
export class TextEntryInteraction extends QtiInteraction {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super(options);
|
|
19
|
+
this.item = fragment().ele("qti-text-entry-interaction", {
|
|
20
|
+
"response-identifier": options.responseIdentifier,
|
|
21
|
+
label: options.label,
|
|
22
|
+
"string-identifier": options.stringIdentifier,
|
|
23
|
+
"expected-length": options.expectedLength?.toString(),
|
|
24
|
+
"placeholder-text": options.placeholderText,
|
|
25
|
+
format: options.format,
|
|
26
|
+
"pattern-mask": options.patternMask,
|
|
27
|
+
"data-patternmask-message": options.patternMaskMessage,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=text-entry-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-entry-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/text-entry-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAyB,MAAM,eAAe,CAAC;AAWtE;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,oBAAqB,SAAQ,cAAc;IACtD,YAAY,OAAoC;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,4BAA4B,EAAE;YACvD,qBAAqB,EAAE,OAAO,CAAC,kBAAkB;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,mBAAmB,EAAE,OAAO,CAAC,gBAAgB;YAC7C,iBAAiB,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE;YACrD,kBAAkB,EAAE,OAAO,CAAC,eAAe;YAC3C,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,cAAc,EAAE,OAAO,CAAC,WAAW;YACnC,0BAA0B,EAAE,OAAO,CAAC,kBAAkB;SACvD,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { QtiPromptInteraction, QtiPromptInteractionOptions } from "./interaction";
|
|
2
|
+
export type UploadInteractionOptions = QtiPromptInteractionOptions & {
|
|
3
|
+
type?: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Allows candidates to upload a file as their response.
|
|
7
|
+
* Used for submitting documents, images, or other file-based answers.
|
|
8
|
+
*
|
|
9
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.qtnex0r52anx
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const interaction = new UploadInteraction({
|
|
13
|
+
* responseIdentifier: "RESPONSE",
|
|
14
|
+
* type: "application/pdf",
|
|
15
|
+
* });
|
|
16
|
+
*/
|
|
17
|
+
export declare class UploadInteraction extends QtiPromptInteraction {
|
|
18
|
+
constructor(options: UploadInteractionOptions);
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { fragment } from "xmlbuilder2";
|
|
2
|
+
import { QtiPromptInteraction, } from "./interaction";
|
|
3
|
+
/**
|
|
4
|
+
* Allows candidates to upload a file as their response.
|
|
5
|
+
* Used for submitting documents, images, or other file-based answers.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.imsglobal.org/spec/qti/v3p0/impl#h.qtnex0r52anx
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const interaction = new UploadInteraction({
|
|
11
|
+
* responseIdentifier: "RESPONSE",
|
|
12
|
+
* type: "application/pdf",
|
|
13
|
+
* });
|
|
14
|
+
*/
|
|
15
|
+
export class UploadInteraction extends QtiPromptInteraction {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
super(options);
|
|
18
|
+
this.item = fragment().ele("qti-upload-interaction", {
|
|
19
|
+
"response-identifier": options.responseIdentifier,
|
|
20
|
+
label: options.label,
|
|
21
|
+
type: options.type,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=upload-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-interaction.js","sourceRoot":"","sources":["../../../src/qti/interactions/upload-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAMvB;;;;;;;;;;;GAWG;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,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { XMLBuilder } from "xmlbuilder2/lib/interfaces";
|
|
2
|
+
export type NamespacedElementContent = string | {
|
|
3
|
+
[key: string]: NamespacedElementContent;
|
|
4
|
+
} | NamespacedElementContent[];
|
|
5
|
+
export declare abstract class QtiElement {
|
|
6
|
+
protected abstract getRootElement(): XMLBuilder;
|
|
7
|
+
buildXml(): string;
|
|
8
|
+
registerNamespace(prefix: string, uri: string): void;
|
|
9
|
+
addNamespacedElement(namespace: string, elementName: string, content: NamespacedElementContent, attributes?: Record<string, string>): void;
|
|
10
|
+
private appendContent;
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export class QtiElement {
|
|
2
|
+
buildXml() {
|
|
3
|
+
return this.getRootElement().end({ prettyPrint: true });
|
|
4
|
+
}
|
|
5
|
+
registerNamespace(prefix, uri) {
|
|
6
|
+
this.getRootElement().att(`xmlns:${prefix}`, uri);
|
|
7
|
+
}
|
|
8
|
+
addNamespacedElement(namespace, elementName, content, attributes) {
|
|
9
|
+
const element = this.getRootElement().ele(`${namespace}:${elementName}`, attributes);
|
|
10
|
+
this.appendContent(element, namespace, content);
|
|
11
|
+
}
|
|
12
|
+
appendContent(element, namespace, content) {
|
|
13
|
+
if (typeof content === "string") {
|
|
14
|
+
element.txt(content);
|
|
15
|
+
}
|
|
16
|
+
else if (Array.isArray(content)) {
|
|
17
|
+
for (const item of content) {
|
|
18
|
+
this.appendContent(element, namespace, item);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
for (const [key, value] of Object.entries(content)) {
|
|
23
|
+
const child = element.ele(`${namespace}:${key}`);
|
|
24
|
+
this.appendContent(child, namespace, value);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=qti-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-element.js","sourceRoot":"","sources":["../../src/qti/qti-element.ts"],"names":[],"mappings":"AAOA,MAAM,OAAgB,UAAU;IAGvB,QAAQ;QACb,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAEM,iBAAiB,CAAC,MAAc,EAAE,GAAW;QAClD,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,SAAS,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IAEM,oBAAoB,CACzB,SAAiB,EACjB,WAAmB,EACnB,OAAiC,EACjC,UAAmC;QAEnC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CACvC,GAAG,SAAS,IAAI,WAAW,EAAE,EAC7B,UAAU,CACX,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAEO,aAAa,CACnB,OAAmB,EACnB,SAAiB,EACjB,OAAiC;QAEjC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,GAAG,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
package/dist/qti/qti-item.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { XMLBuilder } from "xmlbuilder2/lib/interfaces";
|
|
2
|
+
import { QtiInteraction } from "./interactions/interaction";
|
|
3
|
+
import { QtiElement } from "./qti-element";
|
|
1
4
|
import { QtiTest } from "./qti-test";
|
|
2
5
|
import { QtiCardinality, QtiBaseType, QtiAudience } from "./types";
|
|
3
6
|
import { ImsPackage } from "../ims/ims-package";
|
|
@@ -35,7 +38,7 @@ export declare enum ResponseProcessingTemplate {
|
|
|
35
38
|
MapResponse = "https://purl.imsglobal.org/spec/qti/v3p0/rptemplates/map_response.xml",
|
|
36
39
|
MapResponsePoint = "https://purl.imsglobal.org/spec/qti/v3p0/rptemplates/map_response_point.xml"
|
|
37
40
|
}
|
|
38
|
-
export declare class QtiItem {
|
|
41
|
+
export declare class QtiItem extends QtiElement {
|
|
39
42
|
identifier: string;
|
|
40
43
|
adaptive?: boolean;
|
|
41
44
|
timeDependent?: boolean;
|
|
@@ -48,14 +51,15 @@ export declare class QtiItem {
|
|
|
48
51
|
private itemBody?;
|
|
49
52
|
private responseDeclarations;
|
|
50
53
|
constructor(options?: QtiItemOptions);
|
|
51
|
-
|
|
52
|
-
addToPackage(pkg: ImsPackage): void;
|
|
54
|
+
addToPackage(pkg: ImsPackage): Promise<void>;
|
|
53
55
|
addToTest(test: QtiTest): void;
|
|
54
56
|
private getOrCreateItemBody;
|
|
55
57
|
addItemBodyFromHtml(html: string): void;
|
|
58
|
+
addInteraction(interaction: QtiInteraction): void;
|
|
56
59
|
addPciInteraction(interaction: PciInteraction, externalModules?: boolean): void;
|
|
57
60
|
addResponseDeclaration(responseDeclaration?: ResponseDeclaration): void;
|
|
58
61
|
addCorrectResponse(identifier: string, values: string[]): void;
|
|
59
62
|
addResponseProcessing(template: ResponseProcessingTemplate): void;
|
|
60
63
|
addOutcomeDeclaration(outcomeDeclaration?: OutcomeDeclaration): void;
|
|
64
|
+
protected getRootElement(): XMLBuilder;
|
|
61
65
|
}
|