@khanacademy/perseus 49.1.7 → 49.2.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/components/math-input.d.ts +2 -1
- package/dist/es/index.css +5 -0
- package/dist/es/index.js +229 -55
- package/dist/es/index.js.map +1 -1
- package/dist/es/strings.js +16 -12
- package/dist/es/strings.js.map +1 -1
- package/dist/index.css +5 -0
- package/dist/index.js +230 -55
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +4 -3
- package/dist/strings.d.ts +6 -5
- package/dist/strings.js +16 -12
- package/dist/strings.js.map +1 -1
- package/dist/util/parse-perseus-json/general-purpose-parsers/convert.d.ts +2 -0
- package/dist/util/parse-perseus-json/general-purpose-parsers/discriminated-union.d.ts +8 -0
- package/dist/util/parse-perseus-json/perseus-parsers/versioned-widget-options.d.ts +45 -0
- package/dist/widgets/expression/expression.d.ts +1 -1
- package/dist/widgets/passage-ref/passage-ref.d.ts +7 -3
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -487,12 +487,12 @@ const mockStrings = {
|
|
|
487
487
|
angleMeasure,
|
|
488
488
|
vertexX,
|
|
489
489
|
vertexY,
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
490
|
+
startingSideX,
|
|
491
|
+
startingSideY,
|
|
492
|
+
endingSideX,
|
|
493
|
+
endingSideY
|
|
494
494
|
} = _ref40;
|
|
495
|
-
return `The angle measure is ${angleMeasure} degrees with a vertex at ${vertexX} comma ${vertexY}, a point on the
|
|
495
|
+
return `The angle measure is ${angleMeasure} degrees with a vertex at ${vertexX} comma ${vertexY}, a point on the starting side at ${startingSideX} comma ${startingSideY} and a point on the ending side at ${endingSideX} comma ${endingSideY}.`;
|
|
496
496
|
}
|
|
497
497
|
// The above strings are used for interactive graph SR descriptions.
|
|
498
498
|
};
|
|
@@ -897,6 +897,9 @@ const mapButtonSets = buttonSets => {
|
|
|
897
897
|
case "trig":
|
|
898
898
|
keypadButtonSets.trigonometry = true;
|
|
899
899
|
break;
|
|
900
|
+
case "scientific":
|
|
901
|
+
keypadButtonSets.scientific = true;
|
|
902
|
+
break;
|
|
900
903
|
}
|
|
901
904
|
});
|
|
902
905
|
return keypadButtonSets;
|
|
@@ -3971,7 +3974,9 @@ ZoomServiceClass.prototype._scrollHandler = function (e) {
|
|
|
3971
3974
|
}
|
|
3972
3975
|
};
|
|
3973
3976
|
ZoomServiceClass.prototype._keyHandler = function (e) {
|
|
3974
|
-
|
|
3977
|
+
// 27: Esc, 13: Enter, 32: Space
|
|
3978
|
+
const keyCodes = [27, 13, 32];
|
|
3979
|
+
if (keyCodes.includes(e.keyCode)) {
|
|
3975
3980
|
this._activeZoomClose();
|
|
3976
3981
|
}
|
|
3977
3982
|
};
|
|
@@ -4060,6 +4065,7 @@ Zoom.prototype.zoomImage = function () {
|
|
|
4060
4065
|
}.bind(this);
|
|
4061
4066
|
img.src = this._targetImage.src;
|
|
4062
4067
|
img.alt = this._targetImage.alt;
|
|
4068
|
+
img.tabIndex = 0;
|
|
4063
4069
|
this.$zoomedImage = $zoomedImage;
|
|
4064
4070
|
};
|
|
4065
4071
|
Zoom.prototype._zoomOriginal = function () {
|
|
@@ -17242,6 +17248,7 @@ class ImageLoader extends React__namespace.Component {
|
|
|
17242
17248
|
}
|
|
17243
17249
|
const staticUrl = getDependencies().staticUrl;
|
|
17244
17250
|
return /*#__PURE__*/React__namespace.createElement("img", _extends({
|
|
17251
|
+
tabIndex: 0,
|
|
17245
17252
|
src: staticUrl(src),
|
|
17246
17253
|
onKeyUp: onKeyUp,
|
|
17247
17254
|
onKeyDown: onKeyDown
|
|
@@ -22456,7 +22463,7 @@ function scoreNumericInput(userInput, rubric, strings) {
|
|
|
22456
22463
|
// We may have received TeX; try to parse it before grading.
|
|
22457
22464
|
// If `currentValue` is not TeX, this should be a no-op.
|
|
22458
22465
|
const currentValue = ParseTex(userInput.currentValue);
|
|
22459
|
-
const normalizedAnswerExpected = rubric.answers.filter(answer => answer.status === "correct").every(answer => answer.value
|
|
22466
|
+
const normalizedAnswerExpected = rubric.answers.filter(answer => answer.status === "correct").every(answer => answer.value != null && Math.abs(answer.value) <= 1);
|
|
22460
22467
|
|
|
22461
22468
|
// The coefficient is an attribute of the widget
|
|
22462
22469
|
let localValue = currentValue;
|
|
@@ -27732,6 +27739,7 @@ class Dropdown extends React__namespace.Component {
|
|
|
27732
27739
|
}, this.props.visibleLabel), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
27733
27740
|
id: dropdownId,
|
|
27734
27741
|
placeholder: "",
|
|
27742
|
+
className: "perseus-dropdown",
|
|
27735
27743
|
onChange: value => this._handleChange(parseInt(value)),
|
|
27736
27744
|
selectedValue: String(this.props.selected),
|
|
27737
27745
|
disabled: this.props.apiOptions.readOnly,
|
|
@@ -34459,10 +34467,10 @@ function AngleGraph(props) {
|
|
|
34459
34467
|
angleMeasure,
|
|
34460
34468
|
vertexX: srFormatNumber(coords[1][X], locale),
|
|
34461
34469
|
vertexY: srFormatNumber(coords[1][Y], locale),
|
|
34462
|
-
|
|
34463
|
-
|
|
34464
|
-
|
|
34465
|
-
|
|
34470
|
+
startingSideX: srFormatNumber(coords[2][X], locale),
|
|
34471
|
+
startingSideY: srFormatNumber(coords[2][Y], locale),
|
|
34472
|
+
endingSideX: srFormatNumber(coords[0][X], locale),
|
|
34473
|
+
endingSideY: srFormatNumber(coords[0][Y], locale)
|
|
34466
34474
|
});
|
|
34467
34475
|
const formatCoordinates = (x, y) => ({
|
|
34468
34476
|
x: srFormatNumber(x, locale),
|
|
@@ -45936,7 +45944,7 @@ const init = function () {
|
|
|
45936
45944
|
|
|
45937
45945
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45938
45946
|
const libName = "@khanacademy/perseus";
|
|
45939
|
-
const libVersion = "49.
|
|
45947
|
+
const libVersion = "49.2.0";
|
|
45940
45948
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45941
45949
|
|
|
45942
45950
|
const apiVersion = {
|
|
@@ -48236,10 +48244,10 @@ class UnionBuilder {
|
|
|
48236
48244
|
this.parser = parser;
|
|
48237
48245
|
}
|
|
48238
48246
|
or(newBranch) {
|
|
48239
|
-
return new UnionBuilder(either(this.parser, newBranch));
|
|
48247
|
+
return new UnionBuilder(either$1(this.parser, newBranch));
|
|
48240
48248
|
}
|
|
48241
48249
|
}
|
|
48242
|
-
function either(parseA, parseB) {
|
|
48250
|
+
function either$1(parseA, parseB) {
|
|
48243
48251
|
return (rawValue, ctx) => {
|
|
48244
48252
|
const resultA = parseA(rawValue, ctx);
|
|
48245
48253
|
if (isSuccess(resultA)) {
|
|
@@ -48341,22 +48349,108 @@ const parseExplanationWidget = parseWidget(constant("explanation"), object({
|
|
|
48341
48349
|
// We wrap parseWidgetsMap in a function here to make sure it is not
|
|
48342
48350
|
// referenced before it is defined. There is an import cycle between
|
|
48343
48351
|
// this file and widgets-map.ts that could cause it to be undefined.
|
|
48344
|
-
widgets: (rawVal, ctx) => parseWidgetsMap(rawVal, ctx),
|
|
48345
|
-
static: boolean
|
|
48352
|
+
widgets: defaulted((rawVal, ctx) => parseWidgetsMap(rawVal, ctx), () => ({})),
|
|
48353
|
+
static: defaulted(boolean, () => false)
|
|
48346
48354
|
}));
|
|
48347
48355
|
|
|
48348
|
-
|
|
48349
|
-
|
|
48350
|
-
|
|
48351
|
-
|
|
48356
|
+
// Given a function, creates a PartialParser that converts one type to another
|
|
48357
|
+
// using that function. The returned parser never fails.
|
|
48358
|
+
function convert(f) {
|
|
48359
|
+
return (rawValue, ctx) => ctx.success(f(rawValue));
|
|
48360
|
+
}
|
|
48361
|
+
|
|
48362
|
+
/**
|
|
48363
|
+
* Creates a parser for a widget options type with multiple major versions. Old
|
|
48364
|
+
* versions are migrated to the latest version. The parse fails if the input
|
|
48365
|
+
* data does not match any of the versions.
|
|
48366
|
+
*
|
|
48367
|
+
* @example
|
|
48368
|
+
* const parseOptions = versionedWidgetOptions(parseOptionsV3)
|
|
48369
|
+
* .withMigrationFrom(parseOptionsV2, migrateV2ToV3)
|
|
48370
|
+
* .withMigrationFrom(parseOptionsV1, migrateV1ToV2)
|
|
48371
|
+
* .withMigrationFrom(parseOptionsV0, migrateV0ToV1)
|
|
48372
|
+
* .parser;
|
|
48373
|
+
*
|
|
48374
|
+
* @param parseLatest a {@link Parser} for the latest version of the widget
|
|
48375
|
+
* options. This should check version.major and fail if it's not the latest
|
|
48376
|
+
* version.
|
|
48377
|
+
* @returns a builder object, to which migrations from earlier versions can be
|
|
48378
|
+
* added. Migrations must be added in "reverse chronological" order as in the
|
|
48379
|
+
* example above.
|
|
48380
|
+
*/
|
|
48381
|
+
function versionedWidgetOptions(parseLatest) {
|
|
48382
|
+
return new VersionedWidgetOptionsParserBuilder(parseLatest, latest => latest);
|
|
48383
|
+
}
|
|
48384
|
+
class VersionedWidgetOptionsParserBuilder {
|
|
48385
|
+
constructor(parser, migrate) {
|
|
48386
|
+
this.parser = parser;
|
|
48387
|
+
this.migrate = migrate;
|
|
48388
|
+
}
|
|
48389
|
+
|
|
48390
|
+
/**
|
|
48391
|
+
* Add a migration from an old version of the widget options.
|
|
48392
|
+
*
|
|
48393
|
+
* @returns a VersionedWidgetOptionsParserBuilder whose `parser` function
|
|
48394
|
+
* is capable of migrating the old version to the latest version. The parser
|
|
48395
|
+
* will always return the latest version of the widget options on a
|
|
48396
|
+
* successful parse.
|
|
48397
|
+
* @param parseOldVersion should be a {@link Parser} for the old options
|
|
48398
|
+
* type. It should fail if version.major isn't correct.
|
|
48399
|
+
* @param migrateToNextVersion should migrate the `Old` data to the
|
|
48400
|
+
* `Migratable` version of the current VersionedWidgetOptionsParserBuilder.
|
|
48401
|
+
* Usually, this means migrating to the next major version.
|
|
48402
|
+
*/
|
|
48403
|
+
withMigrationFrom(parseOldVersion, migrateToNextVersion) {
|
|
48404
|
+
const parseLatestVersion = this.parser;
|
|
48405
|
+
const migrateToLatest = old => this.migrate(migrateToNextVersion(old));
|
|
48406
|
+
return new VersionedWidgetOptionsParserBuilder((raw, ctx) => {
|
|
48407
|
+
const resultOfParsingLatest = parseLatestVersion(raw, ctx);
|
|
48408
|
+
if (isSuccess(resultOfParsingLatest)) {
|
|
48409
|
+
return resultOfParsingLatest;
|
|
48410
|
+
}
|
|
48411
|
+
const resultOfParsingOld = parseOldVersion(raw, ctx);
|
|
48412
|
+
if (isSuccess(resultOfParsingOld)) {
|
|
48413
|
+
return success(migrateToLatest(resultOfParsingOld.value));
|
|
48414
|
+
}
|
|
48415
|
+
|
|
48416
|
+
// If we're here, neither parse succeeded. Return the failure.
|
|
48417
|
+
return resultOfParsingOld;
|
|
48418
|
+
}, migrateToLatest);
|
|
48419
|
+
}
|
|
48420
|
+
}
|
|
48421
|
+
|
|
48422
|
+
const parsePossiblyInvalidAnswerForm = object({
|
|
48423
|
+
// `value` is the possibly invalid part of this. It should always be a
|
|
48424
|
+
// string, but some answer forms don't have it. The Expression widget
|
|
48425
|
+
// ignores invalid values, so we can safely filter them out during parsing.
|
|
48426
|
+
value: optional(string),
|
|
48427
|
+
form: defaulted(boolean, () => false),
|
|
48428
|
+
simplify: defaulted(boolean, () => false),
|
|
48352
48429
|
considered: enumeration("correct", "wrong", "ungraded"),
|
|
48353
48430
|
key: pipeParsers(optional(union(string).or(number).parser)).then((key, ctx) => ctx.success(String(key))).parser
|
|
48354
48431
|
});
|
|
48355
|
-
|
|
48432
|
+
function removeInvalidAnswerForms(possiblyInvalid) {
|
|
48433
|
+
const valid = [];
|
|
48434
|
+
for (const answerForm of possiblyInvalid) {
|
|
48435
|
+
const {
|
|
48436
|
+
value
|
|
48437
|
+
} = answerForm;
|
|
48438
|
+
if (value != null) {
|
|
48439
|
+
// Copying the object seems to be needed to make TypeScript happy
|
|
48440
|
+
valid.push({
|
|
48441
|
+
...answerForm,
|
|
48442
|
+
value
|
|
48443
|
+
});
|
|
48444
|
+
}
|
|
48445
|
+
}
|
|
48446
|
+
return valid;
|
|
48447
|
+
}
|
|
48448
|
+
const version1 = object({
|
|
48356
48449
|
major: constant(1),
|
|
48357
48450
|
minor: number
|
|
48358
|
-
})
|
|
48359
|
-
|
|
48451
|
+
});
|
|
48452
|
+
const parseExpressionWidgetV1 = parseWidgetWithVersion(version1, constant("expression"), object({
|
|
48453
|
+
answerForms: pipeParsers(array(parsePossiblyInvalidAnswerForm)).then(convert(removeInvalidAnswerForms)).parser,
|
|
48360
48454
|
functions: array(string),
|
|
48361
48455
|
times: boolean,
|
|
48362
48456
|
visibleLabel: optional(string),
|
|
@@ -48364,10 +48458,11 @@ const parseExpressionWidgetV1 = parseWidgetWithVersion(object({
|
|
|
48364
48458
|
buttonSets: array(enumeration("basic", "basic+div", "trig", "prealgebra", "logarithms", "basic relations", "advanced relations")),
|
|
48365
48459
|
buttonsVisible: optional(enumeration("always", "never", "focused"))
|
|
48366
48460
|
}));
|
|
48367
|
-
const
|
|
48461
|
+
const version0 = optional(object({
|
|
48368
48462
|
major: constant(0),
|
|
48369
48463
|
minor: number
|
|
48370
|
-
}))
|
|
48464
|
+
}));
|
|
48465
|
+
const parseExpressionWidgetV0 = parseWidgetWithVersion(version0, constant("expression"), object({
|
|
48371
48466
|
functions: array(string),
|
|
48372
48467
|
times: boolean,
|
|
48373
48468
|
visibleLabel: optional(string),
|
|
@@ -48378,11 +48473,11 @@ const parseExpressionWidgetV0 = parseWidgetWithVersion(optional(object({
|
|
|
48378
48473
|
buttonSets: array(enumeration("basic", "basic+div", "trig", "prealgebra", "logarithms", "basic relations", "advanced relations")),
|
|
48379
48474
|
buttonsVisible: optional(enumeration("always", "never", "focused"))
|
|
48380
48475
|
}));
|
|
48381
|
-
function migrateV0ToV1(widget
|
|
48476
|
+
function migrateV0ToV1(widget) {
|
|
48382
48477
|
const {
|
|
48383
48478
|
options
|
|
48384
48479
|
} = widget;
|
|
48385
|
-
return
|
|
48480
|
+
return {
|
|
48386
48481
|
...widget,
|
|
48387
48482
|
version: {
|
|
48388
48483
|
major: 1,
|
|
@@ -48402,9 +48497,9 @@ function migrateV0ToV1(widget, ctx) {
|
|
|
48402
48497
|
value: options.value
|
|
48403
48498
|
}]
|
|
48404
48499
|
}
|
|
48405
|
-
}
|
|
48500
|
+
};
|
|
48406
48501
|
}
|
|
48407
|
-
const parseExpressionWidget =
|
|
48502
|
+
const parseExpressionWidget = versionedWidgetOptions(parseExpressionWidgetV1).withMigrationFrom(parseExpressionWidgetV0, migrateV0ToV1).parser;
|
|
48408
48503
|
|
|
48409
48504
|
const parsePerseusRenderer = defaulted(object({
|
|
48410
48505
|
// TODO(benchristel): content is also defaulted to empty string in
|
|
@@ -48450,31 +48545,70 @@ const parseGradedGroupSetWidget = parseWidget(constant("graded-group-set"), obje
|
|
|
48450
48545
|
gradedGroups: array(parseGradedGroupWidgetOptions)
|
|
48451
48546
|
}));
|
|
48452
48547
|
|
|
48548
|
+
// discriminatedUnion() should be preferred over union() when parsing a
|
|
48549
|
+
// discriminated union type, because discriminatedUnion() produces more
|
|
48550
|
+
// understandable failure messages. It takes the discriminant as the source of
|
|
48551
|
+
// truth for which variant is to be parsed, and expects the other data to match
|
|
48552
|
+
// that variant.
|
|
48553
|
+
function discriminatedUnion(narrow, parseVariant) {
|
|
48554
|
+
return new DiscriminatedUnionBuilder(pipeParsers(narrow).then(parseVariant).parser);
|
|
48555
|
+
}
|
|
48556
|
+
class DiscriminatedUnionBuilder {
|
|
48557
|
+
constructor(parser) {
|
|
48558
|
+
this.parser = parser;
|
|
48559
|
+
}
|
|
48560
|
+
or(narrow, parseVariant) {
|
|
48561
|
+
return new DiscriminatedUnionBuilder(either(narrow, parseVariant, this.parser));
|
|
48562
|
+
}
|
|
48563
|
+
}
|
|
48564
|
+
function either(narrowToA, parseA, parseB) {
|
|
48565
|
+
return (rawValue, ctx) => {
|
|
48566
|
+
if (isSuccess(narrowToA(rawValue, ctx))) {
|
|
48567
|
+
return parseA(rawValue, ctx);
|
|
48568
|
+
}
|
|
48569
|
+
return parseB(rawValue, ctx);
|
|
48570
|
+
};
|
|
48571
|
+
}
|
|
48572
|
+
|
|
48453
48573
|
const pairOfNumbers$3 = pair(number, number);
|
|
48454
48574
|
const pairOfPoints = pair(pairOfNumbers$3, pairOfNumbers$3);
|
|
48455
48575
|
const parseGrapherWidget = parseWidget(constant("grapher"), object({
|
|
48456
48576
|
availableTypes: array(enumeration("absolute_value", "exponential", "linear", "logarithm", "quadratic", "sinusoid", "tangent")),
|
|
48457
|
-
correct:
|
|
48577
|
+
correct: discriminatedUnion(object({
|
|
48578
|
+
type: constant("absolute_value")
|
|
48579
|
+
}), object({
|
|
48458
48580
|
type: constant("absolute_value"),
|
|
48459
48581
|
coords: pairOfPoints
|
|
48460
48582
|
})).or(object({
|
|
48583
|
+
type: constant("exponential")
|
|
48584
|
+
}), object({
|
|
48461
48585
|
type: constant("exponential"),
|
|
48462
48586
|
asymptote: pairOfPoints,
|
|
48463
48587
|
coords: pairOfPoints
|
|
48464
48588
|
})).or(object({
|
|
48589
|
+
type: constant("linear")
|
|
48590
|
+
}), object({
|
|
48465
48591
|
type: constant("linear"),
|
|
48466
48592
|
coords: pairOfPoints
|
|
48467
48593
|
})).or(object({
|
|
48594
|
+
type: constant("logarithm")
|
|
48595
|
+
}), object({
|
|
48468
48596
|
type: constant("logarithm"),
|
|
48469
48597
|
asymptote: pairOfPoints,
|
|
48470
48598
|
coords: pairOfPoints
|
|
48471
48599
|
})).or(object({
|
|
48600
|
+
type: constant("quadratic")
|
|
48601
|
+
}), object({
|
|
48472
48602
|
type: constant("quadratic"),
|
|
48473
48603
|
coords: pairOfPoints
|
|
48474
48604
|
})).or(object({
|
|
48605
|
+
type: constant("sinusoid")
|
|
48606
|
+
}), object({
|
|
48475
48607
|
type: constant("sinusoid"),
|
|
48476
48608
|
coords: pairOfPoints
|
|
48477
48609
|
})).or(object({
|
|
48610
|
+
type: constant("tangent")
|
|
48611
|
+
}), object({
|
|
48478
48612
|
type: constant("tangent"),
|
|
48479
48613
|
coords: pairOfPoints
|
|
48480
48614
|
})).parser,
|
|
@@ -48534,15 +48668,22 @@ const stringToNumber = (rawValue, ctx) => {
|
|
|
48534
48668
|
return ctx.success(parsedNumber);
|
|
48535
48669
|
};
|
|
48536
48670
|
|
|
48537
|
-
|
|
48671
|
+
function emptyToZero(x) {
|
|
48672
|
+
return x === "" ? 0 : x;
|
|
48673
|
+
}
|
|
48674
|
+
const imageDimensionToNumber = pipeParsers(union(number).or(string).parser)
|
|
48675
|
+
// In this specific case, empty string is equivalent to zero. An empty
|
|
48676
|
+
// string parses to either NaN (using parseInt) or 0 (using unary +) and
|
|
48677
|
+
// CSS will treat NaN as invalid and default to 0 instead.
|
|
48678
|
+
.then(convert(emptyToZero)).then(stringToNumber).parser;
|
|
48538
48679
|
const parsePerseusImageBackground = object({
|
|
48539
48680
|
url: optional(nullable(string)),
|
|
48540
|
-
width: optional(
|
|
48541
|
-
height: optional(
|
|
48542
|
-
top: optional(
|
|
48543
|
-
left: optional(
|
|
48544
|
-
bottom: optional(
|
|
48545
|
-
scale: optional(
|
|
48681
|
+
width: optional(imageDimensionToNumber),
|
|
48682
|
+
height: optional(imageDimensionToNumber),
|
|
48683
|
+
top: optional(imageDimensionToNumber),
|
|
48684
|
+
left: optional(imageDimensionToNumber),
|
|
48685
|
+
bottom: optional(imageDimensionToNumber),
|
|
48686
|
+
scale: optional(imageDimensionToNumber)
|
|
48546
48687
|
});
|
|
48547
48688
|
|
|
48548
48689
|
const pairOfNumbers$2 = pair(number, number);
|
|
@@ -48583,8 +48724,10 @@ const parseInputNumberWidget = parseWidget(constant("input-number"), object({
|
|
|
48583
48724
|
}));
|
|
48584
48725
|
|
|
48585
48726
|
const pairOfNumbers$1 = pair(number, number);
|
|
48727
|
+
const stringOrEmpty = defaulted(string, () => "");
|
|
48728
|
+
const parseFunctionType = constant("function");
|
|
48586
48729
|
const parseFunctionElement = object({
|
|
48587
|
-
type:
|
|
48730
|
+
type: parseFunctionType,
|
|
48588
48731
|
key: string,
|
|
48589
48732
|
options: object({
|
|
48590
48733
|
value: string,
|
|
@@ -48596,8 +48739,9 @@ const parseFunctionElement = object({
|
|
|
48596
48739
|
strokeWidth: number
|
|
48597
48740
|
})
|
|
48598
48741
|
});
|
|
48742
|
+
const parseLabelType = constant("label");
|
|
48599
48743
|
const parseLabelElement = object({
|
|
48600
|
-
type:
|
|
48744
|
+
type: parseLabelType,
|
|
48601
48745
|
key: string,
|
|
48602
48746
|
options: object({
|
|
48603
48747
|
label: string,
|
|
@@ -48606,8 +48750,9 @@ const parseLabelElement = object({
|
|
|
48606
48750
|
coordY: string
|
|
48607
48751
|
})
|
|
48608
48752
|
});
|
|
48753
|
+
const parseLineType = constant("line");
|
|
48609
48754
|
const parseLineElement = object({
|
|
48610
|
-
type:
|
|
48755
|
+
type: parseLineType,
|
|
48611
48756
|
key: string,
|
|
48612
48757
|
options: object({
|
|
48613
48758
|
color: string,
|
|
@@ -48620,8 +48765,9 @@ const parseLineElement = object({
|
|
|
48620
48765
|
arrows: string
|
|
48621
48766
|
})
|
|
48622
48767
|
});
|
|
48768
|
+
const parseMovableLineType = constant("movable-line");
|
|
48623
48769
|
const parseMovableLineElement = object({
|
|
48624
|
-
type:
|
|
48770
|
+
type: parseMovableLineType,
|
|
48625
48771
|
key: string,
|
|
48626
48772
|
options: object({
|
|
48627
48773
|
startX: string,
|
|
@@ -48639,8 +48785,9 @@ const parseMovableLineElement = object({
|
|
|
48639
48785
|
constraintYMax: string
|
|
48640
48786
|
})
|
|
48641
48787
|
});
|
|
48788
|
+
const parseMovablePointType = constant("movable-point");
|
|
48642
48789
|
const parseMovablePointElement = object({
|
|
48643
|
-
type:
|
|
48790
|
+
type: parseMovablePointType,
|
|
48644
48791
|
key: string,
|
|
48645
48792
|
options: object({
|
|
48646
48793
|
startX: string,
|
|
@@ -48649,14 +48796,15 @@ const parseMovablePointElement = object({
|
|
|
48649
48796
|
constraint: string,
|
|
48650
48797
|
snap: number,
|
|
48651
48798
|
constraintFn: string,
|
|
48652
|
-
constraintXMin:
|
|
48653
|
-
constraintXMax:
|
|
48654
|
-
constraintYMin:
|
|
48655
|
-
constraintYMax:
|
|
48799
|
+
constraintXMin: stringOrEmpty,
|
|
48800
|
+
constraintXMax: stringOrEmpty,
|
|
48801
|
+
constraintYMin: stringOrEmpty,
|
|
48802
|
+
constraintYMax: stringOrEmpty
|
|
48656
48803
|
})
|
|
48657
48804
|
});
|
|
48805
|
+
const parseParametricType = constant("parametric");
|
|
48658
48806
|
const parseParametricElement = object({
|
|
48659
|
-
type:
|
|
48807
|
+
type: parseParametricType,
|
|
48660
48808
|
key: string,
|
|
48661
48809
|
options: object({
|
|
48662
48810
|
x: string,
|
|
@@ -48668,8 +48816,9 @@ const parseParametricElement = object({
|
|
|
48668
48816
|
strokeWidth: number
|
|
48669
48817
|
})
|
|
48670
48818
|
});
|
|
48819
|
+
const parsePointType = constant("point");
|
|
48671
48820
|
const parsePointElement = object({
|
|
48672
|
-
type:
|
|
48821
|
+
type: parsePointType,
|
|
48673
48822
|
key: string,
|
|
48674
48823
|
options: object({
|
|
48675
48824
|
color: string,
|
|
@@ -48677,8 +48826,9 @@ const parsePointElement = object({
|
|
|
48677
48826
|
coordY: string
|
|
48678
48827
|
})
|
|
48679
48828
|
});
|
|
48829
|
+
const parseRectangleType = constant("rectangle");
|
|
48680
48830
|
const parseRectangleElement = object({
|
|
48681
|
-
type:
|
|
48831
|
+
type: parseRectangleType,
|
|
48682
48832
|
key: string,
|
|
48683
48833
|
options: object({
|
|
48684
48834
|
color: string,
|
|
@@ -48689,7 +48839,7 @@ const parseRectangleElement = object({
|
|
|
48689
48839
|
})
|
|
48690
48840
|
});
|
|
48691
48841
|
const parseInteractionWidget = parseWidget(constant("interaction"), object({
|
|
48692
|
-
static: boolean,
|
|
48842
|
+
static: defaulted(boolean, () => false),
|
|
48693
48843
|
graph: object({
|
|
48694
48844
|
editableSettings: optional(array(enumeration("canvas", "graph"))),
|
|
48695
48845
|
box: pairOfNumbers$1,
|
|
@@ -48706,7 +48856,23 @@ const parseInteractionWidget = parseWidget(constant("interaction"), object({
|
|
|
48706
48856
|
rulerTicks: optional(number),
|
|
48707
48857
|
tickStep: pairOfNumbers$1
|
|
48708
48858
|
}),
|
|
48709
|
-
elements: array(
|
|
48859
|
+
elements: array(discriminatedUnion(object({
|
|
48860
|
+
type: parseFunctionType
|
|
48861
|
+
}), parseFunctionElement).or(object({
|
|
48862
|
+
type: parseLabelType
|
|
48863
|
+
}), parseLabelElement).or(object({
|
|
48864
|
+
type: parseLineType
|
|
48865
|
+
}), parseLineElement).or(object({
|
|
48866
|
+
type: parseMovableLineType
|
|
48867
|
+
}), parseMovableLineElement).or(object({
|
|
48868
|
+
type: parseMovablePointType
|
|
48869
|
+
}), parseMovablePointElement).or(object({
|
|
48870
|
+
type: parseParametricType
|
|
48871
|
+
}), parseParametricElement).or(object({
|
|
48872
|
+
type: parsePointType
|
|
48873
|
+
}), parsePointElement).or(object({
|
|
48874
|
+
type: parseRectangleType
|
|
48875
|
+
}), parseRectangleElement).parser)
|
|
48710
48876
|
}));
|
|
48711
48877
|
|
|
48712
48878
|
// Used to represent 2-D points and ranges
|
|
@@ -48929,10 +49095,11 @@ const parseMatcherWidget = parseWidget(constant("matcher"), object({
|
|
|
48929
49095
|
padding: boolean
|
|
48930
49096
|
}));
|
|
48931
49097
|
|
|
49098
|
+
const numeric = pipeParsers(union(number).or(string).parser).then(stringToNumber).parser;
|
|
48932
49099
|
const parseMatrixWidget = parseWidget(defaulted(constant("matrix"), () => "matrix"), object({
|
|
48933
49100
|
prefix: optional(string),
|
|
48934
49101
|
suffix: optional(string),
|
|
48935
|
-
answers: array(array(
|
|
49102
|
+
answers: array(array(numeric)),
|
|
48936
49103
|
cursorPosition: optional(array(number)),
|
|
48937
49104
|
matrixBoardSize: array(number),
|
|
48938
49105
|
static: optional(boolean)
|
|
@@ -48980,12 +49147,18 @@ const parseMathFormat = enumeration("integer", "mixed", "improper", "proper", "d
|
|
|
48980
49147
|
const parseNumericInputWidget = parseWidget(constant("numeric-input"), object({
|
|
48981
49148
|
answers: array(object({
|
|
48982
49149
|
message: string,
|
|
48983
|
-
|
|
49150
|
+
// TODO(benchristel): value should never be null or undefined,
|
|
49151
|
+
// but we have some content where it is anyway. If we backfill
|
|
49152
|
+
// the data, simplify this.
|
|
49153
|
+
value: optional(nullable(number)),
|
|
48984
49154
|
status: string,
|
|
48985
49155
|
answerForms: optional(array(parseMathFormat)),
|
|
48986
49156
|
strict: boolean,
|
|
48987
49157
|
maxError: optional(nullable(number)),
|
|
48988
|
-
|
|
49158
|
+
// TODO(benchristel): simplify should never be `true`, but we
|
|
49159
|
+
// have some content where it is anyway. If we ever backfill
|
|
49160
|
+
// the data, we should simplify `simplify`.
|
|
49161
|
+
simplify: optional(nullable(union(string).or(pipeParsers(constant(true)).then(convert(String)).parser).parser))
|
|
48989
49162
|
})),
|
|
48990
49163
|
labelText: optional(string),
|
|
48991
49164
|
size: string,
|
|
@@ -49021,7 +49194,7 @@ const parseOrdererWidget = parseWidget(constant("orderer"), object({
|
|
|
49021
49194
|
const parsePassageRefWidget = parseWidget(constant("passage-ref"), object({
|
|
49022
49195
|
passageNumber: number,
|
|
49023
49196
|
referenceNumber: number,
|
|
49024
|
-
summaryText: string
|
|
49197
|
+
summaryText: optional(string)
|
|
49025
49198
|
}));
|
|
49026
49199
|
|
|
49027
49200
|
const parsePassageWidget = parseWidget(constant("passage"), object({
|
|
@@ -49210,6 +49383,8 @@ const parseWidgetsMapEntry = (_ref, widgetMap, ctx) => {
|
|
|
49210
49383
|
// sequence is a deprecated widget type, and the corresponding
|
|
49211
49384
|
// widget component no longer exists.
|
|
49212
49385
|
return parseAndAssign(`sequence ${id}`, parseDeprecatedWidget);
|
|
49386
|
+
case "lights-puzzle":
|
|
49387
|
+
return parseAndAssign(`lights-puzzle ${id}`, parseDeprecatedWidget);
|
|
49213
49388
|
default:
|
|
49214
49389
|
if (getWidget(type)) {
|
|
49215
49390
|
// @ts-expect-error - 'type' is not a valid widget type
|