@qti-components/processing 1.3.2 → 1.3.3
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/dist/components/index.d.ts +18 -0
- package/dist/components/index.js +18 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/qti-and/qti-and.d.ts +8 -0
- package/dist/components/qti-and/qti-and.js +8 -0
- package/dist/components/qti-and/qti-and.js.map +1 -1
- package/dist/components/qti-any-n/qti-any-n.d.ts +15 -0
- package/dist/components/qti-any-n/qti-any-n.js +61 -0
- package/dist/components/qti-any-n/qti-any-n.js.map +1 -0
- package/dist/components/qti-container-size/qti-container-size.d.ts +5 -5
- package/dist/components/qti-container-size/qti-container-size.js +5 -5
- package/dist/components/qti-container-size/qti-container-size.js.map +1 -1
- package/dist/components/qti-correct/qti-correct.d.ts +8 -0
- package/dist/components/qti-correct/qti-correct.js +8 -0
- package/dist/components/qti-correct/qti-correct.js.map +1 -1
- package/dist/components/qti-default/qti-default.d.ts +5 -5
- package/dist/components/qti-default/qti-default.js +5 -5
- package/dist/components/qti-default/qti-default.js.map +1 -1
- package/dist/components/qti-delete/qti-delete.d.ts +8 -0
- package/dist/components/qti-delete/qti-delete.js +8 -0
- package/dist/components/qti-delete/qti-delete.js.map +1 -1
- package/dist/components/qti-divide/qti-divide.d.ts +13 -0
- package/dist/components/qti-divide/qti-divide.js +50 -0
- package/dist/components/qti-divide/qti-divide.js.map +1 -0
- package/dist/components/qti-duration-gte/qti-duration-gte.d.ts +5 -0
- package/dist/components/qti-duration-gte/qti-duration-gte.js +45 -0
- package/dist/components/qti-duration-gte/qti-duration-gte.js.map +1 -0
- package/dist/components/qti-duration-lt/qti-duration-lt.d.ts +13 -0
- package/dist/components/qti-duration-lt/qti-duration-lt.js +53 -0
- package/dist/components/qti-duration-lt/qti-duration-lt.js.map +1 -0
- package/dist/components/qti-equal/qti-equal.d.ts +9 -0
- package/dist/components/qti-equal/qti-equal.js +15 -0
- package/dist/components/qti-equal/qti-equal.js.map +1 -1
- package/dist/components/qti-equal-rounded/qti-equal-rounded.d.ts +9 -0
- package/dist/components/qti-equal-rounded/qti-equal-rounded.js +9 -0
- package/dist/components/qti-equal-rounded/qti-equal-rounded.js.map +1 -1
- package/dist/components/qti-field-value/qti-field-value.d.ts +8 -0
- package/dist/components/qti-field-value/qti-field-value.js +8 -0
- package/dist/components/qti-field-value/qti-field-value.js.map +1 -1
- package/dist/components/qti-index/qti-index.d.ts +8 -0
- package/dist/components/qti-index/qti-index.js +8 -0
- package/dist/components/qti-index/qti-index.js.map +1 -1
- package/dist/components/qti-inside/qti-inside.d.ts +7 -0
- package/dist/components/qti-inside/qti-inside.js +141 -0
- package/dist/components/qti-inside/qti-inside.js.map +1 -0
- package/dist/components/qti-integer-divide/qti-integer-divide.d.ts +13 -0
- package/dist/components/qti-integer-divide/qti-integer-divide.js +48 -0
- package/dist/components/qti-integer-divide/qti-integer-divide.js.map +1 -0
- package/dist/components/qti-integer-modulus/qti-integer-modulus.d.ts +13 -0
- package/dist/components/qti-integer-modulus/qti-integer-modulus.js +48 -0
- package/dist/components/qti-integer-modulus/qti-integer-modulus.js.map +1 -0
- package/dist/components/qti-integer-to-float/qti-integer-to-float.d.ts +12 -0
- package/dist/components/qti-integer-to-float/qti-integer-to-float.js +38 -0
- package/dist/components/qti-integer-to-float/qti-integer-to-float.js.map +1 -0
- package/dist/components/qti-is-null/qti-is-null.d.ts +8 -0
- package/dist/components/qti-is-null/qti-is-null.js +8 -2
- package/dist/components/qti-is-null/qti-is-null.js.map +1 -1
- package/dist/components/qti-lcm/qti-lcm.d.ts +5 -0
- package/dist/components/qti-lcm/qti-lcm.js +71 -0
- package/dist/components/qti-lcm/qti-lcm.js.map +1 -0
- package/dist/components/qti-map-response/qti-map-response.d.ts +8 -0
- package/dist/components/qti-map-response/qti-map-response.js +8 -0
- package/dist/components/qti-map-response/qti-map-response.js.map +1 -1
- package/dist/components/qti-match/qti-match.d.ts +8 -0
- package/dist/components/qti-match/qti-match.js +8 -0
- package/dist/components/qti-match/qti-match.js.map +1 -1
- package/dist/components/qti-max/qti-max.d.ts +13 -0
- package/dist/components/qti-max/qti-max.js +46 -0
- package/dist/components/qti-max/qti-max.js.map +1 -0
- package/dist/components/qti-min/qti-min.d.ts +13 -0
- package/dist/components/qti-min/qti-min.js +46 -0
- package/dist/components/qti-min/qti-min.js.map +1 -0
- package/dist/components/qti-not/qti-not.d.ts +8 -0
- package/dist/components/qti-not/qti-not.js +8 -0
- package/dist/components/qti-not/qti-not.js.map +1 -1
- package/dist/components/qti-or/qti-or.d.ts +8 -0
- package/dist/components/qti-or/qti-or.js +8 -0
- package/dist/components/qti-or/qti-or.js.map +1 -1
- package/dist/components/qti-pattern-match/qti-pattern-match.d.ts +13 -0
- package/dist/components/qti-pattern-match/qti-pattern-match.js +53 -0
- package/dist/components/qti-pattern-match/qti-pattern-match.js.map +1 -0
- package/dist/components/qti-product/qti-product.d.ts +8 -0
- package/dist/components/qti-product/qti-product.js +8 -0
- package/dist/components/qti-product/qti-product.js.map +1 -1
- package/dist/components/qti-repeat/qti-repeat.d.ts +15 -0
- package/dist/components/qti-repeat/qti-repeat.js +113 -0
- package/dist/components/qti-repeat/qti-repeat.js.map +1 -0
- package/dist/components/qti-round/qti-round.d.ts +4 -5
- package/dist/components/qti-round/qti-round.js +4 -5
- package/dist/components/qti-round/qti-round.js.map +1 -1
- package/dist/components/qti-set-correct-response/qti-set-correct-response.d.ts +24 -0
- package/dist/components/qti-set-correct-response/qti-set-correct-response.js +77 -0
- package/dist/components/qti-set-correct-response/qti-set-correct-response.js.map +1 -0
- package/dist/components/qti-set-template-value/qti-set-template-value.d.ts +24 -0
- package/dist/components/qti-set-template-value/qti-set-template-value.js +81 -0
- package/dist/components/qti-set-template-value/qti-set-template-value.js.map +1 -0
- package/dist/components/qti-stats-operator/qti-stats-operator.d.ts +15 -0
- package/dist/components/qti-stats-operator/qti-stats-operator.js +78 -0
- package/dist/components/qti-stats-operator/qti-stats-operator.js.map +1 -0
- package/dist/components/qti-substring/qti-substring.d.ts +13 -0
- package/dist/components/qti-substring/qti-substring.js +51 -0
- package/dist/components/qti-substring/qti-substring.js.map +1 -0
- package/dist/components/qti-subtract/qti-subtract.d.ts +8 -0
- package/dist/components/qti-subtract/qti-subtract.js +8 -0
- package/dist/components/qti-subtract/qti-subtract.js.map +1 -1
- package/dist/components/qti-sum/qti-sum.d.ts +8 -0
- package/dist/components/qti-sum/qti-sum.js +8 -0
- package/dist/components/qti-sum/qti-sum.js.map +1 -1
- package/dist/components/qti-truncate/qti-truncate.d.ts +12 -0
- package/dist/components/qti-truncate/qti-truncate.js +38 -0
- package/dist/components/qti-truncate/qti-truncate.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-integer-modulus.js","sourceRoot":"","sources":["../../../src/components/qti-integer-modulus/qti-integer-modulus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAkB,SAAQ,aAA4B;IACjD,SAAS;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,EAAwB,CAAC,CAAC;QAErF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,qBAAqB,CAAC,SAA6B;QACjD,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;gBAChE,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,IAAI,QAAQ,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvE,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACjE,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC5D,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAe,EAAE,EAAE,CAAC,CAAC;YAC5D,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBAC7D,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,CAAC","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-integer-modulus operator returns the remainder of integer division.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#integerModulus\n *\n * Takes 2 sub-expressions with base-type integer and single cardinality.\n * Returns the remainder (x % y).\n * Special cases: Returns NULL if any argument is NULL or if divisor is 0.\n */\nexport class QtiIntegerModulus extends QtiExpression<number | null> {\n public override getResult(): number | null {\n const values = this.#collectIntegerValues(this.getVariables() as ResponseVariable[]);\n\n if (values.length !== 2) {\n console.error('qti-integer-modulus requires exactly 2 integer values');\n return null;\n }\n\n if (values[1] === 0) {\n console.error('qti-integer-modulus: division by zero');\n return null;\n }\n\n return values[0] % values[1];\n }\n\n #collectIntegerValues(variables: ResponseVariable[]): number[] {\n const values: number[] = [];\n\n for (const variable of variables) {\n if (variable.baseType !== 'integer') {\n console.error('qti-integer-modulus requires integer base-type');\n return [];\n }\n if (variable.cardinality !== 'single' || Array.isArray(variable.value)) {\n console.error('qti-integer-modulus requires single cardinality');\n return [];\n }\n if (variable.value === null || variable.value === undefined) {\n return [];\n }\n\n const value = Number.parseInt(variable.value as string, 10);\n if (Number.isNaN(value)) {\n console.error('qti-integer-modulus requires integer values');\n return [];\n }\n values.push(value);\n }\n\n return values;\n }\n}\n\ncustomElements.define('qti-integer-modulus', QtiIntegerModulus);\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-integer-to-float operator converts an integer to a float.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#integerToFloat
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 sub-expression with base-type integer and single cardinality.
|
|
7
|
+
* Returns a value of base-type float with the same numeric value.
|
|
8
|
+
* Special cases: Returns NULL if sub-expression is NULL.
|
|
9
|
+
*/
|
|
10
|
+
export declare class QtiIntegerToFloat extends QtiExpression<number | null> {
|
|
11
|
+
getResult(): number | null;
|
|
12
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-integer-to-float operator converts an integer to a float.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#integerToFloat
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 sub-expression with base-type integer and single cardinality.
|
|
7
|
+
* Returns a value of base-type float with the same numeric value.
|
|
8
|
+
* Special cases: Returns NULL if sub-expression is NULL.
|
|
9
|
+
*/
|
|
10
|
+
export class QtiIntegerToFloat extends QtiExpression {
|
|
11
|
+
getResult() {
|
|
12
|
+
const variables = this.getVariables();
|
|
13
|
+
if (variables.length !== 1) {
|
|
14
|
+
console.error('qti-integer-to-float requires exactly one child expression');
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const variable = variables[0];
|
|
18
|
+
if (variable.baseType !== 'integer') {
|
|
19
|
+
console.error('qti-integer-to-float requires integer base-type');
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (variable.cardinality !== 'single' || Array.isArray(variable.value)) {
|
|
23
|
+
console.error('qti-integer-to-float requires single cardinality');
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (variable.value === null || variable.value === undefined) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const value = Number.parseInt(variable.value, 10);
|
|
30
|
+
if (Number.isNaN(value)) {
|
|
31
|
+
console.error('qti-integer-to-float requires an integer value');
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
customElements.define('qti-integer-to-float', QtiIntegerToFloat);
|
|
38
|
+
//# sourceMappingURL=qti-integer-to-float.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-integer-to-float.js","sourceRoot":"","sources":["../../../src/components/qti-integer-to-float/qti-integer-to-float.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAkB,SAAQ,aAA4B;IACjD,SAAS;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAwB,CAAC;QAE5D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;YAC5E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;YACjE,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,QAAQ,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAe,EAAE,EAAE,CAAC,CAAC;QAC5D,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAC","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-integer-to-float operator converts an integer to a float.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#integerToFloat\n *\n * Takes 1 sub-expression with base-type integer and single cardinality.\n * Returns a value of base-type float with the same numeric value.\n * Special cases: Returns NULL if sub-expression is NULL.\n */\nexport class QtiIntegerToFloat extends QtiExpression<number | null> {\n public override getResult(): number | null {\n const variables = this.getVariables() as ResponseVariable[];\n\n if (variables.length !== 1) {\n console.error('qti-integer-to-float requires exactly one child expression');\n return null;\n }\n\n const variable = variables[0];\n if (variable.baseType !== 'integer') {\n console.error('qti-integer-to-float requires integer base-type');\n return null;\n }\n if (variable.cardinality !== 'single' || Array.isArray(variable.value)) {\n console.error('qti-integer-to-float requires single cardinality');\n return null;\n }\n if (variable.value === null || variable.value === undefined) {\n return null;\n }\n\n const value = Number.parseInt(variable.value as string, 10);\n if (Number.isNaN(value)) {\n console.error('qti-integer-to-float requires an integer value');\n return null;\n }\n\n return value;\n }\n}\n\ncustomElements.define('qti-integer-to-float', QtiIntegerToFloat);\n"]}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-is-null operator checks if a variable or expression is missing its value.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#isNull
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 sub-expression with any base-type or cardinality.
|
|
7
|
+
* Returns true if the sub-expression is NULL, false otherwise.
|
|
8
|
+
* Special cases: Empty containers and empty strings are treated as NULL.
|
|
9
|
+
*/
|
|
2
10
|
export declare class QtiIsNull extends QtiExpression<boolean> {
|
|
3
11
|
getResult(): boolean;
|
|
4
12
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-is-null operator checks if a variable or expression is missing its value.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#isNull
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 sub-expression with any base-type or cardinality.
|
|
7
|
+
* Returns true if the sub-expression is NULL, false otherwise.
|
|
8
|
+
* Special cases: Empty containers and empty strings are treated as NULL.
|
|
9
|
+
*/
|
|
4
10
|
export class QtiIsNull extends QtiExpression {
|
|
5
11
|
getResult() {
|
|
6
12
|
if (this.children.length === 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-is-null.js","sourceRoot":"","sources":["../../../src/components/qti-is-null/qti-is-null.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD
|
|
1
|
+
{"version":3,"file":"qti-is-null.js","sourceRoot":"","sources":["../../../src/components/qti-is-null/qti-is-null.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,SAAU,SAAQ,aAAsB;IACnC,SAAS;QACvB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAwB,CAAC;YAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACjC,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC;QAC7D,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-is-null operator checks if a variable or expression is missing its value.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#isNull\n *\n * Takes 1 sub-expression with any base-type or cardinality.\n * Returns true if the sub-expression is NULL, false otherwise.\n * Special cases: Empty containers and empty strings are treated as NULL.\n */\nexport class QtiIsNull extends QtiExpression<boolean> {\n public override getResult(): boolean {\n if (this.children.length === 1) {\n const variables = this.getVariables() as ResponseVariable[];\n if (!variables) {\n return true;\n }\n const value = variables[0].value;\n return value == null || value == undefined || value === '';\n }\n console.error('unexpected number of children in qti Null');\n return null;\n }\n}\n\ncustomElements.define('qti-is-null', QtiIsNull);\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
export class QtiLcm extends QtiExpression {
|
|
3
|
+
getResult() {
|
|
4
|
+
const values = this.#collectIntegerValues(this.getVariables());
|
|
5
|
+
if (values.length === 0) {
|
|
6
|
+
console.error('qti-lcm requires at least one integer value');
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
return values.reduce((accumulator, value) => this.#lcm(accumulator, value));
|
|
10
|
+
}
|
|
11
|
+
#collectIntegerValues(variables) {
|
|
12
|
+
const values = [];
|
|
13
|
+
for (const variable of variables) {
|
|
14
|
+
if (variable.baseType !== 'integer') {
|
|
15
|
+
console.error('qti-lcm requires integer base-type');
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
if (variable.value === null || variable.value === undefined) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
if (variable.cardinality === 'single') {
|
|
22
|
+
if (Array.isArray(variable.value)) {
|
|
23
|
+
console.error('qti-lcm unexpected array value for single cardinality');
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const value = Number.parseInt(variable.value, 10);
|
|
27
|
+
if (Number.isNaN(value)) {
|
|
28
|
+
console.error('qti-lcm requires integer values');
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
values.push(value);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (variable.cardinality !== 'multiple' && variable.cardinality !== 'ordered') {
|
|
35
|
+
console.error('qti-lcm unsupported cardinality');
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
if (!Array.isArray(variable.value)) {
|
|
39
|
+
console.error('qti-lcm expected array value for container cardinality');
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
for (const entry of variable.value) {
|
|
43
|
+
const value = Number.parseInt(entry, 10);
|
|
44
|
+
if (Number.isNaN(value)) {
|
|
45
|
+
console.error('qti-lcm requires integer values');
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
values.push(value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return values;
|
|
52
|
+
}
|
|
53
|
+
#gcd(a, b) {
|
|
54
|
+
let left = Math.abs(a);
|
|
55
|
+
let right = Math.abs(b);
|
|
56
|
+
while (right !== 0) {
|
|
57
|
+
const remainder = left % right;
|
|
58
|
+
left = right;
|
|
59
|
+
right = remainder;
|
|
60
|
+
}
|
|
61
|
+
return left;
|
|
62
|
+
}
|
|
63
|
+
#lcm(a, b) {
|
|
64
|
+
if (a === 0 || b === 0) {
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
return Math.abs((a * b) / this.#gcd(a, b));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
customElements.define('qti-lcm', QtiLcm);
|
|
71
|
+
//# sourceMappingURL=qti-lcm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-lcm.js","sourceRoot":"","sources":["../../../src/components/qti-lcm/qti-lcm.ts"],"names":[],"mappings":"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","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\nexport class QtiLcm extends QtiExpression<number | null> {\n public override getResult(): number | null {\n const values = this.#collectIntegerValues(this.getVariables() as ResponseVariable[]);\n\n if (values.length === 0) {\n console.error('qti-lcm requires at least one integer value');\n return null;\n }\n\n return values.reduce((accumulator, value) => this.#lcm(accumulator, value));\n }\n\n #collectIntegerValues(variables: ResponseVariable[]): number[] {\n const values: number[] = [];\n\n for (const variable of variables) {\n if (variable.baseType !== 'integer') {\n console.error('qti-lcm requires integer base-type');\n return [];\n }\n if (variable.value === null || variable.value === undefined) {\n return [];\n }\n\n if (variable.cardinality === 'single') {\n if (Array.isArray(variable.value)) {\n console.error('qti-lcm unexpected array value for single cardinality');\n return [];\n }\n\n const value = Number.parseInt(variable.value as string, 10);\n if (Number.isNaN(value)) {\n console.error('qti-lcm requires integer values');\n return [];\n }\n values.push(value);\n continue;\n }\n\n if (variable.cardinality !== 'multiple' && variable.cardinality !== 'ordered') {\n console.error('qti-lcm unsupported cardinality');\n return [];\n }\n\n if (!Array.isArray(variable.value)) {\n console.error('qti-lcm expected array value for container cardinality');\n return [];\n }\n\n for (const entry of variable.value) {\n const value = Number.parseInt(entry as string, 10);\n if (Number.isNaN(value)) {\n console.error('qti-lcm requires integer values');\n return [];\n }\n values.push(value);\n }\n }\n\n return values;\n }\n\n #gcd(a: number, b: number): number {\n let left = Math.abs(a);\n let right = Math.abs(b);\n\n while (right !== 0) {\n const remainder = left % right;\n left = right;\n right = remainder;\n }\n\n return left;\n }\n\n #lcm(a: number, b: number): number {\n if (a === 0 || b === 0) {\n return 0;\n }\n\n return Math.abs((a * b) / this.#gcd(a, b));\n }\n}\n\ncustomElements.define('qti-lcm', QtiLcm);\n"]}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-map-response operator applies a mapping to a candidate's response.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#mapResponse
|
|
5
|
+
*
|
|
6
|
+
* Transforms the bound response variable using the declaration's qti-mapping.
|
|
7
|
+
* Returns a single float representing the mapped score (or sum of mapped values).
|
|
8
|
+
* Special cases: Returns 0.0 if response is NULL; counts identical values in containers once.
|
|
9
|
+
*/
|
|
2
10
|
export declare class QtiMapResponse extends QtiExpression<number> {
|
|
3
11
|
identifier: string;
|
|
4
12
|
getResult(): number;
|
|
@@ -7,6 +7,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { property } from 'lit/decorators.js';
|
|
8
8
|
import { QtiExpression } from '@qti-components/base';
|
|
9
9
|
import { ScoringHelper } from '@qti-components/base';
|
|
10
|
+
/**
|
|
11
|
+
* @summary The qti-map-response operator applies a mapping to a candidate's response.
|
|
12
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#mapResponse
|
|
13
|
+
*
|
|
14
|
+
* Transforms the bound response variable using the declaration's qti-mapping.
|
|
15
|
+
* Returns a single float representing the mapped score (or sum of mapped values).
|
|
16
|
+
* Special cases: Returns 0.0 if response is NULL; counts identical values in containers once.
|
|
17
|
+
*/
|
|
10
18
|
export class QtiMapResponse extends QtiExpression {
|
|
11
19
|
getResult() {
|
|
12
20
|
const response = this.context.variables.find(r => r.identifier === this.identifier);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-map-response.js","sourceRoot":"","sources":["../../../src/components/qti-map-response/qti-map-response.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { QtiExpression } from '@qti-components/base';\nimport { ScoringHelper } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\nexport class QtiMapResponse extends QtiExpression<number> {\n @property({ type: String }) identifier: string;\n\n public override getResult(): number {\n const response: ResponseVariable = this.context.variables.find(r => r.identifier === this.identifier);\n if (!response || !response.mapping) {\n console.error(`Response ${this.identifier} can not be found`);\n return null;\n }\n const mapping = response.mapping;\n const candidateResponses = !Array.isArray(response.value) ? [response.value] : response.value;\n let result = 0;\n for (const candidateResponse of candidateResponses) {\n const mappedValues = mapping.mapEntries.filter(entry => {\n if (response.baseType === 'string' && !entry.caseSensitive) {\n return ScoringHelper.compareSingleValues(\n entry.mapKey.toLowerCase(),\n candidateResponse.toLowerCase(),\n response.baseType\n );\n } else {\n return ScoringHelper.compareSingleValues(entry.mapKey, candidateResponse, response.baseType);\n }\n });\n // now find the mapped value with the highest value (if there are multiple)\n const mappedValue = mappedValues.reduce(\n (prev, current) => (prev.mappedValue > current.mappedValue ? prev : current),\n mappedValues.length > 0 ? mappedValues[0] : { mapKey: null, mappedValue: null } // Use the first element instead of a manual initial value\n );\n if (!(mappedValue === null || mappedValue.mappedValue == undefined)) {\n result += mappedValue.mappedValue;\n } else {\n result += mapping.defaultValue;\n }\n }\n if (mapping?.lowerBound !== null && mapping?.lowerBound !== undefined) {\n result = Math.max(mapping.lowerBound, result);\n }\n if (mapping?.upperBound !== null && mapping?.upperBound !== undefined) {\n result = Math.min(mapping.upperBound, result);\n }\n return result;\n }\n}\n\ncustomElements.define('qti-map-response', QtiMapResponse);\n"]}
|
|
1
|
+
{"version":3,"file":"qti-map-response.js","sourceRoot":"","sources":["../../../src/components/qti-map-response/qti-map-response.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { QtiExpression } from '@qti-components/base';\nimport { ScoringHelper } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-map-response operator applies a mapping to a candidate's response.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#mapResponse\n *\n * Transforms the bound response variable using the declaration's qti-mapping.\n * Returns a single float representing the mapped score (or sum of mapped values).\n * Special cases: Returns 0.0 if response is NULL; counts identical values in containers once.\n */\nexport class QtiMapResponse extends QtiExpression<number> {\n @property({ type: String }) identifier: string;\n\n public override getResult(): number {\n const response: ResponseVariable = this.context.variables.find(r => r.identifier === this.identifier);\n if (!response || !response.mapping) {\n console.error(`Response ${this.identifier} can not be found`);\n return null;\n }\n const mapping = response.mapping;\n const candidateResponses = !Array.isArray(response.value) ? [response.value] : response.value;\n let result = 0;\n for (const candidateResponse of candidateResponses) {\n const mappedValues = mapping.mapEntries.filter(entry => {\n if (response.baseType === 'string' && !entry.caseSensitive) {\n return ScoringHelper.compareSingleValues(\n entry.mapKey.toLowerCase(),\n candidateResponse.toLowerCase(),\n response.baseType\n );\n } else {\n return ScoringHelper.compareSingleValues(entry.mapKey, candidateResponse, response.baseType);\n }\n });\n // now find the mapped value with the highest value (if there are multiple)\n const mappedValue = mappedValues.reduce(\n (prev, current) => (prev.mappedValue > current.mappedValue ? prev : current),\n mappedValues.length > 0 ? mappedValues[0] : { mapKey: null, mappedValue: null } // Use the first element instead of a manual initial value\n );\n if (!(mappedValue === null || mappedValue.mappedValue == undefined)) {\n result += mappedValue.mappedValue;\n } else {\n result += mapping.defaultValue;\n }\n }\n if (mapping?.lowerBound !== null && mapping?.lowerBound !== undefined) {\n result = Math.max(mapping.lowerBound, result);\n }\n if (mapping?.upperBound !== null && mapping?.upperBound !== undefined) {\n result = Math.min(mapping.upperBound, result);\n }\n return result;\n }\n}\n\ncustomElements.define('qti-map-response', QtiMapResponse);\n"]}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
2
|
import type { ResponseVariable } from '@qti-components/base';
|
|
3
|
+
/**
|
|
4
|
+
* @summary The qti-match operator compares two expressions for exact value equality.
|
|
5
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#match
|
|
6
|
+
*
|
|
7
|
+
* Takes 2 sub-expressions which must have the same base-type and cardinality.
|
|
8
|
+
* Returns true if they represent the same value, false otherwise.
|
|
9
|
+
* Special cases: Must not be used for float or duration types; returns NULL if any argument is NULL.
|
|
10
|
+
*/
|
|
3
11
|
export declare class QtiMatch extends QtiExpression<boolean> {
|
|
4
12
|
getResult(): boolean;
|
|
5
13
|
static match(valueToMap: ResponseVariable, correctValueInfo: ResponseVariable): boolean;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { ScoringHelper } from '@qti-components/base';
|
|
2
2
|
import { QtiExpression } from '@qti-components/base';
|
|
3
|
+
/**
|
|
4
|
+
* @summary The qti-match operator compares two expressions for exact value equality.
|
|
5
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#match
|
|
6
|
+
*
|
|
7
|
+
* Takes 2 sub-expressions which must have the same base-type and cardinality.
|
|
8
|
+
* Returns true if they represent the same value, false otherwise.
|
|
9
|
+
* Special cases: Must not be used for float or duration types; returns NULL if any argument is NULL.
|
|
10
|
+
*/
|
|
3
11
|
export class QtiMatch extends QtiExpression {
|
|
4
12
|
//PK : FIXME.
|
|
5
13
|
// This was a little experiment if we could call the match function as a static function,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-match.js","sourceRoot":"","sources":["../../../src/components/qti-match/qti-match.ts"],"names":[],"mappings":"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","sourcesContent":["import { ScoringHelper } from '@qti-components/base';\nimport { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\nexport class QtiMatch extends QtiExpression<boolean> {\n //PK : FIXME.\n // This was a little experiment if we could call the match function as a static function,\n // This can be used for all kind of things, but now especially for use in\n // qti-response-condition-script\n // in which we pass the expressions as pure functions, and hope for the best.\n // SADLY, the getVariables throws roet in de eten.. weet nog niet precies hoe deze werkt.\n // Maar ik ga erin duiken.\n public override getResult() {\n if (this.children.length === 2) {\n const values = this.getVariables() as ResponseVariable[];\n const valueToMap = values[0];\n const correctValueInfo = values[1];\n return QtiMatch.match(valueToMap, correctValueInfo);\n }\n\n console.error('unexpected number of children in match');\n return null;\n }\n\n public static match(valueToMap: ResponseVariable, correctValueInfo: ResponseVariable) {\n if (valueToMap.value === null) return false;\n switch (correctValueInfo.cardinality) {\n case 'single': {\n if (Array.isArray(valueToMap.value) || Array.isArray(correctValueInfo.value)) {\n console.error('unexpected cardinality in qti match');\n return false;\n }\n return ScoringHelper.compareSingleValues(\n valueToMap.value?.toString(),\n correctValueInfo.value.toString(),\n correctValueInfo.baseType\n );\n }\n\n case 'ordered': {\n if (!Array.isArray(valueToMap.value) || !Array.isArray(correctValueInfo.value)) {\n console.error('unexpected cardinality in qti match');\n return false;\n }\n if (valueToMap.value.length !== correctValueInfo.value.length) {\n return false;\n }\n for (let i = 0; i < valueToMap.value.length; i++) {\n const result = ScoringHelper.compareSingleValues(\n correctValueInfo.value[i],\n valueToMap.value[i],\n correctValueInfo.baseType\n );\n if (!result) {\n return false;\n }\n }\n return true;\n }\n\n case 'multiple': {\n if (!Array.isArray(valueToMap.value) || !Array.isArray(correctValueInfo.value)) {\n console.error('unexpected cardinality in qti match');\n return false;\n }\n if (valueToMap.value.length !== correctValueInfo.value.length) {\n return false;\n }\n let answerIndex = 0;\n for (const correctAnswer of correctValueInfo.value) {\n let matchingValue: string | null = null;\n const arr = [...valueToMap.value];\n for (const mv of arr) {\n const result = ScoringHelper.compareSingleValues(correctAnswer, mv, correctValueInfo.baseType);\n if (result) {\n matchingValue = mv;\n break;\n }\n }\n if (matchingValue !== null) {\n (arr as string[]).splice(arr.indexOf(matchingValue), 1);\n } else {\n return false;\n }\n answerIndex++;\n }\n return true;\n }\n\n default:\n console.error('unexpected cardinality in qti match');\n return false;\n }\n }\n}\n\ncustomElements.define('qti-match', QtiMatch);\n"]}
|
|
1
|
+
{"version":3,"file":"qti-match.js","sourceRoot":"","sources":["../../../src/components/qti-match/qti-match.ts"],"names":[],"mappings":"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","sourcesContent":["import { ScoringHelper } from '@qti-components/base';\nimport { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-match operator compares two expressions for exact value equality.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#match\n *\n * Takes 2 sub-expressions which must have the same base-type and cardinality.\n * Returns true if they represent the same value, false otherwise.\n * Special cases: Must not be used for float or duration types; returns NULL if any argument is NULL.\n */\nexport class QtiMatch extends QtiExpression<boolean> {\n //PK : FIXME.\n // This was a little experiment if we could call the match function as a static function,\n // This can be used for all kind of things, but now especially for use in\n // qti-response-condition-script\n // in which we pass the expressions as pure functions, and hope for the best.\n // SADLY, the getVariables throws roet in de eten.. weet nog niet precies hoe deze werkt.\n // Maar ik ga erin duiken.\n public override getResult() {\n if (this.children.length === 2) {\n const values = this.getVariables() as ResponseVariable[];\n const valueToMap = values[0];\n const correctValueInfo = values[1];\n return QtiMatch.match(valueToMap, correctValueInfo);\n }\n\n console.error('unexpected number of children in match');\n return null;\n }\n\n public static match(valueToMap: ResponseVariable, correctValueInfo: ResponseVariable) {\n if (valueToMap.value === null) return false;\n switch (correctValueInfo.cardinality) {\n case 'single': {\n if (Array.isArray(valueToMap.value) || Array.isArray(correctValueInfo.value)) {\n console.error('unexpected cardinality in qti match');\n return false;\n }\n return ScoringHelper.compareSingleValues(\n valueToMap.value?.toString(),\n correctValueInfo.value.toString(),\n correctValueInfo.baseType\n );\n }\n\n case 'ordered': {\n if (!Array.isArray(valueToMap.value) || !Array.isArray(correctValueInfo.value)) {\n console.error('unexpected cardinality in qti match');\n return false;\n }\n if (valueToMap.value.length !== correctValueInfo.value.length) {\n return false;\n }\n for (let i = 0; i < valueToMap.value.length; i++) {\n const result = ScoringHelper.compareSingleValues(\n correctValueInfo.value[i],\n valueToMap.value[i],\n correctValueInfo.baseType\n );\n if (!result) {\n return false;\n }\n }\n return true;\n }\n\n case 'multiple': {\n if (!Array.isArray(valueToMap.value) || !Array.isArray(correctValueInfo.value)) {\n console.error('unexpected cardinality in qti match');\n return false;\n }\n if (valueToMap.value.length !== correctValueInfo.value.length) {\n return false;\n }\n let answerIndex = 0;\n for (const correctAnswer of correctValueInfo.value) {\n let matchingValue: string | null = null;\n const arr = [...valueToMap.value];\n for (const mv of arr) {\n const result = ScoringHelper.compareSingleValues(correctAnswer, mv, correctValueInfo.baseType);\n if (result) {\n matchingValue = mv;\n break;\n }\n }\n if (matchingValue !== null) {\n (arr as string[]).splice(arr.indexOf(matchingValue), 1);\n } else {\n return false;\n }\n answerIndex++;\n }\n return true;\n }\n\n default:\n console.error('unexpected cardinality in qti match');\n return false;\n }\n }\n}\n\ncustomElements.define('qti-match', QtiMatch);\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-max operator finds the largest value in a numerical set.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#max
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 or more numerical sub-expressions of any cardinality.
|
|
7
|
+
* Returns the largest value in the collection.
|
|
8
|
+
* Special cases: Returns NULL if any argument is NULL or non-numerical.
|
|
9
|
+
*/
|
|
10
|
+
export declare class QtiMax extends QtiExpression<number | null> {
|
|
11
|
+
#private;
|
|
12
|
+
getResult(): number | null;
|
|
13
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-max operator finds the largest value in a numerical set.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#max
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 or more numerical sub-expressions of any cardinality.
|
|
7
|
+
* Returns the largest value in the collection.
|
|
8
|
+
* Special cases: Returns NULL if any argument is NULL or non-numerical.
|
|
9
|
+
*/
|
|
10
|
+
export class QtiMax extends QtiExpression {
|
|
11
|
+
getResult() {
|
|
12
|
+
const values = this.#collectNumericValues(this.getVariables());
|
|
13
|
+
if (values.length === 0) {
|
|
14
|
+
console.warn('qti-max: no numeric values provided');
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return Math.max(...values);
|
|
18
|
+
}
|
|
19
|
+
#collectNumericValues(variables) {
|
|
20
|
+
const values = [];
|
|
21
|
+
for (const variable of variables) {
|
|
22
|
+
if (!variable) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const pushValue = (raw) => {
|
|
26
|
+
if (raw === null || raw === undefined) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const numValue = parseFloat(raw.toString());
|
|
30
|
+
if (Number.isNaN(numValue)) {
|
|
31
|
+
console.warn('qti-max: non-numeric value encountered');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
values.push(numValue);
|
|
35
|
+
};
|
|
36
|
+
if (Array.isArray(variable.value)) {
|
|
37
|
+
variable.value.forEach(item => pushValue(item));
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
pushValue(variable.value);
|
|
41
|
+
}
|
|
42
|
+
return values;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
customElements.define('qti-max', QtiMax);
|
|
46
|
+
//# sourceMappingURL=qti-max.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-max.js","sourceRoot":"","sources":["../../../src/components/qti-max/qti-max.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,MAAO,SAAQ,aAA4B;IACtC,SAAS;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,EAAwB,CAAC,CAAC;QACrF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,qBAAqB,CAAC,SAA6B;QACjD,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,SAAS;YACX,CAAC;YAED,MAAM,SAAS,GAAG,CAAC,GAAY,EAAE,EAAE;gBACjC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBACtC,OAAO;gBACT,CAAC;gBACD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5C,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC3B,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;oBACvD,OAAO;gBACT,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxB,CAAC,CAAC;YAEF,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBAChD,SAAS;YACX,CAAC;YAED,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-max operator finds the largest value in a numerical set.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#max\n *\n * Takes 1 or more numerical sub-expressions of any cardinality.\n * Returns the largest value in the collection.\n * Special cases: Returns NULL if any argument is NULL or non-numerical.\n */\nexport class QtiMax extends QtiExpression<number | null> {\n public override getResult(): number | null {\n const values = this.#collectNumericValues(this.getVariables() as ResponseVariable[]);\n if (values.length === 0) {\n console.warn('qti-max: no numeric values provided');\n return null;\n }\n\n return Math.max(...values);\n }\n\n #collectNumericValues(variables: ResponseVariable[]): number[] {\n const values: number[] = [];\n\n for (const variable of variables) {\n if (!variable) {\n continue;\n }\n\n const pushValue = (raw: unknown) => {\n if (raw === null || raw === undefined) {\n return;\n }\n const numValue = parseFloat(raw.toString());\n if (Number.isNaN(numValue)) {\n console.warn('qti-max: non-numeric value encountered');\n return;\n }\n values.push(numValue);\n };\n\n if (Array.isArray(variable.value)) {\n variable.value.forEach(item => pushValue(item));\n continue;\n }\n\n pushValue(variable.value);\n }\n\n return values;\n }\n}\n\ncustomElements.define('qti-max', QtiMax);\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-min operator finds the smallest value in a numerical set.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#min
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 or more numerical sub-expressions of any cardinality.
|
|
7
|
+
* Returns the smallest value in the collection.
|
|
8
|
+
* Special cases: Returns NULL if any argument is NULL or non-numerical.
|
|
9
|
+
*/
|
|
10
|
+
export declare class QtiMin extends QtiExpression<number | null> {
|
|
11
|
+
#private;
|
|
12
|
+
getResult(): number | null;
|
|
13
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-min operator finds the smallest value in a numerical set.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#min
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 or more numerical sub-expressions of any cardinality.
|
|
7
|
+
* Returns the smallest value in the collection.
|
|
8
|
+
* Special cases: Returns NULL if any argument is NULL or non-numerical.
|
|
9
|
+
*/
|
|
10
|
+
export class QtiMin extends QtiExpression {
|
|
11
|
+
getResult() {
|
|
12
|
+
const values = this.#collectNumericValues(this.getVariables());
|
|
13
|
+
if (values.length === 0) {
|
|
14
|
+
console.warn('qti-min: no numeric values provided');
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return Math.min(...values);
|
|
18
|
+
}
|
|
19
|
+
#collectNumericValues(variables) {
|
|
20
|
+
const values = [];
|
|
21
|
+
for (const variable of variables) {
|
|
22
|
+
if (!variable) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const pushValue = (raw) => {
|
|
26
|
+
if (raw === null || raw === undefined) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const numValue = parseFloat(raw.toString());
|
|
30
|
+
if (Number.isNaN(numValue)) {
|
|
31
|
+
console.warn('qti-min: non-numeric value encountered');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
values.push(numValue);
|
|
35
|
+
};
|
|
36
|
+
if (Array.isArray(variable.value)) {
|
|
37
|
+
variable.value.forEach(item => pushValue(item));
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
pushValue(variable.value);
|
|
41
|
+
}
|
|
42
|
+
return values;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
customElements.define('qti-min', QtiMin);
|
|
46
|
+
//# sourceMappingURL=qti-min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-min.js","sourceRoot":"","sources":["../../../src/components/qti-min/qti-min.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,MAAO,SAAQ,aAA4B;IACtC,SAAS;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,EAAwB,CAAC,CAAC;QACrF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,qBAAqB,CAAC,SAA6B;QACjD,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,SAAS;YACX,CAAC;YAED,MAAM,SAAS,GAAG,CAAC,GAAY,EAAE,EAAE;gBACjC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBACtC,OAAO;gBACT,CAAC;gBACD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5C,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC3B,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;oBACvD,OAAO;gBACT,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxB,CAAC,CAAC;YAEF,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBAChD,SAAS;YACX,CAAC;YAED,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-min operator finds the smallest value in a numerical set.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#min\n *\n * Takes 1 or more numerical sub-expressions of any cardinality.\n * Returns the smallest value in the collection.\n * Special cases: Returns NULL if any argument is NULL or non-numerical.\n */\nexport class QtiMin extends QtiExpression<number | null> {\n public override getResult(): number | null {\n const values = this.#collectNumericValues(this.getVariables() as ResponseVariable[]);\n if (values.length === 0) {\n console.warn('qti-min: no numeric values provided');\n return null;\n }\n\n return Math.min(...values);\n }\n\n #collectNumericValues(variables: ResponseVariable[]): number[] {\n const values: number[] = [];\n\n for (const variable of variables) {\n if (!variable) {\n continue;\n }\n\n const pushValue = (raw: unknown) => {\n if (raw === null || raw === undefined) {\n return;\n }\n const numValue = parseFloat(raw.toString());\n if (Number.isNaN(numValue)) {\n console.warn('qti-min: non-numeric value encountered');\n return;\n }\n values.push(numValue);\n };\n\n if (Array.isArray(variable.value)) {\n variable.value.forEach(item => pushValue(item));\n continue;\n }\n\n pushValue(variable.value);\n }\n\n return values;\n }\n}\n\ncustomElements.define('qti-min', QtiMin);\n"]}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-not operator performs logical negation.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#not
|
|
5
|
+
*
|
|
6
|
+
* Takes exactly 1 sub-expression with base-type boolean and single cardinality.
|
|
7
|
+
* Returns true if sub-expression is false, and false if sub-expression is true.
|
|
8
|
+
* Special cases: Returns NULL if sub-expression is NULL.
|
|
9
|
+
*/
|
|
2
10
|
export declare class QtiNot extends QtiExpression<boolean> {
|
|
3
11
|
render(): import("lit").TemplateResult<1>;
|
|
4
12
|
getResult(): boolean;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
2
|
import { QtiExpression } from '@qti-components/base';
|
|
3
|
+
/**
|
|
4
|
+
* @summary The qti-not operator performs logical negation.
|
|
5
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#not
|
|
6
|
+
*
|
|
7
|
+
* Takes exactly 1 sub-expression with base-type boolean and single cardinality.
|
|
8
|
+
* Returns true if sub-expression is false, and false if sub-expression is true.
|
|
9
|
+
* Special cases: Returns NULL if sub-expression is NULL.
|
|
10
|
+
*/
|
|
3
11
|
export class QtiNot extends QtiExpression {
|
|
4
12
|
render() {
|
|
5
13
|
return html `${super.render()}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-not.js","sourceRoot":"","sources":["../../../src/components/qti-not/qti-not.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,MAAO,SAAQ,aAAsB;IACvC,MAAM;QACb,OAAO,IAAI,CAAA,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;IACjC,CAAC;IAEe,SAAS;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,iBAA2C,CAAC;QACpE,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,EAAa,CAAC;QACjD,OAAO,CAAC,MAAM,CAAC;IACjB,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC","sourcesContent":["import { html } from 'lit';\n\nimport { QtiExpression } from '@qti-components/base';\n\nexport class QtiNot extends QtiExpression<boolean> {\n override render() {\n return html`${super.render()}`;\n }\n\n public override getResult() {\n const expression = this.firstElementChild as QtiExpression<boolean>;\n const result = expression.calculate() as boolean;\n return !result;\n }\n}\n\ncustomElements.define('qti-not', QtiNot);\n"]}
|
|
1
|
+
{"version":3,"file":"qti-not.js","sourceRoot":"","sources":["../../../src/components/qti-not/qti-not.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;;;;;GAOG;AACH,MAAM,OAAO,MAAO,SAAQ,aAAsB;IACvC,MAAM;QACb,OAAO,IAAI,CAAA,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;IACjC,CAAC;IAEe,SAAS;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,iBAA2C,CAAC;QACpE,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,EAAa,CAAC;QACjD,OAAO,CAAC,MAAM,CAAC;IACjB,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC","sourcesContent":["import { html } from 'lit';\n\nimport { QtiExpression } from '@qti-components/base';\n\n/**\n * @summary The qti-not operator performs logical negation.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#not\n *\n * Takes exactly 1 sub-expression with base-type boolean and single cardinality.\n * Returns true if sub-expression is false, and false if sub-expression is true.\n * Special cases: Returns NULL if sub-expression is NULL.\n */\nexport class QtiNot extends QtiExpression<boolean> {\n override render() {\n return html`${super.render()}`;\n }\n\n public override getResult() {\n const expression = this.firstElementChild as QtiExpression<boolean>;\n const result = expression.calculate() as boolean;\n return !result;\n }\n}\n\ncustomElements.define('qti-not', QtiNot);\n"]}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { QtiConditionExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-or operator evaluates if any provided boolean expressions are true.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#or
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 or more sub-expressions with base-type boolean and single cardinality.
|
|
7
|
+
* Returns true if at least one sub-expression is true, false if all are false.
|
|
8
|
+
* Special cases: Returns NULL if any sub-expression is NULL and all others are false.
|
|
9
|
+
*/
|
|
2
10
|
export declare class QtiOr extends QtiConditionExpression {
|
|
3
11
|
getResult(): boolean;
|
|
4
12
|
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { QtiConditionExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-or operator evaluates if any provided boolean expressions are true.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#or
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 or more sub-expressions with base-type boolean and single cardinality.
|
|
7
|
+
* Returns true if at least one sub-expression is true, false if all are false.
|
|
8
|
+
* Special cases: Returns NULL if any sub-expression is NULL and all others are false.
|
|
9
|
+
*/
|
|
2
10
|
export class QtiOr extends QtiConditionExpression {
|
|
3
11
|
getResult() {
|
|
4
12
|
// children can be a mix of qti-expression and qti-condition-expression
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-or.js","sourceRoot":"","sources":["../../../src/components/qti-or/qti-or.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAI9D,MAAM,OAAO,KAAM,SAAQ,sBAAsB;IAC/B,SAAS;QACvB,uEAAuE;QACvE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC/C,MAAM,SAAS,GAAG,CAAuB,CAAC;YAC1C,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;gBAClE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,GAAG,GAAG,KAAK,CAAC;YAChB,kEAAkE;YAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;oBACrB,GAAG,GAAG,IAAI,CAAC;gBACb,CAAC;qBAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;oBAC7B,GAAG,GAAG,KAAK,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;oBAC5D,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC/B,GAAG,GAAG,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YACrB,OAAO,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC","sourcesContent":["import { QtiConditionExpression } from '@qti-components/base';\n\nimport type { QtiExpression } from '@qti-components/base';\n\nexport class QtiOr extends QtiConditionExpression {\n public override getResult() {\n // children can be a mix of qti-expression and qti-condition-expression\n const values = Array.from(this.children).map(c => {\n const condition = c as QtiExpression<any>;\n if (!condition.calculate) {\n console.error(\"Element doesn't implement QtiConditionExpression\");\n return null;\n }\n const value = condition.calculate();\n let val = false;\n // convert string value to boolean and return null if not possible\n if (typeof value === 'string') {\n if (value === 'true') {\n val = true;\n } else if (value === 'false') {\n val = false;\n } else {\n console.error('unexpected val in qti-or, expected boolean');\n return null;\n }\n } else {\n if (typeof value === 'boolean') {\n val = value;\n }\n }\n return val;\n });\n return values.some(e => {\n return typeof e === 'boolean' && e;\n });\n }\n}\n\ncustomElements.define('qti-or', QtiOr);\n"]}
|
|
1
|
+
{"version":3,"file":"qti-or.js","sourceRoot":"","sources":["../../../src/components/qti-or/qti-or.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAI9D;;;;;;;GAOG;AACH,MAAM,OAAO,KAAM,SAAQ,sBAAsB;IAC/B,SAAS;QACvB,uEAAuE;QACvE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC/C,MAAM,SAAS,GAAG,CAAuB,CAAC;YAC1C,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;gBAClE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,GAAG,GAAG,KAAK,CAAC;YAChB,kEAAkE;YAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;oBACrB,GAAG,GAAG,IAAI,CAAC;gBACb,CAAC;qBAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;oBAC7B,GAAG,GAAG,KAAK,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;oBAC5D,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC/B,GAAG,GAAG,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YACrB,OAAO,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC","sourcesContent":["import { QtiConditionExpression } from '@qti-components/base';\n\nimport type { QtiExpression } from '@qti-components/base';\n\n/**\n * @summary The qti-or operator evaluates if any provided boolean expressions are true.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#or\n *\n * Takes 1 or more sub-expressions with base-type boolean and single cardinality.\n * Returns true if at least one sub-expression is true, false if all are false.\n * Special cases: Returns NULL if any sub-expression is NULL and all others are false.\n */\nexport class QtiOr extends QtiConditionExpression {\n public override getResult() {\n // children can be a mix of qti-expression and qti-condition-expression\n const values = Array.from(this.children).map(c => {\n const condition = c as QtiExpression<any>;\n if (!condition.calculate) {\n console.error(\"Element doesn't implement QtiConditionExpression\");\n return null;\n }\n const value = condition.calculate();\n let val = false;\n // convert string value to boolean and return null if not possible\n if (typeof value === 'string') {\n if (value === 'true') {\n val = true;\n } else if (value === 'false') {\n val = false;\n } else {\n console.error('unexpected val in qti-or, expected boolean');\n return null;\n }\n } else {\n if (typeof value === 'boolean') {\n val = value;\n }\n }\n return val;\n });\n return values.some(e => {\n return typeof e === 'boolean' && e;\n });\n }\n}\n\ncustomElements.define('qti-or', QtiOr);\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-pattern-match operator checks a string against a regular expression.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#patternMatch
|
|
5
|
+
*
|
|
6
|
+
* Takes 1 string sub-expression; 'pattern' attribute contains the regex.
|
|
7
|
+
* Returns true if the string matches the pattern, false otherwise.
|
|
8
|
+
* Special cases: Returns NULL if sub-expression is NULL.
|
|
9
|
+
*/
|
|
10
|
+
export declare class QtiPatternMatch extends QtiExpression<boolean | null> {
|
|
11
|
+
pattern: string;
|
|
12
|
+
getResult(): boolean | null;
|
|
13
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { property } from 'lit/decorators.js';
|
|
8
|
+
import { QtiExpression } from '@qti-components/base';
|
|
9
|
+
/**
|
|
10
|
+
* @summary The qti-pattern-match operator checks a string against a regular expression.
|
|
11
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#patternMatch
|
|
12
|
+
*
|
|
13
|
+
* Takes 1 string sub-expression; 'pattern' attribute contains the regex.
|
|
14
|
+
* Returns true if the string matches the pattern, false otherwise.
|
|
15
|
+
* Special cases: Returns NULL if sub-expression is NULL.
|
|
16
|
+
*/
|
|
17
|
+
export class QtiPatternMatch extends QtiExpression {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.pattern = '';
|
|
21
|
+
}
|
|
22
|
+
getResult() {
|
|
23
|
+
const variables = this.getVariables();
|
|
24
|
+
if (variables.length !== 1) {
|
|
25
|
+
console.error('qti-pattern-match requires exactly one child expression');
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
if (!this.pattern) {
|
|
29
|
+
console.error('qti-pattern-match requires a pattern attribute');
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const variable = variables[0];
|
|
33
|
+
if (variable.cardinality !== 'single' || Array.isArray(variable.value)) {
|
|
34
|
+
console.error('qti-pattern-match requires single cardinality');
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (variable.value === null || variable.value === undefined) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
return new RegExp(this.pattern).test(variable.value.toString());
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error('qti-pattern-match requires a valid regular expression', error);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
__decorate([
|
|
50
|
+
property({ type: String })
|
|
51
|
+
], QtiPatternMatch.prototype, "pattern", void 0);
|
|
52
|
+
customElements.define('qti-pattern-match', QtiPatternMatch);
|
|
53
|
+
//# sourceMappingURL=qti-pattern-match.js.map
|