@khanacademy/perseus 38.0.1 → 39.0.1
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 +1 -1
- package/dist/components/sortable.d.ts +1 -1
- package/dist/definition-context.d.ts +1 -1
- package/dist/es/index.js +121 -226
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +96 -202
- package/dist/index.js.map +1 -1
- package/dist/interactive2/movable-point.d.ts +1 -1
- package/dist/multi-items/prop-type-builders.d.ts +0 -6
- package/dist/perseus-api.d.ts +3 -1
- package/dist/perseus-types.d.ts +3 -42
- package/dist/renderer.d.ts +1 -2
- package/dist/server-item-renderer.d.ts +3 -2
- package/dist/sigfigs.d.ts +0 -16
- package/dist/styles/constants.d.ts +0 -18
- package/dist/types.d.ts +4 -6
- package/dist/util/math.d.ts +0 -1
- package/dist/util.d.ts +2 -1
- package/dist/validation.types.d.ts +17 -16
- package/dist/widgets/__shared__/noop-validator.d.ts +1 -1
- package/dist/widgets/definition/definition.d.ts +1 -2
- package/dist/widgets/explanation/explanation.d.ts +1 -2
- package/dist/widgets/expression/expression.d.ts +25 -12
- package/dist/widgets/iframe/iframe-validator.d.ts +1 -1
- package/dist/widgets/image/image.d.ts +1 -2
- package/dist/widgets/input-number/input-number.d.ts +0 -1
- package/dist/widgets/interaction/interaction.d.ts +1 -2
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +0 -11
- package/dist/widgets/interactive-graphs/graphs/point.d.ts +0 -2
- package/dist/widgets/interactive-graphs/graphs/use-transform.d.ts +0 -1
- package/dist/widgets/interactive-graphs/mafs-supported-graph-types.d.ts +2 -1
- package/dist/widgets/interactive-graphs/protractor.d.ts +0 -2
- package/dist/widgets/label-image/answer-choices.d.ts +1 -1
- package/dist/widgets/label-image/label-image.d.ts +12 -28
- package/dist/widgets/matrix/matrix-validator.d.ts +1 -1
- package/dist/widgets/matrix/matrix.d.ts +0 -1
- package/dist/widgets/measurer/measurer.d.ts +3 -15
- package/dist/widgets/molecule/molecule.d.ts +0 -21
- package/dist/widgets/number-line/number-line.d.ts +0 -1
- package/dist/widgets/numeric-input/numeric-input.d.ts +0 -1
- package/dist/widgets/orderer/orderer.d.ts +1 -1
- package/dist/widgets/passage/passage.d.ts +1 -2
- package/dist/widgets/passage-ref/passage-ref.d.ts +1 -2
- package/dist/widgets/radio/base-radio.d.ts +5 -10
- package/dist/widgets/radio/focus-ring.d.ts +4 -11
- package/dist/widgets/table/table.d.ts +0 -1
- package/dist/widgets/video/video.d.ts +1 -2
- package/package.json +3 -3
- package/dist/util/fix-passage-refs.d.ts +0 -3
- package/dist/widgets/radio/choice.jsx.fixture.d.ts +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -84,7 +84,7 @@ export type { ILogger, LogErrorOptions } from "./logging/log";
|
|
|
84
84
|
export type { ServerItemRenderer as ServerItemRendererComponent } from "./server-item-renderer";
|
|
85
85
|
export type { Alignment, APIOptions, APIOptionsWithDefaults, ChangeHandler, DeviceType, DomInsertCheckFn, EditorMode, FocusPath, ImageDict, ImageUploader, JiptLabelStore, JiptRenderer, PerseusDependencies, PerseusScore, Version, VideoData, VideoKind, WidgetExports, SharedRendererProps, } from "./types";
|
|
86
86
|
export type { ParsedValue } from "./util";
|
|
87
|
-
export type { Hint, LegacyButtonSets, LockedFigure, LockedFigureColor, LockedFigureFillType, LockedFigureType, LockedPointType, LockedLineType, LockedVectorType, LockedEllipseType, LockedPolygonType, LockedFunctionType, LockedLabelType, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, CollinearTuple, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
|
|
87
|
+
export type { Hint, LegacyButtonSets, LockedFigure, LockedFigureColor, LockedFigureFillType, LockedFigureType, LockedPointType, LockedLineType, LockedVectorType, LockedEllipseType, LockedPolygonType, LockedFunctionType, LockedLabelType, LockedLineStyle, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, CollinearTuple, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
|
|
88
88
|
PerseusImageBackground, PerseusInputNumberWidgetOptions, PerseusInteractiveGraphWidgetOptions, PerseusItem, PerseusPhetSimulationWidgetOptions, PerseusPlotterWidgetOptions, PerseusPythonProgramWidgetOptions, PerseusRadioWidgetOptions, PerseusExampleWidgetOptions, PerseusSimpleMarkdownTesterWidgetOptions, PerseusRenderer, PerseusWidget, PerseusWidgetsMap, MultiItem, } from "./perseus-types";
|
|
89
89
|
export type { Coord } from "./interactive2/types";
|
|
90
90
|
export type { MarkerType } from "./widgets/label-image/types";
|
package/dist/index.js
CHANGED
|
@@ -2530,12 +2530,6 @@ class Expression extends React__namespace.Component {
|
|
|
2530
2530
|
/* c8 ignore next */
|
|
2531
2531
|
return [[]];
|
|
2532
2532
|
};
|
|
2533
|
-
|
|
2534
|
-
// TODO(Nicole): I believe this is going away and won't be needed anymore
|
|
2535
|
-
getGrammarTypeForPath(inputPath) {
|
|
2536
|
-
/* c8 ignore next */
|
|
2537
|
-
return "expression";
|
|
2538
|
-
}
|
|
2539
2533
|
setInputValue(path, newValue, cb) {
|
|
2540
2534
|
this.props.onChange({
|
|
2541
2535
|
value: newValue
|
|
@@ -2995,7 +2989,9 @@ function flattenScores(widgetScoreMap) {
|
|
|
2995
2989
|
function isCorrect(score) {
|
|
2996
2990
|
return score.type === "points" && score.earned >= score.total;
|
|
2997
2991
|
}
|
|
2998
|
-
function keScoreFromPerseusScore(score,
|
|
2992
|
+
function keScoreFromPerseusScore(score,
|
|
2993
|
+
// It's weird, but this is what we're passing it
|
|
2994
|
+
guess, state) {
|
|
2999
2995
|
if (score.type === "points") {
|
|
3000
2996
|
return {
|
|
3001
2997
|
empty: false,
|
|
@@ -4006,36 +4002,14 @@ const ZoomService = new ZoomServiceClass();
|
|
|
4006
4002
|
const baseFontFamily$1 = "'Lato', sans-serif";
|
|
4007
4003
|
// @boldFontFamily: "Lato-Bold", "Lato", sans-serif;
|
|
4008
4004
|
const boldFontFamily = "'Lato-Bold', 'Lato', sans-serif";
|
|
4009
|
-
// @green: #76a005;
|
|
4010
|
-
const green$1 = "#76A005";
|
|
4011
4005
|
// @kaGreen: #71b307;
|
|
4012
4006
|
const kaGreen$1 = "#71B307";
|
|
4013
|
-
// @blue: #1c758a;
|
|
4014
|
-
const blue$1 = "#1C758A";
|
|
4015
|
-
// @gray: #aaa;
|
|
4016
|
-
const gray$1 = "#AAAAAA";
|
|
4017
|
-
// @red: #ffbaba;
|
|
4018
|
-
const red$1 = "#FFBABA";
|
|
4019
|
-
// @grayLight: #aaa;
|
|
4020
|
-
const grayLight$1 = "#AAAAAA";
|
|
4021
|
-
// @grayLighter: #ddd;
|
|
4022
|
-
const grayLighter$1 = "#DDDDDD";
|
|
4023
|
-
// @learnstormBlue: #4898fc;
|
|
4024
|
-
const learnstormBlue$1 = "#4898FC";
|
|
4025
4007
|
const white$1 = "#FFFFFF";
|
|
4026
|
-
const gray98 = "#FAFAFA";
|
|
4027
4008
|
const gray97 = "#F6F7F7";
|
|
4028
|
-
const gray95 = "#F0F1F2";
|
|
4029
|
-
const gray90 = "#E3E5E6";
|
|
4030
4009
|
const gray85 = "#D6D8DA";
|
|
4031
4010
|
const gray76 = "#BABEC2";
|
|
4032
4011
|
const gray68 = "#888D93";
|
|
4033
|
-
const gray41 = "#626569";
|
|
4034
|
-
const gray25 = "#3B3e40";
|
|
4035
4012
|
const gray17 = "#21242c";
|
|
4036
|
-
const black$1 = "#000000";
|
|
4037
|
-
const warning1 = "#F86700";
|
|
4038
|
-
const warning3 = "#C75300";
|
|
4039
4013
|
|
|
4040
4014
|
// @pure-sm-min: 568px;
|
|
4041
4015
|
const pureSmMin$2 = "568px";
|
|
@@ -4055,16 +4029,10 @@ const pureMdMax$2 = "1023px";
|
|
|
4055
4029
|
const pureLgMax$2 = "1279px";
|
|
4056
4030
|
// @tableBackgroundAccent: #f9f9f9; // for striping
|
|
4057
4031
|
const tableBackgroundAccent$1 = "#F9F9F9";
|
|
4058
|
-
// @zIndexScratchPad: 1;
|
|
4059
|
-
const zIndexScratchPad = 1;
|
|
4060
4032
|
// @zIndexAboveScratchpad: @zIndexScratchPad + 1;
|
|
4061
4033
|
const zIndexAboveScratchpad$1 = 2;
|
|
4062
4034
|
// @zIndexInteractiveComponent: @zIndexAboveScratchpad + 1;
|
|
4063
4035
|
const zIndexInteractiveComponent$1 = 3;
|
|
4064
|
-
// @zIndexCurrentlyDragging: @zIndexInteractiveComponent + 1;
|
|
4065
|
-
const zIndexCurrentlyDragging = 4;
|
|
4066
|
-
// @zIndexCalculator: @zIndexCurrentlyDragging + 1;
|
|
4067
|
-
const zIndexCalculator = 5;
|
|
4068
4036
|
// @phoneMargin: 16px;
|
|
4069
4037
|
const phoneMargin = 16;
|
|
4070
4038
|
const negativePhoneMargin = -16;
|
|
@@ -4092,28 +4060,13 @@ var constants$1 = /*#__PURE__*/Object.freeze({
|
|
|
4092
4060
|
__proto__: null,
|
|
4093
4061
|
baseFontFamily: baseFontFamily$1,
|
|
4094
4062
|
boldFontFamily: boldFontFamily,
|
|
4095
|
-
green: green$1,
|
|
4096
4063
|
kaGreen: kaGreen$1,
|
|
4097
|
-
blue: blue$1,
|
|
4098
|
-
gray: gray$1,
|
|
4099
|
-
red: red$1,
|
|
4100
|
-
grayLight: grayLight$1,
|
|
4101
|
-
grayLighter: grayLighter$1,
|
|
4102
|
-
learnstormBlue: learnstormBlue$1,
|
|
4103
4064
|
white: white$1,
|
|
4104
|
-
gray98: gray98,
|
|
4105
4065
|
gray97: gray97,
|
|
4106
|
-
gray95: gray95,
|
|
4107
|
-
gray90: gray90,
|
|
4108
4066
|
gray85: gray85,
|
|
4109
4067
|
gray76: gray76,
|
|
4110
4068
|
gray68: gray68,
|
|
4111
|
-
gray41: gray41,
|
|
4112
|
-
gray25: gray25,
|
|
4113
4069
|
gray17: gray17,
|
|
4114
|
-
black: black$1,
|
|
4115
|
-
warning1: warning1,
|
|
4116
|
-
warning3: warning3,
|
|
4117
4070
|
pureSmMin: pureSmMin$2,
|
|
4118
4071
|
pureMdMin: pureMdMin$2,
|
|
4119
4072
|
pureLgMin: pureLgMin$2,
|
|
@@ -4123,11 +4076,8 @@ var constants$1 = /*#__PURE__*/Object.freeze({
|
|
|
4123
4076
|
pureMdMax: pureMdMax$2,
|
|
4124
4077
|
pureLgMax: pureLgMax$2,
|
|
4125
4078
|
tableBackgroundAccent: tableBackgroundAccent$1,
|
|
4126
|
-
zIndexScratchPad: zIndexScratchPad,
|
|
4127
4079
|
zIndexAboveScratchpad: zIndexAboveScratchpad$1,
|
|
4128
4080
|
zIndexInteractiveComponent: zIndexInteractiveComponent$1,
|
|
4129
|
-
zIndexCurrentlyDragging: zIndexCurrentlyDragging,
|
|
4130
|
-
zIndexCalculator: zIndexCalculator,
|
|
4131
4081
|
phoneMargin: phoneMargin,
|
|
4132
4082
|
negativePhoneMargin: negativePhoneMargin,
|
|
4133
4083
|
hintBorderWidth: hintBorderWidth,
|
|
@@ -20119,6 +20069,7 @@ class Renderer extends React__namespace.Component {
|
|
|
20119
20069
|
onBlur: ___default["default"].partial(this._onWidgetBlur, id),
|
|
20120
20070
|
findWidgets: this.findWidgets,
|
|
20121
20071
|
reviewModeRubric: reviewModeRubric,
|
|
20072
|
+
reviewMode: this.props.reviewMode,
|
|
20122
20073
|
onChange: function (newProps, cb) {
|
|
20123
20074
|
let silent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
20124
20075
|
_this._setWidgetProps(id, newProps, cb, silent);
|
|
@@ -20832,14 +20783,6 @@ class Renderer extends React__namespace.Component {
|
|
|
20832
20783
|
return ReactDOM__default["default"].findDOMNode(widget);
|
|
20833
20784
|
}
|
|
20834
20785
|
};
|
|
20835
|
-
getGrammarTypeForPath = path => {
|
|
20836
|
-
// @ts-expect-error - TS2345 - Argument of type 'FocusPath' is not assignable to parameter of type 'List<any>'.
|
|
20837
|
-
const widgetId = ___default["default"].first(path);
|
|
20838
|
-
// @ts-expect-error - TS2345 - Argument of type 'FocusPath' is not assignable to parameter of type 'List<any>'.
|
|
20839
|
-
const interWidgetPath = ___default["default"].rest(path);
|
|
20840
|
-
const widget = this.getWidgetInstance(widgetId);
|
|
20841
|
-
return widget?.getGrammarTypeForPath?.(interWidgetPath);
|
|
20842
|
-
};
|
|
20843
20786
|
getInputPaths = () => {
|
|
20844
20787
|
const inputPaths = [];
|
|
20845
20788
|
___default["default"].each(this.widgetIds, widgetId => {
|
|
@@ -21040,11 +20983,11 @@ class Renderer extends React__namespace.Component {
|
|
|
21040
20983
|
const combinedScore = Util.flattenScores(scores);
|
|
21041
20984
|
return combinedScore;
|
|
21042
20985
|
}
|
|
21043
|
-
guessAndScore
|
|
20986
|
+
guessAndScore() {
|
|
21044
20987
|
const totalGuess = this.getUserInput();
|
|
21045
20988
|
const totalScore = this.score();
|
|
21046
20989
|
return [totalGuess, totalScore];
|
|
21047
|
-
}
|
|
20990
|
+
}
|
|
21048
20991
|
examples = () => {
|
|
21049
20992
|
const widgetIds = this.widgetIds;
|
|
21050
20993
|
const examples = ___default["default"].compact(___default["default"].map(widgetIds, widgetId => {
|
|
@@ -21317,7 +21260,14 @@ const Triangle = props => {
|
|
|
21317
21260
|
}
|
|
21318
21261
|
});
|
|
21319
21262
|
};
|
|
21320
|
-
const TooltipArrow =
|
|
21263
|
+
const TooltipArrow = _ref => {
|
|
21264
|
+
let {
|
|
21265
|
+
position = "relative",
|
|
21266
|
+
visibility = "visible",
|
|
21267
|
+
left = 100,
|
|
21268
|
+
top = 0,
|
|
21269
|
+
...props
|
|
21270
|
+
} = _ref;
|
|
21321
21271
|
// TODO(aria): Think about adding a box-shadow to the triangle here
|
|
21322
21272
|
// See http://css-tricks.com/triangle-with-shadow/
|
|
21323
21273
|
|
|
@@ -21328,10 +21278,10 @@ const TooltipArrow = props => {
|
|
|
21328
21278
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
21329
21279
|
style: {
|
|
21330
21280
|
display: "block",
|
|
21331
|
-
position:
|
|
21332
|
-
visibility:
|
|
21333
|
-
left:
|
|
21334
|
-
top:
|
|
21281
|
+
position: position,
|
|
21282
|
+
visibility: visibility,
|
|
21283
|
+
left: left,
|
|
21284
|
+
top: top,
|
|
21335
21285
|
width: props.width + 2,
|
|
21336
21286
|
height: props.height + 1,
|
|
21337
21287
|
marginTop: -1,
|
|
@@ -21357,12 +21307,6 @@ const TooltipArrow = props => {
|
|
|
21357
21307
|
height: props.height
|
|
21358
21308
|
}));
|
|
21359
21309
|
};
|
|
21360
|
-
TooltipArrow.defaultProps = {
|
|
21361
|
-
position: "relative",
|
|
21362
|
-
visibility: "visible",
|
|
21363
|
-
left: 0,
|
|
21364
|
-
top: 0
|
|
21365
|
-
};
|
|
21366
21310
|
const VERTICAL_CORNERS = {
|
|
21367
21311
|
top: {
|
|
21368
21312
|
top: "-100%"
|
|
@@ -22023,13 +21967,6 @@ class InputNumber extends React__namespace.Component {
|
|
|
22023
21967
|
/* c8 ignore next */
|
|
22024
21968
|
return [[]];
|
|
22025
21969
|
};
|
|
22026
|
-
|
|
22027
|
-
// Note: We believe that this isn't used anywhere but are leaving it during
|
|
22028
|
-
// the initial refactor
|
|
22029
|
-
getGrammarTypeForPath = path => {
|
|
22030
|
-
/* c8 ignore next */
|
|
22031
|
-
return "number";
|
|
22032
|
-
};
|
|
22033
21970
|
setInputValue = (path, newValue, cb) => {
|
|
22034
21971
|
this.props.onChange({
|
|
22035
21972
|
currentValue: newValue
|
|
@@ -22067,17 +22004,13 @@ class InputNumber extends React__namespace.Component {
|
|
|
22067
22004
|
}
|
|
22068
22005
|
return input;
|
|
22069
22006
|
}
|
|
22070
|
-
// HACK(johnsullivan): Create a function with shared logic between
|
|
22071
|
-
// this and NumericInput.
|
|
22072
|
-
// TODO(jeremy): Deprecate this widget and prefer numeric-input.
|
|
22073
|
-
const rubric = this.props.reviewModeRubric;
|
|
22074
22007
|
|
|
22075
22008
|
// Note: This is _very_ similar to what `numeric-input.jsx` does. If
|
|
22076
22009
|
// you modify this, double-check if you also need to modify that
|
|
22077
22010
|
// component.
|
|
22078
22011
|
const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
|
|
22079
22012
|
// Unanswered
|
|
22080
|
-
if (
|
|
22013
|
+
if (this.props.reviewMode && !this.props.currentValue) {
|
|
22081
22014
|
inputStyles.push(styles$A.answerStateUnanswered);
|
|
22082
22015
|
}
|
|
22083
22016
|
return /*#__PURE__*/React__namespace.createElement(InputWithExamples
|
|
@@ -22244,48 +22177,35 @@ function numericInputValidator(userInput, rubric, strings) {
|
|
|
22244
22177
|
// We may have received TeX; try to parse it before grading.
|
|
22245
22178
|
// If `currentValue` is not TeX, this should be a no-op.
|
|
22246
22179
|
const currentValue = ParseTex(userInput.currentValue);
|
|
22247
|
-
const
|
|
22248
|
-
const normalizedAnswerExpected = correctAnswers.every(answer => Math.abs(answer.value) <= 1);
|
|
22249
|
-
|
|
22250
|
-
// Look through all correct answers for one that matches either
|
|
22251
|
-
// precisely or approximately and return the appropriate message:
|
|
22252
|
-
// - if precise, return the message that the answer came with
|
|
22253
|
-
// - if it needs to be simplified, etc., show that message
|
|
22254
|
-
let result = correctAnswers.map(answer => {
|
|
22255
|
-
// The coefficient is an attribute of the widget
|
|
22256
|
-
let localValue = currentValue;
|
|
22257
|
-
if (rubric.coefficient) {
|
|
22258
|
-
if (!localValue) {
|
|
22259
|
-
localValue = 1;
|
|
22260
|
-
} else if (localValue === "-") {
|
|
22261
|
-
localValue = -1;
|
|
22262
|
-
}
|
|
22263
|
-
}
|
|
22264
|
-
const validate = createValidator(answer);
|
|
22265
|
-
return validate(maybeParsePercentInput(localValue, normalizedAnswerExpected));
|
|
22266
|
-
}).find(match => match.correct || match.empty);
|
|
22267
|
-
if (!result) {
|
|
22268
|
-
// Otherwise, if the guess is not correct
|
|
22269
|
-
const otherAnswers = [].concat(
|
|
22270
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
22271
|
-
rubric.answers.filter(answer => answer.status === "ungraded"), rubric.answers.filter(answer => answer.status === "wrong"));
|
|
22180
|
+
const normalizedAnswerExpected = rubric.answers.filter(answer => answer.status === "correct").every(answer => Math.abs(answer.value) <= 1);
|
|
22272
22181
|
|
|
22273
|
-
|
|
22274
|
-
|
|
22275
|
-
|
|
22276
|
-
|
|
22277
|
-
|
|
22278
|
-
})
|
|
22279
|
-
|
|
22280
|
-
|
|
22281
|
-
empty: match ? match.status === "ungraded" : false,
|
|
22282
|
-
// @ts-expect-error - TS2339 - Property 'status' does not exist on type 'never'.
|
|
22283
|
-
correct: match ? match.status === "correct" : false,
|
|
22284
|
-
// @ts-expect-error - TS2339 - Property 'message' does not exist on type 'never'.
|
|
22285
|
-
message: match ? match.message : null,
|
|
22286
|
-
guess: currentValue
|
|
22287
|
-
};
|
|
22182
|
+
// The coefficient is an attribute of the widget
|
|
22183
|
+
let localValue = currentValue;
|
|
22184
|
+
if (rubric.coefficient) {
|
|
22185
|
+
if (!localValue) {
|
|
22186
|
+
localValue = 1;
|
|
22187
|
+
} else if (localValue === "-") {
|
|
22188
|
+
localValue = -1;
|
|
22189
|
+
}
|
|
22288
22190
|
}
|
|
22191
|
+
const matchedAnswer = rubric.answers.map(answer => {
|
|
22192
|
+
const validateFn = createValidator(answer);
|
|
22193
|
+
const score = validateFn(maybeParsePercentInput(localValue, normalizedAnswerExpected));
|
|
22194
|
+
return {
|
|
22195
|
+
...answer,
|
|
22196
|
+
score
|
|
22197
|
+
};
|
|
22198
|
+
}).find(answer => {
|
|
22199
|
+
// NOTE: "answer.score.correct" indicates a match via the validate function.
|
|
22200
|
+
// It does NOT indicate that the answer itself is correct.
|
|
22201
|
+
return answer.score.correct || answer.status === "correct" && answer.score.empty;
|
|
22202
|
+
});
|
|
22203
|
+
const result = matchedAnswer?.status === "correct" ? matchedAnswer.score : {
|
|
22204
|
+
empty: matchedAnswer?.status === "ungraded",
|
|
22205
|
+
correct: matchedAnswer?.status === "correct",
|
|
22206
|
+
message: matchedAnswer?.message ?? null,
|
|
22207
|
+
guess: localValue
|
|
22208
|
+
};
|
|
22289
22209
|
|
|
22290
22210
|
// TODO(eater): Seems silly to translate result to this
|
|
22291
22211
|
// invalid/points thing and immediately translate it
|
|
@@ -22378,10 +22298,6 @@ class NumericInput extends React__namespace.Component {
|
|
|
22378
22298
|
/* c8 ignore next */
|
|
22379
22299
|
return [[]];
|
|
22380
22300
|
};
|
|
22381
|
-
getGrammarTypeForPath = inputPath => {
|
|
22382
|
-
/* c8 ignore next */
|
|
22383
|
-
return "number";
|
|
22384
|
-
};
|
|
22385
22301
|
setInputValue = (path, newValue, cb) => {
|
|
22386
22302
|
/* c8 ignore next */
|
|
22387
22303
|
this.props.onChange({
|
|
@@ -22551,7 +22467,7 @@ var NumericInput$1 = {
|
|
|
22551
22467
|
* Several widgets don't have "right"/"wrong" validation logic,
|
|
22552
22468
|
* so this just says to move on past those widgets
|
|
22553
22469
|
*
|
|
22554
|
-
* TODO(LEMS-
|
|
22470
|
+
* TODO(LEMS-2543) widgets that use this probably shouldn't have any
|
|
22555
22471
|
* validation logic and the thing validating an exercise
|
|
22556
22472
|
* should just know to skip these
|
|
22557
22473
|
*/
|
|
@@ -24625,7 +24541,7 @@ class Passage extends React__namespace.Component {
|
|
|
24625
24541
|
const enabled = this.state.stylesAreApplied;
|
|
24626
24542
|
|
|
24627
24543
|
// Highlights are read-only in review mode.
|
|
24628
|
-
const editable = !this.props.
|
|
24544
|
+
const editable = !this.props.reviewMode;
|
|
24629
24545
|
return /*#__PURE__*/React__namespace.createElement(HighlightableContent, {
|
|
24630
24546
|
editable: editable,
|
|
24631
24547
|
enabled: enabled,
|
|
@@ -25263,13 +25179,13 @@ function getA11yText(letter, checked, correct, crossedOut, showCorrectness, stri
|
|
|
25263
25179
|
/**
|
|
25264
25180
|
* Renders a circular selection ring around the child.
|
|
25265
25181
|
*/
|
|
25266
|
-
const FocusRing = function (
|
|
25267
|
-
|
|
25268
|
-
visible,
|
|
25269
|
-
color,
|
|
25270
|
-
|
|
25271
|
-
|
|
25272
|
-
} =
|
|
25182
|
+
const FocusRing = function (_ref) {
|
|
25183
|
+
let {
|
|
25184
|
+
visible = true,
|
|
25185
|
+
color = kaGreen$1,
|
|
25186
|
+
multipleSelect = false,
|
|
25187
|
+
children
|
|
25188
|
+
} = _ref;
|
|
25273
25189
|
const borderColor = visible ? color : "transparent";
|
|
25274
25190
|
const borderRadius = multipleSelect ? 5 : "50%";
|
|
25275
25191
|
const style = {
|
|
@@ -25282,11 +25198,6 @@ const FocusRing = function (props) {
|
|
|
25282
25198
|
style: style
|
|
25283
25199
|
}, children);
|
|
25284
25200
|
};
|
|
25285
|
-
FocusRing.defaultProps = {
|
|
25286
|
-
visible: true,
|
|
25287
|
-
color: kaGreen$1,
|
|
25288
|
-
multipleSelect: false
|
|
25289
|
-
};
|
|
25290
25201
|
const styles$v = aphrodite.StyleSheet.create({
|
|
25291
25202
|
ring: {
|
|
25292
25203
|
margin: "auto",
|
|
@@ -25825,13 +25736,13 @@ var Choice$1 = /*#__PURE__*/React__namespace.forwardRef((props, ref) => /*#__PUR
|
|
|
25825
25736
|
forwardedRef: ref
|
|
25826
25737
|
})));
|
|
25827
25738
|
|
|
25828
|
-
const ChoiceNoneAbove = function (
|
|
25829
|
-
|
|
25830
|
-
showContent,
|
|
25739
|
+
const ChoiceNoneAbove = function (_ref) {
|
|
25740
|
+
let {
|
|
25831
25741
|
content,
|
|
25832
25742
|
forwardedRef,
|
|
25743
|
+
showContent = true,
|
|
25833
25744
|
...rest
|
|
25834
|
-
} =
|
|
25745
|
+
} = _ref;
|
|
25835
25746
|
const {
|
|
25836
25747
|
strings
|
|
25837
25748
|
} = usePerseusI18n();
|
|
@@ -25859,9 +25770,6 @@ const ChoiceNoneAbove = function (props) {
|
|
|
25859
25770
|
ref: forwardedRef
|
|
25860
25771
|
}));
|
|
25861
25772
|
};
|
|
25862
|
-
ChoiceNoneAbove.defaultProps = {
|
|
25863
|
-
showContent: true
|
|
25864
|
-
};
|
|
25865
25773
|
var ChoiceNoneAbove$1 = /*#__PURE__*/React__namespace.forwardRef((props, ref) => /*#__PURE__*/React__namespace.createElement(ChoiceNoneAbove, _extends({}, props, {
|
|
25866
25774
|
forwardedRef: ref
|
|
25867
25775
|
})));
|
|
@@ -25883,19 +25791,21 @@ function getInstructionsText(multipleSelect, countChoices, numCorrect, strings)
|
|
|
25883
25791
|
}
|
|
25884
25792
|
return strings.chooseOneAnswer;
|
|
25885
25793
|
}
|
|
25886
|
-
const BaseRadio = function (
|
|
25887
|
-
|
|
25794
|
+
const BaseRadio = function (_ref) {
|
|
25795
|
+
let {
|
|
25888
25796
|
apiOptions,
|
|
25889
25797
|
reviewModeRubric,
|
|
25798
|
+
reviewMode,
|
|
25890
25799
|
choices,
|
|
25891
|
-
editMode,
|
|
25892
|
-
multipleSelect,
|
|
25800
|
+
editMode = false,
|
|
25801
|
+
multipleSelect = false,
|
|
25893
25802
|
labelWrap,
|
|
25894
25803
|
countChoices,
|
|
25895
25804
|
numCorrect,
|
|
25896
25805
|
isLastUsedWidget,
|
|
25806
|
+
onChange,
|
|
25897
25807
|
registerFocusFunction
|
|
25898
|
-
} =
|
|
25808
|
+
} = _ref;
|
|
25899
25809
|
const {
|
|
25900
25810
|
strings
|
|
25901
25811
|
} = usePerseusI18n();
|
|
@@ -25952,12 +25862,6 @@ const BaseRadio = function (props) {
|
|
|
25952
25862
|
// contains a boolean value specifying the new checked and crossed-out
|
|
25953
25863
|
// value of this choice.
|
|
25954
25864
|
function updateChoice(choiceIndex, newValues) {
|
|
25955
|
-
const {
|
|
25956
|
-
multipleSelect,
|
|
25957
|
-
choices,
|
|
25958
|
-
onChange
|
|
25959
|
-
} = props;
|
|
25960
|
-
|
|
25961
25865
|
// Get the baseline `checked` values. If we're checking a new answer
|
|
25962
25866
|
// and multiple-select is not on, we should clear all choices to be
|
|
25963
25867
|
// unchecked. Otherwise, we should copy the old checked values.
|
|
@@ -25999,7 +25903,6 @@ const BaseRadio = function (props) {
|
|
|
25999
25903
|
});
|
|
26000
25904
|
|
|
26001
25905
|
// some commonly used shorthands
|
|
26002
|
-
const reviewMode = !!reviewModeRubric;
|
|
26003
25906
|
const isMobile = apiOptions.isMobile;
|
|
26004
25907
|
const firstChoiceHighlighted = choices[0].highlighted;
|
|
26005
25908
|
const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
|
|
@@ -26125,10 +26028,6 @@ const BaseRadio = function (props) {
|
|
|
26125
26028
|
className: aphrodite.css(styles$p.responsiveContainer)
|
|
26126
26029
|
}, fieldset);
|
|
26127
26030
|
};
|
|
26128
|
-
BaseRadio.defaultProps = {
|
|
26129
|
-
editMode: false,
|
|
26130
|
-
multipleSelect: false
|
|
26131
|
-
};
|
|
26132
26031
|
const styles$p = aphrodite.StyleSheet.create({
|
|
26133
26032
|
instructions: {
|
|
26134
26033
|
display: "block",
|
|
@@ -26227,7 +26126,7 @@ function radioValidator(userInput, rubric, strings) {
|
|
|
26227
26126
|
};
|
|
26228
26127
|
}
|
|
26229
26128
|
|
|
26230
|
-
// TODO: should numCorrect actually be on the rubric
|
|
26129
|
+
// TODO(LEMS-2541): should numCorrect actually be on the rubric
|
|
26231
26130
|
// instead of the userInput?
|
|
26232
26131
|
if (userInput.numCorrect && userInput.numCorrect > 1 && numSelected !== userInput.numCorrect) {
|
|
26233
26132
|
return {
|
|
@@ -26237,7 +26136,7 @@ function radioValidator(userInput, rubric, strings) {
|
|
|
26237
26136
|
// If NOTA and some other answer are checked, ...
|
|
26238
26137
|
}
|
|
26239
26138
|
|
|
26240
|
-
// TODO: should noneOfTheAboveSelected be replaced with a
|
|
26139
|
+
// TODO(LEMS-2541): should noneOfTheAboveSelected be replaced with a
|
|
26241
26140
|
// combination of choicesSelected and noneOfTheAboveIndex?
|
|
26242
26141
|
if (userInput.noneOfTheAboveSelected && numSelected > 1) {
|
|
26243
26142
|
return {
|
|
@@ -26247,7 +26146,7 @@ function radioValidator(userInput, rubric, strings) {
|
|
|
26247
26146
|
}
|
|
26248
26147
|
const correct = userInput.choicesSelected.every((selected, i) => {
|
|
26249
26148
|
let isCorrect;
|
|
26250
|
-
// TODO: should noneOfTheAboveIndex actually be on the rubric
|
|
26149
|
+
// TODO(LEMS-2541): should noneOfTheAboveIndex actually be on the rubric
|
|
26251
26150
|
// instead of the userInput?
|
|
26252
26151
|
if (userInput.noneOfTheAboveIndex === i) {
|
|
26253
26152
|
isCorrect = rubric.choices.every((choice, j) => {
|
|
@@ -26289,7 +26188,6 @@ class Radio$1 extends React__namespace.Component {
|
|
|
26289
26188
|
let noneOfTheAboveSelected = false;
|
|
26290
26189
|
const choiceStates = props.choiceStates;
|
|
26291
26190
|
const choicesSelected = choiceStates.map(() => false);
|
|
26292
|
-
const countChoices = props.countChoices;
|
|
26293
26191
|
const numCorrect = props.numCorrect;
|
|
26294
26192
|
for (let i = 0; i < choicesSelected.length; i++) {
|
|
26295
26193
|
const index = props.choices[i].originalIndex;
|
|
@@ -26303,7 +26201,6 @@ class Radio$1 extends React__namespace.Component {
|
|
|
26303
26201
|
}
|
|
26304
26202
|
}
|
|
26305
26203
|
return {
|
|
26306
|
-
countChoices,
|
|
26307
26204
|
choicesSelected,
|
|
26308
26205
|
numCorrect,
|
|
26309
26206
|
noneOfTheAboveIndex,
|
|
@@ -26319,7 +26216,6 @@ class Radio$1 extends React__namespace.Component {
|
|
|
26319
26216
|
let noneOfTheAboveIndex = null;
|
|
26320
26217
|
let noneOfTheAboveSelected = false;
|
|
26321
26218
|
const choicesSelected = [...values];
|
|
26322
|
-
const countChoices = props.countChoices;
|
|
26323
26219
|
const numCorrect = props.numCorrect;
|
|
26324
26220
|
const valuesLength = values.length;
|
|
26325
26221
|
for (let i = 0; i < valuesLength; i++) {
|
|
@@ -26337,7 +26233,6 @@ class Radio$1 extends React__namespace.Component {
|
|
|
26337
26233
|
choicesSelected,
|
|
26338
26234
|
noneOfTheAboveIndex,
|
|
26339
26235
|
noneOfTheAboveSelected,
|
|
26340
|
-
countChoices,
|
|
26341
26236
|
numCorrect
|
|
26342
26237
|
};
|
|
26343
26238
|
}
|
|
@@ -26600,7 +26495,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
26600
26495
|
highlighted,
|
|
26601
26496
|
previouslyAnswered
|
|
26602
26497
|
} = choiceStates[i];
|
|
26603
|
-
const reviewChoice = this.props.reviewModeRubric
|
|
26498
|
+
const reviewChoice = this.props.reviewModeRubric?.choices[i];
|
|
26604
26499
|
return {
|
|
26605
26500
|
content: this._renderRenderer(content),
|
|
26606
26501
|
checked: selected,
|
|
@@ -26635,6 +26530,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
26635
26530
|
choices: choicesProp,
|
|
26636
26531
|
onChange: this.updateChoices,
|
|
26637
26532
|
reviewModeRubric: this.props.reviewModeRubric,
|
|
26533
|
+
reviewMode: this.props.reviewMode,
|
|
26638
26534
|
deselectEnabled: this.props.deselectEnabled,
|
|
26639
26535
|
apiOptions: this.props.apiOptions,
|
|
26640
26536
|
isLastUsedWidget: this.props.isLastUsedWidget,
|
|
@@ -29393,7 +29289,7 @@ class Group extends React__namespace.Component {
|
|
|
29393
29289
|
ref: ref => this.rendererRef = ref,
|
|
29394
29290
|
apiOptions: apiOptions,
|
|
29395
29291
|
findExternalWidgets: this.props.findWidgets,
|
|
29396
|
-
reviewMode:
|
|
29292
|
+
reviewMode: this.props.reviewMode,
|
|
29397
29293
|
onInteractWithWidget: onInteractWithWidget,
|
|
29398
29294
|
linterContext: this.props.linterContext,
|
|
29399
29295
|
strings: this.context.strings
|
|
@@ -29420,23 +29316,23 @@ var Group$1 = {
|
|
|
29420
29316
|
isLintable: true
|
|
29421
29317
|
};
|
|
29422
29318
|
|
|
29423
|
-
function iframeValidator(
|
|
29319
|
+
function iframeValidator(userInput) {
|
|
29424
29320
|
// The iframe can tell us whether it's correct or incorrect,
|
|
29425
29321
|
// and pass an optional message
|
|
29426
|
-
if (
|
|
29322
|
+
if (userInput.status === "correct") {
|
|
29427
29323
|
return {
|
|
29428
29324
|
type: "points",
|
|
29429
29325
|
earned: 1,
|
|
29430
29326
|
total: 1,
|
|
29431
|
-
message:
|
|
29327
|
+
message: userInput.message || null
|
|
29432
29328
|
};
|
|
29433
29329
|
}
|
|
29434
|
-
if (
|
|
29330
|
+
if (userInput.status === "incorrect") {
|
|
29435
29331
|
return {
|
|
29436
29332
|
type: "points",
|
|
29437
29333
|
earned: 0,
|
|
29438
29334
|
total: 1,
|
|
29439
|
-
message:
|
|
29335
|
+
message: userInput.message || null
|
|
29440
29336
|
};
|
|
29441
29337
|
}
|
|
29442
29338
|
return {
|
|
@@ -39327,8 +39223,6 @@ const styles$b = aphrodite.StyleSheet.create({
|
|
|
39327
39223
|
* No diagonals allowed.
|
|
39328
39224
|
*/
|
|
39329
39225
|
|
|
39330
|
-
// TODO: should this be using WidgetProps / PerseusLabelImageWidgetOptions?
|
|
39331
|
-
|
|
39332
39226
|
class LabelImage extends React__namespace.Component {
|
|
39333
39227
|
static contextType = PerseusI18nContext;
|
|
39334
39228
|
// The rendered markers on the question image for labeling.
|
|
@@ -40822,9 +40716,9 @@ var Matcher$1 = {
|
|
|
40822
40716
|
validator: matcherValidator
|
|
40823
40717
|
};
|
|
40824
40718
|
|
|
40825
|
-
function matrixValidator(
|
|
40719
|
+
function matrixValidator(userInput, rubric, strings) {
|
|
40826
40720
|
const solution = rubric.answers;
|
|
40827
|
-
const supplied =
|
|
40721
|
+
const supplied = userInput.answers;
|
|
40828
40722
|
const solutionSize = getMatrixSize(solution);
|
|
40829
40723
|
const suppliedSize = getMatrixSize(supplied);
|
|
40830
40724
|
const incorrectSize = solutionSize[0] !== suppliedSize[0] || solutionSize[1] !== suppliedSize[1];
|
|
@@ -40979,9 +40873,6 @@ class Matrix extends React__namespace.Component {
|
|
|
40979
40873
|
});
|
|
40980
40874
|
return inputPaths;
|
|
40981
40875
|
};
|
|
40982
|
-
getGrammarTypeForPath = inputPath => {
|
|
40983
|
-
return "number";
|
|
40984
|
-
};
|
|
40985
40876
|
_handleFocus = (row, col) => {
|
|
40986
40877
|
this.props.onFocus(getInputPath$1(row, col));
|
|
40987
40878
|
};
|
|
@@ -41298,7 +41189,7 @@ const defaultImage = {
|
|
|
41298
41189
|
class Measurer extends React__namespace.Component {
|
|
41299
41190
|
static defaultProps = {
|
|
41300
41191
|
box: [480, 480],
|
|
41301
|
-
image:
|
|
41192
|
+
image: defaultImage,
|
|
41302
41193
|
showProtractor: true,
|
|
41303
41194
|
protractorX: 7.5,
|
|
41304
41195
|
protractorY: 0.5,
|
|
@@ -42596,11 +42487,6 @@ class NumberLine extends React__namespace.Component {
|
|
|
42596
42487
|
}
|
|
42597
42488
|
return null;
|
|
42598
42489
|
}
|
|
42599
|
-
getGrammarTypeForPath(inputPath) {
|
|
42600
|
-
if (inputPath?.length === 1 && inputPath[0] === "tick-ctrl") {
|
|
42601
|
-
return "number";
|
|
42602
|
-
}
|
|
42603
|
-
}
|
|
42604
42490
|
setInputValue = (inputPath, value, callback) => {
|
|
42605
42491
|
if (inputPath.length === 1 && inputPath[0] === "tick-ctrl") {
|
|
42606
42492
|
this.onNumDivisionsChange(value, callback);
|
|
@@ -44889,9 +44775,6 @@ class Table extends React__namespace.Component {
|
|
|
44889
44775
|
});
|
|
44890
44776
|
return inputPaths;
|
|
44891
44777
|
};
|
|
44892
|
-
getGrammarTypeForPath = inputPath => {
|
|
44893
|
-
return "number";
|
|
44894
|
-
};
|
|
44895
44778
|
setInputValue = (path, newValue, cb) => {
|
|
44896
44779
|
// Extract row, column information
|
|
44897
44780
|
const row = getRowFromPath(path);
|
|
@@ -45185,7 +45068,7 @@ const init = function (options) {
|
|
|
45185
45068
|
|
|
45186
45069
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45187
45070
|
const libName = "@khanacademy/perseus";
|
|
45188
|
-
const libVersion = "
|
|
45071
|
+
const libVersion = "39.0.1";
|
|
45189
45072
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45190
45073
|
|
|
45191
45074
|
const apiVersion = {
|
|
@@ -45896,9 +45779,6 @@ class ServerItemRenderer extends React__namespace.Component {
|
|
|
45896
45779
|
getDOMNodeForPath(path) {
|
|
45897
45780
|
return this.questionRenderer.getDOMNodeForPath(path);
|
|
45898
45781
|
}
|
|
45899
|
-
getGrammarTypeForPath(path) {
|
|
45900
|
-
return this.questionRenderer.getGrammarTypeForPath(path);
|
|
45901
|
-
}
|
|
45902
45782
|
getInputPaths() {
|
|
45903
45783
|
const questionAreaInputPaths = this.questionRenderer.getInputPaths();
|
|
45904
45784
|
return questionAreaInputPaths;
|
|
@@ -47199,7 +47079,6 @@ const styles = aphrodite.StyleSheet.create({
|
|
|
47199
47079
|
* If you're writing new components, though, consider using the Item and Shape
|
|
47200
47080
|
* types instead.
|
|
47201
47081
|
*/
|
|
47202
|
-
|
|
47203
47082
|
/**
|
|
47204
47083
|
* Return a PropType that accepts Items of the given shape, and rejects other
|
|
47205
47084
|
* objects.
|
|
@@ -47431,6 +47310,21 @@ function violatingWidgets(itemData) {
|
|
|
47431
47310
|
}
|
|
47432
47311
|
|
|
47433
47312
|
/* eslint-disable eqeqeq, @typescript-eslint/no-unused-vars */
|
|
47313
|
+
/*
|
|
47314
|
+
* A class for formatting number to significant digits.
|
|
47315
|
+
* Copyright (C) 2001 Stephen Ostermiller
|
|
47316
|
+
* http://ostermiller.org/contact.pl?regarding?JavaScript+Significant+Figures
|
|
47317
|
+
*
|
|
47318
|
+
* This program is free software; you can redistribute it and/or modify
|
|
47319
|
+
* it under the terms of the GNU General Public License as published by
|
|
47320
|
+
* the Free Software Foundation; either version 2 of the License, or
|
|
47321
|
+
* (at your option) any later version.
|
|
47322
|
+
*
|
|
47323
|
+
* This program is distributed in the hope that it will be useful,
|
|
47324
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
47325
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
47326
|
+
* GNU General Public License for more details.
|
|
47327
|
+
*/
|
|
47434
47328
|
|
|
47435
47329
|
/**
|
|
47436
47330
|
* Format a floating point for display using the specified
|