@khanacademy/perseus 41.3.0 → 41.5.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/dist/es/index.css +3 -0
- package/dist/es/index.js +591 -97
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +3 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +591 -97
- package/dist/index.js.map +1 -1
- package/dist/server-item-renderer.d.ts +1 -1
- package/dist/util/answer-types.d.ts +45 -2
- package/dist/util/parse-perseus-json/perseus-parsers/graded-group-set-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/graded-group-widget.d.ts +16 -0
- package/dist/util/parse-perseus-json/perseus-parsers/grapher-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/group-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/iframe-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/image-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/input-number-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/interaction-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/label-image-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/matcher-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/matrix-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/measurer-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/molecule-renderer-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/number-line-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/numeric-input-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/orderer-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/passage-ref-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/passage-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/phet-simulation-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/plotter-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/python-program-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/radio-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/sorter-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/table-widget.d.ts +3 -0
- package/dist/util/parse-perseus-json/perseus-parsers/video-widget.d.ts +3 -0
- package/dist/validation.types.d.ts +4 -2
- package/dist/widgets/numeric-input/numeric-input.d.ts +7 -0
- package/dist/widgets/table/score-table.d.ts +1 -1
- package/dist/widgets/table/utils.d.ts +7 -0
- package/dist/widgets/table/validate-table.d.ts +6 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1588,7 +1588,7 @@ const MAXERROR_EPSILON = Math.pow(2, -42);
|
|
|
1588
1588
|
// TOOD(kevinb): Figure out how this relates to KEScore in
|
|
1589
1589
|
// perseus-all-package/types.js and see if there's a way to
|
|
1590
1590
|
// unify these types.
|
|
1591
|
-
|
|
1591
|
+
/**
|
|
1592
1592
|
* Answer types
|
|
1593
1593
|
*
|
|
1594
1594
|
* Utility for creating answerable questions displayed in exercises
|
|
@@ -1631,7 +1631,6 @@ const MAXERROR_EPSILON = Math.pow(2, -42);
|
|
|
1631
1631
|
* TODO(alpert): Think of a less-absurd name for createValidatorFunctional.
|
|
1632
1632
|
*
|
|
1633
1633
|
*/
|
|
1634
|
-
|
|
1635
1634
|
const KhanAnswerTypes = {
|
|
1636
1635
|
/*
|
|
1637
1636
|
* predicate answer type
|
|
@@ -2103,9 +2102,7 @@ const KhanAnswerTypes = {
|
|
|
2103
2102
|
})];
|
|
2104
2103
|
},
|
|
2105
2104
|
createValidatorFunctional: function (correctAnswer, options, strings) {
|
|
2106
|
-
return KhanAnswerTypes.predicate.createValidatorFunctional(
|
|
2107
|
-
// @ts-expect-error - TS2556 - A spread argument must either have a tuple type or be passed to a rest parameter.
|
|
2108
|
-
...KhanAnswerTypes.number.convertToPredicate(correctAnswer, options), strings);
|
|
2105
|
+
return KhanAnswerTypes.predicate.createValidatorFunctional(...KhanAnswerTypes.number.convertToPredicate(correctAnswer, options), strings);
|
|
2109
2106
|
}
|
|
2110
2107
|
},
|
|
2111
2108
|
/*
|
|
@@ -2715,7 +2712,7 @@ const keypadConfigurationForProps = widgetOptions => {
|
|
|
2715
2712
|
times: widgetOptions.times
|
|
2716
2713
|
};
|
|
2717
2714
|
};
|
|
2718
|
-
const propUpgrades$
|
|
2715
|
+
const propUpgrades$3 = {
|
|
2719
2716
|
/* c8 ignore next */
|
|
2720
2717
|
"1": v0props => ({
|
|
2721
2718
|
times: v0props.times,
|
|
@@ -2775,7 +2772,7 @@ var Expression$1 = {
|
|
|
2775
2772
|
major: 1,
|
|
2776
2773
|
minor: 0
|
|
2777
2774
|
},
|
|
2778
|
-
propUpgrades: propUpgrades$
|
|
2775
|
+
propUpgrades: propUpgrades$3,
|
|
2779
2776
|
// For use by the editor
|
|
2780
2777
|
isLintable: true,
|
|
2781
2778
|
scorer: scoreExpression,
|
|
@@ -18927,6 +18924,9 @@ const replaceDeprecatedWidgets = () => {
|
|
|
18927
18924
|
replaceWidget("sequence", "deprecated-standin");
|
|
18928
18925
|
replaceWidget("simulator", "deprecated-standin");
|
|
18929
18926
|
replaceWidget("unit-input", "deprecated-standin");
|
|
18927
|
+
|
|
18928
|
+
// Input-Number is a special case as it is being replaced by Numeric-Input
|
|
18929
|
+
replaceWidget("input-number", "numeric-input");
|
|
18930
18930
|
};
|
|
18931
18931
|
const registerEditors = editorsToRegister => {
|
|
18932
18932
|
editorsToRegister.forEach(editor => {
|
|
@@ -18961,6 +18961,11 @@ const replaceDeprecatedEditors = () => {
|
|
|
18961
18961
|
replaceEditor("sequence", "deprecated-standin");
|
|
18962
18962
|
replaceEditor("simulator", "deprecated-standin");
|
|
18963
18963
|
replaceEditor("unit-input", "deprecated-standin");
|
|
18964
|
+
|
|
18965
|
+
// We're replacing the input-number editor with the numeric-input editor here,
|
|
18966
|
+
// but we're also modifying the JSON content to convert input-number into the
|
|
18967
|
+
// numeric-input format over in editor-page.tsx on line 92.
|
|
18968
|
+
replaceEditor("input-number", "numeric-input");
|
|
18964
18969
|
};
|
|
18965
18970
|
const getWidget = name => {
|
|
18966
18971
|
// TODO(alex): Consider referring to these as renderers to avoid
|
|
@@ -19007,10 +19012,8 @@ const getVersionVector = () => {
|
|
|
19007
19012
|
const getPublicWidgets = () => {
|
|
19008
19013
|
// TODO(alex): Update underscore.js so that _.pick can take a function.
|
|
19009
19014
|
// @ts-expect-error - TS2740 - Type 'Pick<{ [key: string]: Readonly<{ name: string; displayName: string; getWidget?: (() => ComponentType<any>) | undefined; accessible?: boolean | ((props: any) => boolean) | undefined; hidden?: boolean | undefined; ... 10 more ...; widget: ComponentType<...>; }>; }, string>' is missing the following properties from type 'readonly Readonly<{ name: string; displayName: string; getWidget?: (() => ComponentType<any>) | undefined; accessible?: boolean | ((props: any) => boolean) | undefined; hidden?: boolean | undefined; ... 10 more ...; widget: ComponentType<...>; }>[]': length, concat, join, slice, and 18 more.
|
|
19010
|
-
return ___default["default"].pick(widgets,
|
|
19011
|
-
|
|
19012
|
-
___default["default"].reject(___default["default"].keys(widgets), function (name) {
|
|
19013
|
-
return widgets[name].hidden;
|
|
19015
|
+
return ___default["default"].pick(widgets, ___default["default"].reject(___default["default"].keys(widgets), function (name) {
|
|
19016
|
+
return widgets[name].hidden || name === "input-number";
|
|
19014
19017
|
}));
|
|
19015
19018
|
};
|
|
19016
19019
|
const isAccessible = widgetInfo => {
|
|
@@ -22380,7 +22383,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
22380
22383
|
height: "auto"
|
|
22381
22384
|
}
|
|
22382
22385
|
});
|
|
22383
|
-
return /*#__PURE__*/React__namespace.createElement(
|
|
22386
|
+
return /*#__PURE__*/React__namespace.createElement(InputWithExamples, {
|
|
22384
22387
|
ref: ref => this.inputRef = ref,
|
|
22385
22388
|
value: this.props.currentValue,
|
|
22386
22389
|
onChange: this.handleChange,
|
|
@@ -22392,7 +22395,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
22392
22395
|
id: this.props.widgetId,
|
|
22393
22396
|
disabled: this.props.apiOptions.readOnly,
|
|
22394
22397
|
style: styles.input
|
|
22395
|
-
})
|
|
22398
|
+
});
|
|
22396
22399
|
}
|
|
22397
22400
|
}
|
|
22398
22401
|
|
|
@@ -22450,13 +22453,65 @@ const propsTransform = function (widgetOptions) {
|
|
|
22450
22453
|
});
|
|
22451
22454
|
return rendererProps;
|
|
22452
22455
|
};
|
|
22456
|
+
|
|
22457
|
+
// This function is being used to replace the input-number widget
|
|
22458
|
+
// with the numeric-input widget
|
|
22459
|
+
const propUpgrades$2 = {
|
|
22460
|
+
/* c8 ignore next */
|
|
22461
|
+
"1": initialProps => {
|
|
22462
|
+
// If the initialProps has a value, it means we're upgrading from
|
|
22463
|
+
// input-number to numeric-input. In this case, we need to upgrade
|
|
22464
|
+
// the widget options accordingly.
|
|
22465
|
+
if (initialProps.value) {
|
|
22466
|
+
const provideAnswerForm = initialProps.answerType !== "number";
|
|
22467
|
+
|
|
22468
|
+
// We need to determine the mathFormat for the numeric-input widget
|
|
22469
|
+
const mathFormat = initialProps.answerType === "rational" ? "proper" // input-number uses "rational" for proper fractions
|
|
22470
|
+
: initialProps.answerType; // Otherwise, we can use the answerType directly
|
|
22471
|
+
|
|
22472
|
+
// If adjusting this logic, also adjust the logic in the convertInputNumberWidgetOptions
|
|
22473
|
+
// function in input-number.ts in the Perseus Editor package's util folder
|
|
22474
|
+
const answers = [{
|
|
22475
|
+
value: initialProps.value,
|
|
22476
|
+
simplify: initialProps.simplify,
|
|
22477
|
+
answerForms: provideAnswerForm ? [mathFormat] : undefined,
|
|
22478
|
+
strict: initialProps.inexact,
|
|
22479
|
+
// We only want to set maxError if the inexact prop is true
|
|
22480
|
+
maxError: initialProps.inexact ? initialProps.maxError : 0,
|
|
22481
|
+
status: "correct",
|
|
22482
|
+
// Input-number only allows correct answers
|
|
22483
|
+
message: ""
|
|
22484
|
+
}];
|
|
22485
|
+
return {
|
|
22486
|
+
answers,
|
|
22487
|
+
size: initialProps.size,
|
|
22488
|
+
coefficient: false,
|
|
22489
|
+
// input-number doesn't have a coefficient prop
|
|
22490
|
+
labelText: "",
|
|
22491
|
+
// input-number doesn't have a labelText prop
|
|
22492
|
+
static: false,
|
|
22493
|
+
// static is always false for numeric-input
|
|
22494
|
+
rightAlign: initialProps.rightAlign || false
|
|
22495
|
+
};
|
|
22496
|
+
} else {
|
|
22497
|
+
// Otherwise simply return the initialProps as there's no differences
|
|
22498
|
+
// between v0 and v1 for numeric-input
|
|
22499
|
+
return initialProps;
|
|
22500
|
+
}
|
|
22501
|
+
}
|
|
22502
|
+
};
|
|
22453
22503
|
var NumericInput$1 = {
|
|
22454
22504
|
name: "numeric-input",
|
|
22455
22505
|
displayName: "Numeric input",
|
|
22456
22506
|
defaultAlignment: "inline-block",
|
|
22457
22507
|
accessible: true,
|
|
22458
22508
|
widget: NumericInput,
|
|
22509
|
+
version: {
|
|
22510
|
+
major: 1,
|
|
22511
|
+
minor: 0
|
|
22512
|
+
},
|
|
22459
22513
|
transform: propsTransform,
|
|
22514
|
+
propUpgrades: propUpgrades$2,
|
|
22460
22515
|
isLintable: true,
|
|
22461
22516
|
scorer: scoreNumericInput,
|
|
22462
22517
|
getOneCorrectAnswerFromRubric(rubric) {
|
|
@@ -32262,17 +32317,12 @@ const ItemExtras = [
|
|
|
32262
32317
|
// prettier-ignore
|
|
32263
32318
|
|
|
32264
32319
|
// prettier-ignore
|
|
32265
|
-
|
|
32320
|
+
// While this widget is deprecated, we still need the type for conversion purposes
|
|
32266
32321
|
// prettier-ignore
|
|
32267
|
-
|
|
32268
32322
|
// prettier-ignore
|
|
32269
|
-
|
|
32270
32323
|
// prettier-ignore
|
|
32271
|
-
|
|
32272
32324
|
//prettier-ignore
|
|
32273
|
-
|
|
32274
32325
|
// A background image applied to various widgets.
|
|
32275
|
-
|
|
32276
32326
|
const PerseusExpressionAnswerFormConsidered = ["correct", "wrong", "ungraded"];
|
|
32277
32327
|
|
|
32278
32328
|
// 2D range: xMin, xMax, yMin, yMax
|
|
@@ -32367,6 +32417,9 @@ function replaceOutsideTeX(mathString) {
|
|
|
32367
32417
|
// Condense adjacent text nodes into a single text node
|
|
32368
32418
|
function condenseTextNodes(nodes) {
|
|
32369
32419
|
const result = [];
|
|
32420
|
+
if (!nodes) {
|
|
32421
|
+
return result;
|
|
32422
|
+
}
|
|
32370
32423
|
let currentText = "";
|
|
32371
32424
|
for (const node of nodes) {
|
|
32372
32425
|
if (node.type === "math") {
|
|
@@ -44512,17 +44565,23 @@ var Sorter$1 = {
|
|
|
44512
44565
|
scorer: scoreSorter
|
|
44513
44566
|
};
|
|
44514
44567
|
|
|
44515
|
-
|
|
44516
|
-
|
|
44517
|
-
|
|
44518
|
-
|
|
44519
|
-
|
|
44520
|
-
|
|
44521
|
-
|
|
44522
|
-
|
|
44523
|
-
|
|
44524
|
-
|
|
44525
|
-
|
|
44568
|
+
/**
|
|
44569
|
+
* Filters the given table (modelled as a 2D array) to remove any rows that are
|
|
44570
|
+
* completely empty.
|
|
44571
|
+
*
|
|
44572
|
+
* @returns A new table with only non-empty rows.
|
|
44573
|
+
*/
|
|
44574
|
+
const filterNonEmpty = function (table) {
|
|
44575
|
+
return table.filter(function (row) {
|
|
44576
|
+
// Return only rows that are non-empty.
|
|
44577
|
+
return row.some(cell => cell);
|
|
44578
|
+
});
|
|
44579
|
+
};
|
|
44580
|
+
|
|
44581
|
+
function validateTable(userInput) {
|
|
44582
|
+
const supplied = filterNonEmpty(userInput);
|
|
44583
|
+
const hasEmptyCell = supplied.some(function (row) {
|
|
44584
|
+
return row.some(function (cell) {
|
|
44526
44585
|
return cell === "";
|
|
44527
44586
|
});
|
|
44528
44587
|
});
|
|
@@ -44532,6 +44591,16 @@ function scoreTable(state, rubric, strings) {
|
|
|
44532
44591
|
message: null
|
|
44533
44592
|
};
|
|
44534
44593
|
}
|
|
44594
|
+
return null;
|
|
44595
|
+
}
|
|
44596
|
+
|
|
44597
|
+
function scoreTable(userInput, rubric, strings) {
|
|
44598
|
+
const validationResult = validateTable(userInput);
|
|
44599
|
+
if (validationResult != null) {
|
|
44600
|
+
return validationResult;
|
|
44601
|
+
}
|
|
44602
|
+
const supplied = filterNonEmpty(userInput);
|
|
44603
|
+
const solution = filterNonEmpty(rubric.answers);
|
|
44535
44604
|
if (supplied.length !== solution.length) {
|
|
44536
44605
|
return {
|
|
44537
44606
|
type: "points",
|
|
@@ -44542,17 +44611,16 @@ function scoreTable(state, rubric, strings) {
|
|
|
44542
44611
|
}
|
|
44543
44612
|
const createValidator = KhanAnswerTypes.number.createValidatorFunctional;
|
|
44544
44613
|
let message = null;
|
|
44545
|
-
const allCorrect =
|
|
44614
|
+
const allCorrect = solution.every(function (rowSolution) {
|
|
44546
44615
|
for (let i = 0; i < supplied.length; i++) {
|
|
44547
44616
|
const rowSupplied = supplied[i];
|
|
44548
|
-
const correct =
|
|
44617
|
+
const correct = rowSupplied.every(function (cellSupplied, i) {
|
|
44549
44618
|
const cellSolution = rowSolution[i];
|
|
44550
44619
|
const validator = createValidator(cellSolution, {
|
|
44551
44620
|
simplify: true
|
|
44552
44621
|
}, strings);
|
|
44553
44622
|
const result = validator(cellSupplied);
|
|
44554
44623
|
if (result.message) {
|
|
44555
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
44556
44624
|
message = result.message;
|
|
44557
44625
|
}
|
|
44558
44626
|
return result.correct;
|
|
@@ -44568,7 +44636,7 @@ function scoreTable(state, rubric, strings) {
|
|
|
44568
44636
|
type: "points",
|
|
44569
44637
|
earned: allCorrect ? 1 : 0,
|
|
44570
44638
|
total: 1,
|
|
44571
|
-
message
|
|
44639
|
+
message
|
|
44572
44640
|
};
|
|
44573
44641
|
}
|
|
44574
44642
|
|
|
@@ -44971,7 +45039,7 @@ const init = function () {
|
|
|
44971
45039
|
|
|
44972
45040
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
44973
45041
|
const libName = "@khanacademy/perseus";
|
|
44974
|
-
const libVersion = "41.
|
|
45042
|
+
const libVersion = "41.5.0";
|
|
44975
45043
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
44976
45044
|
|
|
44977
45045
|
const apiVersion = {
|
|
@@ -45664,7 +45732,7 @@ class ServerItemRenderer extends React__namespace.Component {
|
|
|
45664
45732
|
|
|
45665
45733
|
/**
|
|
45666
45734
|
* Accepts a question area widgetId, or an answer area widgetId of
|
|
45667
|
-
* the form "answer-input
|
|
45735
|
+
* the form "answer-numeric-input 1", or the string "answer-area"
|
|
45668
45736
|
* for the whole answer area (if the answer area is a single widget).
|
|
45669
45737
|
*/
|
|
45670
45738
|
_setWidgetProps(widgetId, newProps, callback) {
|
|
@@ -48648,6 +48716,118 @@ const parseExpressionWidget = parseWidget(constant("expression"), object({
|
|
|
48648
48716
|
buttonsVisible: optional(enumeration("always", "never", "focused"))
|
|
48649
48717
|
}));
|
|
48650
48718
|
|
|
48719
|
+
const parsePerseusRenderer = object({
|
|
48720
|
+
content: string,
|
|
48721
|
+
// This module has an import cycle with parseWidgetsMap, because the
|
|
48722
|
+
// `group` widget can contain another renderer.
|
|
48723
|
+
// The anonymous function below ensures that we don't try to access
|
|
48724
|
+
// parseWidgetsMap before it's defined.
|
|
48725
|
+
widgets: (rawVal, ctx) => parseWidgetsMap(rawVal, ctx),
|
|
48726
|
+
metadata: optional(array(string)),
|
|
48727
|
+
images: record(string, object({
|
|
48728
|
+
width: number,
|
|
48729
|
+
height: number
|
|
48730
|
+
}))
|
|
48731
|
+
});
|
|
48732
|
+
|
|
48733
|
+
const parseGradedGroupWidgetOptions = object({
|
|
48734
|
+
title: string,
|
|
48735
|
+
hasHint: optional(nullable(boolean)),
|
|
48736
|
+
// This module has an import cycle with parsePerseusRenderer.
|
|
48737
|
+
// The anonymous function below ensures that we don't try to access
|
|
48738
|
+
// parsePerseusRenderer before it's defined.
|
|
48739
|
+
hint: optional(nullable((rawVal, ctx) => parsePerseusRenderer(rawVal, ctx))),
|
|
48740
|
+
content: string,
|
|
48741
|
+
// This module has an import cycle with parseWidgetsMap.
|
|
48742
|
+
// The anonymous function below ensures that we don't try to access
|
|
48743
|
+
// parseWidgetsMap before it's defined.
|
|
48744
|
+
widgets: (rawVal, ctx) => parseWidgetsMap(rawVal, ctx),
|
|
48745
|
+
widgetEnabled: optional(nullable(boolean)),
|
|
48746
|
+
immutableWidgets: optional(nullable(boolean)),
|
|
48747
|
+
images: record(string, object({
|
|
48748
|
+
width: number,
|
|
48749
|
+
height: number
|
|
48750
|
+
}))
|
|
48751
|
+
});
|
|
48752
|
+
const parseGradedGroupWidget = parseWidget(constant("graded-group"), parseGradedGroupWidgetOptions);
|
|
48753
|
+
|
|
48754
|
+
const parseGradedGroupSetWidget = parseWidget(constant("graded-group-set"), object({
|
|
48755
|
+
gradedGroups: array(parseGradedGroupWidgetOptions)
|
|
48756
|
+
}));
|
|
48757
|
+
|
|
48758
|
+
const pairOfNumbers$3 = pair(number, number);
|
|
48759
|
+
const pairOfPoints = pair(pairOfNumbers$3, pairOfNumbers$3);
|
|
48760
|
+
const parseGrapherWidget = parseWidget(constant("grapher"), object({
|
|
48761
|
+
availableTypes: array(enumeration("absolute_value", "exponential", "linear", "logarithm", "quadratic", "sinusoid", "tangent")),
|
|
48762
|
+
correct: union(object({
|
|
48763
|
+
type: constant("absolute_value"),
|
|
48764
|
+
coords: pairOfPoints
|
|
48765
|
+
})).or(object({
|
|
48766
|
+
type: constant("exponential"),
|
|
48767
|
+
asymptote: pairOfPoints,
|
|
48768
|
+
coords: pairOfPoints
|
|
48769
|
+
})).or(object({
|
|
48770
|
+
type: constant("linear"),
|
|
48771
|
+
coords: pairOfPoints
|
|
48772
|
+
})).or(object({
|
|
48773
|
+
type: constant("logarithm"),
|
|
48774
|
+
asymptote: pairOfPoints,
|
|
48775
|
+
coords: pairOfPoints
|
|
48776
|
+
})).or(object({
|
|
48777
|
+
type: constant("quadratic"),
|
|
48778
|
+
coords: pairOfPoints
|
|
48779
|
+
})).or(object({
|
|
48780
|
+
type: constant("sinusoid"),
|
|
48781
|
+
coords: pairOfPoints
|
|
48782
|
+
})).or(object({
|
|
48783
|
+
type: constant("tangent"),
|
|
48784
|
+
coords: pairOfPoints
|
|
48785
|
+
})).parser,
|
|
48786
|
+
graph: object({
|
|
48787
|
+
backgroundImage: object({
|
|
48788
|
+
bottom: optional(number),
|
|
48789
|
+
height: optional(number),
|
|
48790
|
+
left: optional(number),
|
|
48791
|
+
scale: optional(number),
|
|
48792
|
+
url: optional(nullable(string)),
|
|
48793
|
+
width: optional(number)
|
|
48794
|
+
}),
|
|
48795
|
+
box: optional(pairOfNumbers$3),
|
|
48796
|
+
editableSettings: optional(array(enumeration("graph", "snap", "image", "measure"))),
|
|
48797
|
+
gridStep: optional(pairOfNumbers$3),
|
|
48798
|
+
labels: pair(string, string),
|
|
48799
|
+
markings: enumeration("graph", "none", "grid"),
|
|
48800
|
+
range: pair(pairOfNumbers$3, pairOfNumbers$3),
|
|
48801
|
+
rulerLabel: constant(""),
|
|
48802
|
+
rulerTicks: number,
|
|
48803
|
+
showProtractor: optional(boolean),
|
|
48804
|
+
showRuler: optional(boolean),
|
|
48805
|
+
showTooltips: optional(boolean),
|
|
48806
|
+
snapStep: optional(pairOfNumbers$3),
|
|
48807
|
+
step: pairOfNumbers$3,
|
|
48808
|
+
valid: optional(union(boolean).or(string).parser)
|
|
48809
|
+
})
|
|
48810
|
+
}));
|
|
48811
|
+
|
|
48812
|
+
const parseGroupWidget = parseWidget(constant("group"),
|
|
48813
|
+
// This module has an import cycle with parsePerseusRenderer.
|
|
48814
|
+
// The anonymous function below ensures that we don't try to access
|
|
48815
|
+
// parsePerseusRenderer before it's defined.
|
|
48816
|
+
(rawVal, ctx) => parsePerseusRenderer(rawVal, ctx));
|
|
48817
|
+
|
|
48818
|
+
const parseIframeWidget = parseWidget(constant("iframe"), object({
|
|
48819
|
+
url: string,
|
|
48820
|
+
settings: array(object({
|
|
48821
|
+
name: string,
|
|
48822
|
+
value: string
|
|
48823
|
+
})),
|
|
48824
|
+
width: union(number).or(string).parser,
|
|
48825
|
+
height: union(number).or(string).parser,
|
|
48826
|
+
allowFullScreen: boolean,
|
|
48827
|
+
allowTopNavigation: optional(boolean),
|
|
48828
|
+
static: boolean
|
|
48829
|
+
}));
|
|
48830
|
+
|
|
48651
48831
|
const parsePerseusImageBackground = object({
|
|
48652
48832
|
url: optional(nullable(string)),
|
|
48653
48833
|
width: optional(number),
|
|
@@ -48659,6 +48839,160 @@ const parsePerseusImageBackground = object({
|
|
|
48659
48839
|
scale: optional(union(number).or(string).parser)
|
|
48660
48840
|
});
|
|
48661
48841
|
|
|
48842
|
+
const pairOfNumbers$2 = pair(number, number);
|
|
48843
|
+
const parseImageWidget = parseWidget(constant("image"), object({
|
|
48844
|
+
title: optional(string),
|
|
48845
|
+
caption: optional(string),
|
|
48846
|
+
alt: optional(string),
|
|
48847
|
+
backgroundImage: parsePerseusImageBackground,
|
|
48848
|
+
static: optional(boolean),
|
|
48849
|
+
labels: optional(array(object({
|
|
48850
|
+
content: string,
|
|
48851
|
+
alignment: string,
|
|
48852
|
+
coordinates: array(number)
|
|
48853
|
+
}))),
|
|
48854
|
+
range: optional(pair(pairOfNumbers$2, pairOfNumbers$2)),
|
|
48855
|
+
box: optional(pairOfNumbers$2)
|
|
48856
|
+
}));
|
|
48857
|
+
|
|
48858
|
+
const parseInputNumberWidget = parseWidget(constant("input-number"), object({
|
|
48859
|
+
answerType: optional(enumeration("number", "decimal", "integer", "rational", "improper", "mixed", "percent", "pi")),
|
|
48860
|
+
inexact: optional(boolean),
|
|
48861
|
+
maxError: optional(union(number).or(string).parser),
|
|
48862
|
+
rightAlign: optional(boolean),
|
|
48863
|
+
simplify: enumeration("required", "optional", "enforced"),
|
|
48864
|
+
size: enumeration("normal", "small"),
|
|
48865
|
+
value: union(number).or(string).parser,
|
|
48866
|
+
customKeypad: optional(boolean)
|
|
48867
|
+
}));
|
|
48868
|
+
|
|
48869
|
+
const pairOfNumbers$1 = pair(number, number);
|
|
48870
|
+
const parseFunctionElement = object({
|
|
48871
|
+
type: constant("function"),
|
|
48872
|
+
key: string,
|
|
48873
|
+
options: object({
|
|
48874
|
+
value: string,
|
|
48875
|
+
funcName: string,
|
|
48876
|
+
rangeMin: string,
|
|
48877
|
+
rangeMax: string,
|
|
48878
|
+
color: string,
|
|
48879
|
+
strokeDasharray: string,
|
|
48880
|
+
strokeWidth: number
|
|
48881
|
+
})
|
|
48882
|
+
});
|
|
48883
|
+
const parseLabelElement = object({
|
|
48884
|
+
type: constant("label"),
|
|
48885
|
+
key: string,
|
|
48886
|
+
options: object({
|
|
48887
|
+
label: string,
|
|
48888
|
+
color: string,
|
|
48889
|
+
coordX: string,
|
|
48890
|
+
coordY: string
|
|
48891
|
+
})
|
|
48892
|
+
});
|
|
48893
|
+
const parseLineElement = object({
|
|
48894
|
+
type: constant("line"),
|
|
48895
|
+
key: string,
|
|
48896
|
+
options: object({
|
|
48897
|
+
color: string,
|
|
48898
|
+
startX: string,
|
|
48899
|
+
startY: string,
|
|
48900
|
+
endX: string,
|
|
48901
|
+
endY: string,
|
|
48902
|
+
strokeDasharray: string,
|
|
48903
|
+
strokeWidth: number,
|
|
48904
|
+
arrows: string
|
|
48905
|
+
})
|
|
48906
|
+
});
|
|
48907
|
+
const parseMovableLineElement = object({
|
|
48908
|
+
type: constant("movable-line"),
|
|
48909
|
+
key: string,
|
|
48910
|
+
options: object({
|
|
48911
|
+
startX: string,
|
|
48912
|
+
startY: string,
|
|
48913
|
+
startSubscript: number,
|
|
48914
|
+
endX: string,
|
|
48915
|
+
endY: string,
|
|
48916
|
+
endSubscript: number,
|
|
48917
|
+
constraint: string,
|
|
48918
|
+
snap: number,
|
|
48919
|
+
constraintFn: string,
|
|
48920
|
+
constraintXMin: string,
|
|
48921
|
+
constraintXMax: string,
|
|
48922
|
+
constraintYMin: string,
|
|
48923
|
+
constraintYMax: string
|
|
48924
|
+
})
|
|
48925
|
+
});
|
|
48926
|
+
const parseMovablePointElement = object({
|
|
48927
|
+
type: constant("movable-point"),
|
|
48928
|
+
key: string,
|
|
48929
|
+
options: object({
|
|
48930
|
+
startX: string,
|
|
48931
|
+
startY: string,
|
|
48932
|
+
varSubscript: number,
|
|
48933
|
+
constraint: string,
|
|
48934
|
+
snap: number,
|
|
48935
|
+
constraintFn: string,
|
|
48936
|
+
constraintXMin: string,
|
|
48937
|
+
constraintXMax: string,
|
|
48938
|
+
constraintYMin: string,
|
|
48939
|
+
constraintYMax: string
|
|
48940
|
+
})
|
|
48941
|
+
});
|
|
48942
|
+
const parseParametricElement = object({
|
|
48943
|
+
type: constant("parametric"),
|
|
48944
|
+
key: string,
|
|
48945
|
+
options: object({
|
|
48946
|
+
x: string,
|
|
48947
|
+
y: string,
|
|
48948
|
+
rangeMin: string,
|
|
48949
|
+
rangeMax: string,
|
|
48950
|
+
color: string,
|
|
48951
|
+
strokeDasharray: string,
|
|
48952
|
+
strokeWidth: number
|
|
48953
|
+
})
|
|
48954
|
+
});
|
|
48955
|
+
const parsePointElement = object({
|
|
48956
|
+
type: constant("point"),
|
|
48957
|
+
key: string,
|
|
48958
|
+
options: object({
|
|
48959
|
+
color: string,
|
|
48960
|
+
coordX: string,
|
|
48961
|
+
coordY: string
|
|
48962
|
+
})
|
|
48963
|
+
});
|
|
48964
|
+
const parseRectangleElement = object({
|
|
48965
|
+
type: constant("rectangle"),
|
|
48966
|
+
key: string,
|
|
48967
|
+
options: object({
|
|
48968
|
+
color: string,
|
|
48969
|
+
coordX: string,
|
|
48970
|
+
coordY: string,
|
|
48971
|
+
width: string,
|
|
48972
|
+
height: string
|
|
48973
|
+
})
|
|
48974
|
+
});
|
|
48975
|
+
const parseInteractionWidget = parseWidget(constant("interaction"), object({
|
|
48976
|
+
static: boolean,
|
|
48977
|
+
graph: object({
|
|
48978
|
+
editableSettings: optional(array(enumeration("canvas", "graph"))),
|
|
48979
|
+
box: pairOfNumbers$1,
|
|
48980
|
+
labels: array(string),
|
|
48981
|
+
range: pair(pairOfNumbers$1, pairOfNumbers$1),
|
|
48982
|
+
gridStep: pairOfNumbers$1,
|
|
48983
|
+
markings: enumeration("graph", "grid", "none"),
|
|
48984
|
+
snapStep: optional(pairOfNumbers$1),
|
|
48985
|
+
valid: optional(union(boolean).or(string).parser),
|
|
48986
|
+
backgroundImage: optional(parsePerseusImageBackground),
|
|
48987
|
+
showProtractor: optional(boolean),
|
|
48988
|
+
showRuler: optional(boolean),
|
|
48989
|
+
rulerLabel: optional(string),
|
|
48990
|
+
rulerTicks: optional(number),
|
|
48991
|
+
tickStep: pairOfNumbers$1
|
|
48992
|
+
}),
|
|
48993
|
+
elements: array(union(parseFunctionElement).or(parseLabelElement).or(parseLineElement).or(parseMovableLineElement).or(parseMovablePointElement).or(parseParametricElement).or(parsePointElement).or(parseRectangleElement).parser)
|
|
48994
|
+
}));
|
|
48995
|
+
|
|
48662
48996
|
// Used to represent 2-D points and ranges
|
|
48663
48997
|
const pairOfNumbers = pair(number, number);
|
|
48664
48998
|
const parsePerseusGraphTypeAngle = object({
|
|
@@ -48845,6 +49179,195 @@ const parseInteractiveGraphWidget = parseWidget(constant("interactive-graph"), o
|
|
|
48845
49179
|
fullGraphAriaDescription: optional(string)
|
|
48846
49180
|
}));
|
|
48847
49181
|
|
|
49182
|
+
const parseLabelImageWidget = parseWidget(constant("label-image"), object({
|
|
49183
|
+
choices: array(string),
|
|
49184
|
+
imageUrl: string,
|
|
49185
|
+
imageAlt: string,
|
|
49186
|
+
imageHeight: number,
|
|
49187
|
+
imageWidth: number,
|
|
49188
|
+
markers: array(object({
|
|
49189
|
+
answers: array(string),
|
|
49190
|
+
label: string,
|
|
49191
|
+
x: number,
|
|
49192
|
+
y: number
|
|
49193
|
+
})),
|
|
49194
|
+
hideChoicesFromInstructions: boolean,
|
|
49195
|
+
multipleAnswers: boolean,
|
|
49196
|
+
static: boolean
|
|
49197
|
+
}));
|
|
49198
|
+
|
|
49199
|
+
const parseMatcherWidget = parseWidget(constant("matcher"), object({
|
|
49200
|
+
labels: array(string),
|
|
49201
|
+
left: array(string),
|
|
49202
|
+
right: array(string),
|
|
49203
|
+
orderMatters: boolean,
|
|
49204
|
+
padding: boolean
|
|
49205
|
+
}));
|
|
49206
|
+
|
|
49207
|
+
const parseMatrixWidget = parseWidget(constant("matrix"), object({
|
|
49208
|
+
prefix: string,
|
|
49209
|
+
suffix: string,
|
|
49210
|
+
answers: array(array(number)),
|
|
49211
|
+
cursorPosition: array(number),
|
|
49212
|
+
matrixBoardSize: array(number),
|
|
49213
|
+
static: boolean
|
|
49214
|
+
}));
|
|
49215
|
+
|
|
49216
|
+
const parseMeasurerWidget = parseWidget(constant("measurer"), object({
|
|
49217
|
+
image: parsePerseusImageBackground,
|
|
49218
|
+
showProtractor: boolean,
|
|
49219
|
+
showRuler: boolean,
|
|
49220
|
+
rulerLabel: string,
|
|
49221
|
+
rulerTicks: number,
|
|
49222
|
+
rulerPixels: number,
|
|
49223
|
+
rulerLength: number,
|
|
49224
|
+
box: pair(number, number),
|
|
49225
|
+
static: boolean
|
|
49226
|
+
}));
|
|
49227
|
+
|
|
49228
|
+
const parseMoleculeRendererWidget = parseWidget(constant("molecule-renderer"), object({
|
|
49229
|
+
widgetId: string,
|
|
49230
|
+
rotationAngle: optional(number),
|
|
49231
|
+
smiles: optional(string)
|
|
49232
|
+
}));
|
|
49233
|
+
|
|
49234
|
+
const parseNumberLineWidget = parseWidget(constant("number-line"), object({
|
|
49235
|
+
range: array(number),
|
|
49236
|
+
labelRange: array(nullable(number)),
|
|
49237
|
+
labelStyle: string,
|
|
49238
|
+
labelTicks: boolean,
|
|
49239
|
+
isTickCtrl: optional(nullable(boolean)),
|
|
49240
|
+
divisionRange: array(number),
|
|
49241
|
+
numDivisions: optional(nullable(number)),
|
|
49242
|
+
snapDivisions: number,
|
|
49243
|
+
tickStep: optional(nullable(number)),
|
|
49244
|
+
correctRel: optional(nullable(string)),
|
|
49245
|
+
correctX: number,
|
|
49246
|
+
initialX: optional(nullable(number)),
|
|
49247
|
+
showTooltip: optional(boolean),
|
|
49248
|
+
static: boolean
|
|
49249
|
+
}));
|
|
49250
|
+
|
|
49251
|
+
const parseMathFormat = enumeration("integer", "mixed", "improper", "proper", "decimal", "percent", "pi");
|
|
49252
|
+
const parseNumericInputWidget = parseWidget(constant("numeric-input"), object({
|
|
49253
|
+
answers: array(object({
|
|
49254
|
+
message: string,
|
|
49255
|
+
value: number,
|
|
49256
|
+
status: string,
|
|
49257
|
+
answerForms: optional(array(parseMathFormat)),
|
|
49258
|
+
strict: boolean,
|
|
49259
|
+
maxError: optional(nullable(number)),
|
|
49260
|
+
simplify: optional(nullable(string))
|
|
49261
|
+
})),
|
|
49262
|
+
labelText: string,
|
|
49263
|
+
size: string,
|
|
49264
|
+
coefficient: boolean,
|
|
49265
|
+
rightAlign: optional(boolean),
|
|
49266
|
+
static: boolean,
|
|
49267
|
+
answerForms: optional(array(object({
|
|
49268
|
+
name: parseMathFormat,
|
|
49269
|
+
simplify: optional(nullable(enumeration("required", "correct", "enforced", "optional")))
|
|
49270
|
+
})))
|
|
49271
|
+
}));
|
|
49272
|
+
|
|
49273
|
+
// There is an import cycle between orderer-widget.ts and perseus-renderer.ts.
|
|
49274
|
+
// This wrapper ensures that we don't refer to parsePerseusRenderer before
|
|
49275
|
+
// it's defined.
|
|
49276
|
+
function parseRenderer(rawValue, ctx) {
|
|
49277
|
+
return parsePerseusRenderer(rawValue, ctx);
|
|
49278
|
+
}
|
|
49279
|
+
const parseOrdererWidget = parseWidget(constant("orderer"), object({
|
|
49280
|
+
options: array(parseRenderer),
|
|
49281
|
+
correctOptions: array(parseRenderer),
|
|
49282
|
+
otherOptions: array(parseRenderer),
|
|
49283
|
+
height: string,
|
|
49284
|
+
layout: string
|
|
49285
|
+
}));
|
|
49286
|
+
|
|
49287
|
+
const parsePassageRefWidget = parseWidget(constant("passage-ref"), object({
|
|
49288
|
+
passageNumber: number,
|
|
49289
|
+
referenceNumber: number,
|
|
49290
|
+
summaryText: string
|
|
49291
|
+
}));
|
|
49292
|
+
|
|
49293
|
+
const parsePassageWidget = parseWidget(constant("passage"), object({
|
|
49294
|
+
footnotes: string,
|
|
49295
|
+
passageText: string,
|
|
49296
|
+
passageTitle: string,
|
|
49297
|
+
showLineNumbers: boolean,
|
|
49298
|
+
static: boolean
|
|
49299
|
+
}));
|
|
49300
|
+
|
|
49301
|
+
const parsePhetSimulationWidget = parseWidget(constant("phet-simulation"), object({
|
|
49302
|
+
url: string,
|
|
49303
|
+
description: string
|
|
49304
|
+
}));
|
|
49305
|
+
|
|
49306
|
+
const parsePlotterWidget = parseWidget(constant("plotter"), object({
|
|
49307
|
+
labels: array(string),
|
|
49308
|
+
categories: array(string),
|
|
49309
|
+
type: enumeration(...plotterPlotTypes),
|
|
49310
|
+
maxY: number,
|
|
49311
|
+
scaleY: number,
|
|
49312
|
+
labelInterval: optional(nullable(number)),
|
|
49313
|
+
snapsPerLine: number,
|
|
49314
|
+
starting: array(number),
|
|
49315
|
+
correct: array(number),
|
|
49316
|
+
picUrl: optional(nullable(string)),
|
|
49317
|
+
picSize: optional(nullable(number)),
|
|
49318
|
+
picBoxHeight: optional(nullable(number)),
|
|
49319
|
+
plotDimensions: array(number)
|
|
49320
|
+
}));
|
|
49321
|
+
|
|
49322
|
+
const parsePythonProgramWidget = parseWidget(constant("python-program"), object({
|
|
49323
|
+
programID: string,
|
|
49324
|
+
height: number
|
|
49325
|
+
}));
|
|
49326
|
+
|
|
49327
|
+
const parseRadioWidget = parseWidget(constant("radio"), object({
|
|
49328
|
+
choices: array(object({
|
|
49329
|
+
content: string,
|
|
49330
|
+
clue: optional(string),
|
|
49331
|
+
correct: optional(boolean),
|
|
49332
|
+
isNoneOfTheAbove: optional(boolean),
|
|
49333
|
+
// deprecated
|
|
49334
|
+
// There is an import cycle between radio-widget.ts and
|
|
49335
|
+
// widgets-map.ts. The anonymous function below ensures that we
|
|
49336
|
+
// don't refer to parseWidgetsMap before it's defined.
|
|
49337
|
+
widgets: optional((rawVal, ctx) => parseWidgetsMap(rawVal, ctx))
|
|
49338
|
+
})),
|
|
49339
|
+
hasNoneOfTheAbove: optional(boolean),
|
|
49340
|
+
countChoices: optional(boolean),
|
|
49341
|
+
randomize: optional(boolean),
|
|
49342
|
+
multipleSelect: optional(boolean),
|
|
49343
|
+
deselectEnabled: optional(boolean),
|
|
49344
|
+
// deprecated
|
|
49345
|
+
onePerLine: optional(boolean),
|
|
49346
|
+
// deprecated
|
|
49347
|
+
displayCount: optional(any),
|
|
49348
|
+
// v0 props
|
|
49349
|
+
// `noneOfTheAbove` is still in use (but only set to `false`).
|
|
49350
|
+
noneOfTheAbove: constant(false)
|
|
49351
|
+
}));
|
|
49352
|
+
|
|
49353
|
+
const parseSorterWidget = parseWidget(constant("sorter"), object({
|
|
49354
|
+
correct: array(string),
|
|
49355
|
+
padding: boolean,
|
|
49356
|
+
layout: enumeration("horizontal", "vertical")
|
|
49357
|
+
}));
|
|
49358
|
+
|
|
49359
|
+
const parseTableWidget = parseWidget(constant("table"), object({
|
|
49360
|
+
headers: array(string),
|
|
49361
|
+
rows: number,
|
|
49362
|
+
columns: number,
|
|
49363
|
+
answers: array(array(string))
|
|
49364
|
+
}));
|
|
49365
|
+
|
|
49366
|
+
const parseVideoWidget = parseWidget(constant("video"), object({
|
|
49367
|
+
location: string,
|
|
49368
|
+
static: optional(boolean)
|
|
49369
|
+
}));
|
|
49370
|
+
|
|
48848
49371
|
const parseWidgetsMap = (rawValue, ctx) => {
|
|
48849
49372
|
if (!isObject(rawValue)) {
|
|
48850
49373
|
return ctx.failure("PerseusWidgetsMap", rawValue);
|
|
@@ -48890,86 +49413,67 @@ const parseWidgetsMapEntry = (_ref, widgetMap, ctx) => {
|
|
|
48890
49413
|
case "expression":
|
|
48891
49414
|
return parseAndAssign(`expression ${id}`, parseExpressionWidget);
|
|
48892
49415
|
case "grapher":
|
|
48893
|
-
|
|
48894
|
-
return parseAndAssign(`grapher ${id}`, any);
|
|
49416
|
+
return parseAndAssign(`grapher ${id}`, parseGrapherWidget);
|
|
48895
49417
|
case "group":
|
|
48896
|
-
|
|
48897
|
-
return parseAndAssign(`group ${id}`, any);
|
|
49418
|
+
return parseAndAssign(`group ${id}`, parseGroupWidget);
|
|
48898
49419
|
case "graded-group":
|
|
48899
|
-
|
|
48900
|
-
return parseAndAssign(`graded-group ${id}`, any);
|
|
49420
|
+
return parseAndAssign(`graded-group ${id}`, parseGradedGroupWidget);
|
|
48901
49421
|
case "graded-group-set":
|
|
48902
|
-
|
|
48903
|
-
return parseAndAssign(`graded-group-set ${id}`, any);
|
|
49422
|
+
return parseAndAssign(`graded-group-set ${id}`, parseGradedGroupSetWidget);
|
|
48904
49423
|
case "iframe":
|
|
48905
|
-
|
|
48906
|
-
return parseAndAssign(`iframe ${id}`, any);
|
|
49424
|
+
return parseAndAssign(`iframe ${id}`, parseIframeWidget);
|
|
48907
49425
|
case "image":
|
|
48908
|
-
|
|
48909
|
-
return parseAndAssign(`image ${id}`, any);
|
|
49426
|
+
return parseAndAssign(`image ${id}`, parseImageWidget);
|
|
48910
49427
|
case "input-number":
|
|
48911
|
-
|
|
48912
|
-
return parseAndAssign(`input-number ${id}`, any);
|
|
49428
|
+
return parseAndAssign(`input-number ${id}`, parseInputNumberWidget);
|
|
48913
49429
|
case "interaction":
|
|
48914
|
-
|
|
48915
|
-
return parseAndAssign(`interaction ${id}`, any);
|
|
49430
|
+
return parseAndAssign(`interaction ${id}`, parseInteractionWidget);
|
|
48916
49431
|
case "interactive-graph":
|
|
48917
49432
|
return parseAndAssign(`interactive-graph ${id}`, parseInteractiveGraphWidget);
|
|
48918
49433
|
case "label-image":
|
|
48919
|
-
|
|
48920
|
-
return parseAndAssign(`label-image ${id}`, any);
|
|
49434
|
+
return parseAndAssign(`label-image ${id}`, parseLabelImageWidget);
|
|
48921
49435
|
case "matcher":
|
|
48922
|
-
|
|
48923
|
-
return parseAndAssign(`matcher ${id}`, any);
|
|
49436
|
+
return parseAndAssign(`matcher ${id}`, parseMatcherWidget);
|
|
48924
49437
|
case "matrix":
|
|
48925
|
-
|
|
48926
|
-
return parseAndAssign(`matrix ${id}`, any);
|
|
49438
|
+
return parseAndAssign(`matrix ${id}`, parseMatrixWidget);
|
|
48927
49439
|
case "measurer":
|
|
48928
|
-
|
|
48929
|
-
return parseAndAssign(`measurer ${id}`, any);
|
|
49440
|
+
return parseAndAssign(`measurer ${id}`, parseMeasurerWidget);
|
|
48930
49441
|
case "molecule-renderer":
|
|
48931
|
-
|
|
48932
|
-
return parseAndAssign(`molecule-renderer ${id}`, any);
|
|
49442
|
+
return parseAndAssign(`molecule-renderer ${id}`, parseMoleculeRendererWidget);
|
|
48933
49443
|
case "number-line":
|
|
48934
|
-
|
|
48935
|
-
return parseAndAssign(`number-line ${id}`, any);
|
|
49444
|
+
return parseAndAssign(`number-line ${id}`, parseNumberLineWidget);
|
|
48936
49445
|
case "numeric-input":
|
|
48937
|
-
|
|
48938
|
-
return parseAndAssign(`numeric-input ${id}`, any);
|
|
49446
|
+
return parseAndAssign(`numeric-input ${id}`, parseNumericInputWidget);
|
|
48939
49447
|
case "orderer":
|
|
48940
|
-
|
|
48941
|
-
return parseAndAssign(`orderer ${id}`, any);
|
|
49448
|
+
return parseAndAssign(`orderer ${id}`, parseOrdererWidget);
|
|
48942
49449
|
case "passage":
|
|
48943
|
-
|
|
48944
|
-
return parseAndAssign(`passage ${id}`, any);
|
|
49450
|
+
return parseAndAssign(`passage ${id}`, parsePassageWidget);
|
|
48945
49451
|
case "passage-ref":
|
|
48946
|
-
|
|
48947
|
-
return parseAndAssign(`passage-ref ${id}`, any);
|
|
49452
|
+
return parseAndAssign(`passage-ref ${id}`, parsePassageRefWidget);
|
|
48948
49453
|
case "passage-ref-target":
|
|
48949
|
-
//
|
|
49454
|
+
// NOTE(benchristel): as of 2024-11-12, passage-ref-target is only
|
|
49455
|
+
// used in test content. See:
|
|
49456
|
+
// https://www.khanacademy.org/devadmin/content/search?query=widget:passage-ref-target
|
|
48950
49457
|
return parseAndAssign(`passage-ref-target ${id}`, any);
|
|
48951
49458
|
case "phet-simulation":
|
|
48952
|
-
|
|
48953
|
-
return parseAndAssign(`phet-simulation ${id}`, any);
|
|
49459
|
+
return parseAndAssign(`phet-simulation ${id}`, parsePhetSimulationWidget);
|
|
48954
49460
|
case "plotter":
|
|
48955
|
-
|
|
48956
|
-
return parseAndAssign(`plotter ${id}`, any);
|
|
49461
|
+
return parseAndAssign(`plotter ${id}`, parsePlotterWidget);
|
|
48957
49462
|
case "python-program":
|
|
48958
|
-
|
|
48959
|
-
return parseAndAssign(`python-program ${id}`, any);
|
|
49463
|
+
return parseAndAssign(`python-program ${id}`, parsePythonProgramWidget);
|
|
48960
49464
|
case "radio":
|
|
48961
|
-
|
|
48962
|
-
return parseAndAssign(`radio ${id}`, any);
|
|
49465
|
+
return parseAndAssign(`radio ${id}`, parseRadioWidget);
|
|
48963
49466
|
case "sorter":
|
|
48964
|
-
|
|
48965
|
-
return parseAndAssign(`sorter ${id}`, any);
|
|
49467
|
+
return parseAndAssign(`sorter ${id}`, parseSorterWidget);
|
|
48966
49468
|
case "table":
|
|
48967
|
-
|
|
48968
|
-
return parseAndAssign(`table ${id}`, any);
|
|
49469
|
+
return parseAndAssign(`table ${id}`, parseTableWidget);
|
|
48969
49470
|
case "video":
|
|
48970
|
-
|
|
48971
|
-
return parseAndAssign(`video ${id}`, any);
|
|
49471
|
+
return parseAndAssign(`video ${id}`, parseVideoWidget);
|
|
48972
49472
|
default:
|
|
49473
|
+
if (getWidget(type)) {
|
|
49474
|
+
// @ts-expect-error - 'type' is not a valid widget type
|
|
49475
|
+
return parseAndAssign(`${type} ${id}`, any);
|
|
49476
|
+
}
|
|
48973
49477
|
return ctx.failure("a valid widget type", type);
|
|
48974
49478
|
}
|
|
48975
49479
|
};
|
|
@@ -48992,16 +49496,6 @@ const parseHint = object({
|
|
|
48992
49496
|
}))
|
|
48993
49497
|
});
|
|
48994
49498
|
|
|
48995
|
-
const parsePerseusRenderer = object({
|
|
48996
|
-
content: string,
|
|
48997
|
-
widgets: parseWidgetsMap,
|
|
48998
|
-
metadata: optional(array(string)),
|
|
48999
|
-
images: record(string, object({
|
|
49000
|
-
width: number,
|
|
49001
|
-
height: number
|
|
49002
|
-
}))
|
|
49003
|
-
});
|
|
49004
|
-
|
|
49005
49499
|
object({
|
|
49006
49500
|
question: parsePerseusRenderer,
|
|
49007
49501
|
hints: array(parseHint),
|