@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/es/index.js
CHANGED
|
@@ -2402,11 +2402,6 @@ class Expression extends React.Component {
|
|
|
2402
2402
|
// @ts-expect-error - TS2339 - Property 'insert' does not exist on type 'ReactInstance'.
|
|
2403
2403
|
this.refs.input.insert(keyPressed);
|
|
2404
2404
|
}
|
|
2405
|
-
// TODO(Nicole): I believe this is going away and won't be needed anymore
|
|
2406
|
-
getGrammarTypeForPath(inputPath) {
|
|
2407
|
-
/* c8 ignore next */
|
|
2408
|
-
return "expression";
|
|
2409
|
-
}
|
|
2410
2405
|
setInputValue(path, newValue, cb) {
|
|
2411
2406
|
this.props.onChange({
|
|
2412
2407
|
value: newValue
|
|
@@ -2878,7 +2873,9 @@ function flattenScores(widgetScoreMap) {
|
|
|
2878
2873
|
function isCorrect(score) {
|
|
2879
2874
|
return score.type === "points" && score.earned >= score.total;
|
|
2880
2875
|
}
|
|
2881
|
-
function keScoreFromPerseusScore(score,
|
|
2876
|
+
function keScoreFromPerseusScore(score,
|
|
2877
|
+
// It's weird, but this is what we're passing it
|
|
2878
|
+
guess, state) {
|
|
2882
2879
|
if (score.type === "points") {
|
|
2883
2880
|
return {
|
|
2884
2881
|
empty: false,
|
|
@@ -3892,36 +3889,14 @@ const ZoomService = new ZoomServiceClass();
|
|
|
3892
3889
|
const baseFontFamily$1 = "'Lato', sans-serif";
|
|
3893
3890
|
// @boldFontFamily: "Lato-Bold", "Lato", sans-serif;
|
|
3894
3891
|
const boldFontFamily = "'Lato-Bold', 'Lato', sans-serif";
|
|
3895
|
-
// @green: #76a005;
|
|
3896
|
-
const green$1 = "#76A005";
|
|
3897
3892
|
// @kaGreen: #71b307;
|
|
3898
3893
|
const kaGreen$1 = "#71B307";
|
|
3899
|
-
// @blue: #1c758a;
|
|
3900
|
-
const blue$1 = "#1C758A";
|
|
3901
|
-
// @gray: #aaa;
|
|
3902
|
-
const gray$1 = "#AAAAAA";
|
|
3903
|
-
// @red: #ffbaba;
|
|
3904
|
-
const red$1 = "#FFBABA";
|
|
3905
|
-
// @grayLight: #aaa;
|
|
3906
|
-
const grayLight$1 = "#AAAAAA";
|
|
3907
|
-
// @grayLighter: #ddd;
|
|
3908
|
-
const grayLighter$1 = "#DDDDDD";
|
|
3909
|
-
// @learnstormBlue: #4898fc;
|
|
3910
|
-
const learnstormBlue$1 = "#4898FC";
|
|
3911
3894
|
const white$1 = "#FFFFFF";
|
|
3912
|
-
const gray98 = "#FAFAFA";
|
|
3913
3895
|
const gray97 = "#F6F7F7";
|
|
3914
|
-
const gray95 = "#F0F1F2";
|
|
3915
|
-
const gray90 = "#E3E5E6";
|
|
3916
3896
|
const gray85 = "#D6D8DA";
|
|
3917
3897
|
const gray76 = "#BABEC2";
|
|
3918
3898
|
const gray68 = "#888D93";
|
|
3919
|
-
const gray41 = "#626569";
|
|
3920
|
-
const gray25 = "#3B3e40";
|
|
3921
3899
|
const gray17 = "#21242c";
|
|
3922
|
-
const black$1 = "#000000";
|
|
3923
|
-
const warning1 = "#F86700";
|
|
3924
|
-
const warning3 = "#C75300";
|
|
3925
3900
|
|
|
3926
3901
|
// @pure-sm-min: 568px;
|
|
3927
3902
|
const pureSmMin$2 = "568px";
|
|
@@ -3941,16 +3916,10 @@ const pureMdMax$2 = "1023px";
|
|
|
3941
3916
|
const pureLgMax$2 = "1279px";
|
|
3942
3917
|
// @tableBackgroundAccent: #f9f9f9; // for striping
|
|
3943
3918
|
const tableBackgroundAccent$1 = "#F9F9F9";
|
|
3944
|
-
// @zIndexScratchPad: 1;
|
|
3945
|
-
const zIndexScratchPad = 1;
|
|
3946
3919
|
// @zIndexAboveScratchpad: @zIndexScratchPad + 1;
|
|
3947
3920
|
const zIndexAboveScratchpad$1 = 2;
|
|
3948
3921
|
// @zIndexInteractiveComponent: @zIndexAboveScratchpad + 1;
|
|
3949
3922
|
const zIndexInteractiveComponent$1 = 3;
|
|
3950
|
-
// @zIndexCurrentlyDragging: @zIndexInteractiveComponent + 1;
|
|
3951
|
-
const zIndexCurrentlyDragging = 4;
|
|
3952
|
-
// @zIndexCalculator: @zIndexCurrentlyDragging + 1;
|
|
3953
|
-
const zIndexCalculator = 5;
|
|
3954
3923
|
// @phoneMargin: 16px;
|
|
3955
3924
|
const phoneMargin = 16;
|
|
3956
3925
|
const negativePhoneMargin = -16;
|
|
@@ -3978,28 +3947,13 @@ var constants$1 = /*#__PURE__*/Object.freeze({
|
|
|
3978
3947
|
__proto__: null,
|
|
3979
3948
|
baseFontFamily: baseFontFamily$1,
|
|
3980
3949
|
boldFontFamily: boldFontFamily,
|
|
3981
|
-
green: green$1,
|
|
3982
3950
|
kaGreen: kaGreen$1,
|
|
3983
|
-
blue: blue$1,
|
|
3984
|
-
gray: gray$1,
|
|
3985
|
-
red: red$1,
|
|
3986
|
-
grayLight: grayLight$1,
|
|
3987
|
-
grayLighter: grayLighter$1,
|
|
3988
|
-
learnstormBlue: learnstormBlue$1,
|
|
3989
3951
|
white: white$1,
|
|
3990
|
-
gray98: gray98,
|
|
3991
3952
|
gray97: gray97,
|
|
3992
|
-
gray95: gray95,
|
|
3993
|
-
gray90: gray90,
|
|
3994
3953
|
gray85: gray85,
|
|
3995
3954
|
gray76: gray76,
|
|
3996
3955
|
gray68: gray68,
|
|
3997
|
-
gray41: gray41,
|
|
3998
|
-
gray25: gray25,
|
|
3999
3956
|
gray17: gray17,
|
|
4000
|
-
black: black$1,
|
|
4001
|
-
warning1: warning1,
|
|
4002
|
-
warning3: warning3,
|
|
4003
3957
|
pureSmMin: pureSmMin$2,
|
|
4004
3958
|
pureMdMin: pureMdMin$2,
|
|
4005
3959
|
pureLgMin: pureLgMin$2,
|
|
@@ -4009,11 +3963,8 @@ var constants$1 = /*#__PURE__*/Object.freeze({
|
|
|
4009
3963
|
pureMdMax: pureMdMax$2,
|
|
4010
3964
|
pureLgMax: pureLgMax$2,
|
|
4011
3965
|
tableBackgroundAccent: tableBackgroundAccent$1,
|
|
4012
|
-
zIndexScratchPad: zIndexScratchPad,
|
|
4013
3966
|
zIndexAboveScratchpad: zIndexAboveScratchpad$1,
|
|
4014
3967
|
zIndexInteractiveComponent: zIndexInteractiveComponent$1,
|
|
4015
|
-
zIndexCurrentlyDragging: zIndexCurrentlyDragging,
|
|
4016
|
-
zIndexCalculator: zIndexCalculator,
|
|
4017
3968
|
phoneMargin: phoneMargin,
|
|
4018
3969
|
negativePhoneMargin: negativePhoneMargin,
|
|
4019
3970
|
hintBorderWidth: hintBorderWidth,
|
|
@@ -19756,6 +19707,7 @@ class Renderer extends React.Component {
|
|
|
19756
19707
|
onBlur: _.partial(this._onWidgetBlur, id),
|
|
19757
19708
|
findWidgets: this.findWidgets,
|
|
19758
19709
|
reviewModeRubric: reviewModeRubric,
|
|
19710
|
+
reviewMode: this.props.reviewMode,
|
|
19759
19711
|
onChange: (newProps, cb, silent = false) => {
|
|
19760
19712
|
this._setWidgetProps(id, newProps, cb, silent);
|
|
19761
19713
|
},
|
|
@@ -20435,14 +20387,6 @@ class Renderer extends React.Component {
|
|
|
20435
20387
|
return ReactDOM__default.findDOMNode(widget);
|
|
20436
20388
|
}
|
|
20437
20389
|
};
|
|
20438
|
-
this.getGrammarTypeForPath = path => {
|
|
20439
|
-
// @ts-expect-error - TS2345 - Argument of type 'FocusPath' is not assignable to parameter of type 'List<any>'.
|
|
20440
|
-
const widgetId = _.first(path);
|
|
20441
|
-
// @ts-expect-error - TS2345 - Argument of type 'FocusPath' is not assignable to parameter of type 'List<any>'.
|
|
20442
|
-
const interWidgetPath = _.rest(path);
|
|
20443
|
-
const widget = this.getWidgetInstance(widgetId);
|
|
20444
|
-
return widget == null || widget.getGrammarTypeForPath == null ? void 0 : widget.getGrammarTypeForPath(interWidgetPath);
|
|
20445
|
-
};
|
|
20446
20390
|
this.getInputPaths = () => {
|
|
20447
20391
|
const inputPaths = [];
|
|
20448
20392
|
_.each(this.widgetIds, widgetId => {
|
|
@@ -20582,11 +20526,6 @@ class Renderer extends React.Component {
|
|
|
20582
20526
|
this.getWidgetIds = () => {
|
|
20583
20527
|
return this.widgetIds;
|
|
20584
20528
|
};
|
|
20585
|
-
this.guessAndScore = () => {
|
|
20586
|
-
const totalGuess = this.getUserInput();
|
|
20587
|
-
const totalScore = this.score();
|
|
20588
|
-
return [totalGuess, totalScore];
|
|
20589
|
-
};
|
|
20590
20529
|
this.examples = () => {
|
|
20591
20530
|
const widgetIds = this.widgetIds;
|
|
20592
20531
|
const examples = _.compact(_.map(widgetIds, widgetId => {
|
|
@@ -20808,6 +20747,11 @@ class Renderer extends React.Component {
|
|
|
20808
20747
|
const combinedScore = Util.flattenScores(scores);
|
|
20809
20748
|
return combinedScore;
|
|
20810
20749
|
}
|
|
20750
|
+
guessAndScore() {
|
|
20751
|
+
const totalGuess = this.getUserInput();
|
|
20752
|
+
const totalScore = this.score();
|
|
20753
|
+
return [totalGuess, totalScore];
|
|
20754
|
+
}
|
|
20811
20755
|
render() {
|
|
20812
20756
|
const apiOptions = this.getApiOptions();
|
|
20813
20757
|
if (this.reuseMarkdown) {
|
|
@@ -21024,7 +20968,17 @@ TextInput.defaultProps = {
|
|
|
21024
20968
|
disabled: false
|
|
21025
20969
|
};
|
|
21026
20970
|
|
|
21027
|
-
|
|
20971
|
+
function _objectWithoutPropertiesLoose(r, e) {
|
|
20972
|
+
if (null == r) return {};
|
|
20973
|
+
var t = {};
|
|
20974
|
+
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
20975
|
+
if (e.includes(n)) continue;
|
|
20976
|
+
t[n] = r[n];
|
|
20977
|
+
}
|
|
20978
|
+
return t;
|
|
20979
|
+
}
|
|
20980
|
+
|
|
20981
|
+
const _excluded$5 = ["position", "visibility", "left", "top"];
|
|
21028
20982
|
const zIndex = 10;
|
|
21029
20983
|
let HorizontalDirection = /*#__PURE__*/function (HorizontalDirection) {
|
|
21030
20984
|
HorizontalDirection["Left"] = "left";
|
|
@@ -21068,7 +21022,14 @@ const Triangle = props => {
|
|
|
21068
21022
|
}
|
|
21069
21023
|
});
|
|
21070
21024
|
};
|
|
21071
|
-
const TooltipArrow =
|
|
21025
|
+
const TooltipArrow = _ref => {
|
|
21026
|
+
let {
|
|
21027
|
+
position = "relative",
|
|
21028
|
+
visibility = "visible",
|
|
21029
|
+
left = 100,
|
|
21030
|
+
top = 0
|
|
21031
|
+
} = _ref,
|
|
21032
|
+
props = _objectWithoutPropertiesLoose(_ref, _excluded$5);
|
|
21072
21033
|
// TODO(aria): Think about adding a box-shadow to the triangle here
|
|
21073
21034
|
// See http://css-tricks.com/triangle-with-shadow/
|
|
21074
21035
|
|
|
@@ -21079,10 +21040,10 @@ const TooltipArrow = props => {
|
|
|
21079
21040
|
return /*#__PURE__*/React.createElement("div", {
|
|
21080
21041
|
style: {
|
|
21081
21042
|
display: "block",
|
|
21082
|
-
position:
|
|
21083
|
-
visibility:
|
|
21084
|
-
left:
|
|
21085
|
-
top:
|
|
21043
|
+
position: position,
|
|
21044
|
+
visibility: visibility,
|
|
21045
|
+
left: left,
|
|
21046
|
+
top: top,
|
|
21086
21047
|
width: props.width + 2,
|
|
21087
21048
|
height: props.height + 1,
|
|
21088
21049
|
marginTop: -1,
|
|
@@ -21108,12 +21069,6 @@ const TooltipArrow = props => {
|
|
|
21108
21069
|
height: props.height
|
|
21109
21070
|
}));
|
|
21110
21071
|
};
|
|
21111
|
-
TooltipArrow.defaultProps = {
|
|
21112
|
-
position: "relative",
|
|
21113
|
-
visibility: "visible",
|
|
21114
|
-
left: 0,
|
|
21115
|
-
top: 0
|
|
21116
|
-
};
|
|
21117
21072
|
const VERTICAL_CORNERS = {
|
|
21118
21073
|
top: {
|
|
21119
21074
|
top: "-100%"
|
|
@@ -21396,16 +21351,6 @@ InputWithExamples.defaultProps = {
|
|
|
21396
21351
|
className: ""
|
|
21397
21352
|
};
|
|
21398
21353
|
|
|
21399
|
-
function _objectWithoutPropertiesLoose(r, e) {
|
|
21400
|
-
if (null == r) return {};
|
|
21401
|
-
var t = {};
|
|
21402
|
-
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
21403
|
-
if (e.includes(n)) continue;
|
|
21404
|
-
t[n] = r[n];
|
|
21405
|
-
}
|
|
21406
|
-
return t;
|
|
21407
|
-
}
|
|
21408
|
-
|
|
21409
21354
|
const _excluded$4 = ["keypadElement", "onFocus", "value"];
|
|
21410
21355
|
class SimpleKeypadInput extends React.Component {
|
|
21411
21356
|
constructor(...args) {
|
|
@@ -21787,12 +21732,6 @@ class InputNumber extends React.Component {
|
|
|
21787
21732
|
/* c8 ignore next */
|
|
21788
21733
|
return [[]];
|
|
21789
21734
|
};
|
|
21790
|
-
// Note: We believe that this isn't used anywhere but are leaving it during
|
|
21791
|
-
// the initial refactor
|
|
21792
|
-
this.getGrammarTypeForPath = path => {
|
|
21793
|
-
/* c8 ignore next */
|
|
21794
|
-
return "number";
|
|
21795
|
-
};
|
|
21796
21735
|
this.setInputValue = (path, newValue, cb) => {
|
|
21797
21736
|
this.props.onChange({
|
|
21798
21737
|
currentValue: newValue
|
|
@@ -21836,17 +21775,13 @@ class InputNumber extends React.Component {
|
|
|
21836
21775
|
}
|
|
21837
21776
|
return input;
|
|
21838
21777
|
}
|
|
21839
|
-
// HACK(johnsullivan): Create a function with shared logic between
|
|
21840
|
-
// this and NumericInput.
|
|
21841
|
-
// TODO(jeremy): Deprecate this widget and prefer numeric-input.
|
|
21842
|
-
const rubric = this.props.reviewModeRubric;
|
|
21843
21778
|
|
|
21844
21779
|
// Note: This is _very_ similar to what `numeric-input.jsx` does. If
|
|
21845
21780
|
// you modify this, double-check if you also need to modify that
|
|
21846
21781
|
// component.
|
|
21847
21782
|
const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
|
|
21848
21783
|
// Unanswered
|
|
21849
|
-
if (
|
|
21784
|
+
if (this.props.reviewMode && !this.props.currentValue) {
|
|
21850
21785
|
inputStyles.push(styles$A.answerStateUnanswered);
|
|
21851
21786
|
}
|
|
21852
21787
|
return /*#__PURE__*/React.createElement(InputWithExamples
|
|
@@ -21993,6 +21928,7 @@ function maybeParsePercentInput(inputValue, normalizedAnswerExpected) {
|
|
|
21993
21928
|
return value;
|
|
21994
21929
|
}
|
|
21995
21930
|
function numericInputValidator(userInput, rubric, strings) {
|
|
21931
|
+
var _matchedAnswer$messag;
|
|
21996
21932
|
const defaultAnswerForms = answerFormButtons.map(e => e["value"])
|
|
21997
21933
|
// Don't default to validating the answer as a pi answer
|
|
21998
21934
|
// if answerForm isn't set on the answer
|
|
@@ -22025,48 +21961,34 @@ function numericInputValidator(userInput, rubric, strings) {
|
|
|
22025
21961
|
// We may have received TeX; try to parse it before grading.
|
|
22026
21962
|
// If `currentValue` is not TeX, this should be a no-op.
|
|
22027
21963
|
const currentValue = ParseTex(userInput.currentValue);
|
|
22028
|
-
const
|
|
22029
|
-
|
|
22030
|
-
|
|
22031
|
-
|
|
22032
|
-
|
|
22033
|
-
|
|
22034
|
-
|
|
22035
|
-
|
|
22036
|
-
|
|
22037
|
-
|
|
22038
|
-
|
|
22039
|
-
|
|
22040
|
-
|
|
22041
|
-
|
|
22042
|
-
|
|
22043
|
-
|
|
22044
|
-
}
|
|
22045
|
-
const validate = createValidator(answer);
|
|
22046
|
-
return validate(maybeParsePercentInput(localValue, normalizedAnswerExpected));
|
|
22047
|
-
}).find(match => match.correct || match.empty);
|
|
22048
|
-
if (!result) {
|
|
22049
|
-
// Otherwise, if the guess is not correct
|
|
22050
|
-
const otherAnswers = [].concat(
|
|
22051
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
22052
|
-
rubric.answers.filter(answer => answer.status === "ungraded"), rubric.answers.filter(answer => answer.status === "wrong"));
|
|
22053
|
-
|
|
22054
|
-
// Look through all other answers and if one matches either
|
|
22055
|
-
// precisely or approximately return the answer's message
|
|
22056
|
-
const match = otherAnswers.find(answer => {
|
|
22057
|
-
const validate = createValidator(answer);
|
|
22058
|
-
return validate(maybeParsePercentInput(currentValue, normalizedAnswerExpected)).correct;
|
|
21964
|
+
const normalizedAnswerExpected = rubric.answers.filter(answer => answer.status === "correct").every(answer => Math.abs(answer.value) <= 1);
|
|
21965
|
+
|
|
21966
|
+
// The coefficient is an attribute of the widget
|
|
21967
|
+
let localValue = currentValue;
|
|
21968
|
+
if (rubric.coefficient) {
|
|
21969
|
+
if (!localValue) {
|
|
21970
|
+
localValue = 1;
|
|
21971
|
+
} else if (localValue === "-") {
|
|
21972
|
+
localValue = -1;
|
|
21973
|
+
}
|
|
21974
|
+
}
|
|
21975
|
+
const matchedAnswer = rubric.answers.map(answer => {
|
|
21976
|
+
const validateFn = createValidator(answer);
|
|
21977
|
+
const score = validateFn(maybeParsePercentInput(localValue, normalizedAnswerExpected));
|
|
21978
|
+
return _extends({}, answer, {
|
|
21979
|
+
score
|
|
22059
21980
|
});
|
|
22060
|
-
|
|
22061
|
-
|
|
22062
|
-
|
|
22063
|
-
|
|
22064
|
-
|
|
22065
|
-
|
|
22066
|
-
|
|
22067
|
-
|
|
22068
|
-
|
|
22069
|
-
|
|
21981
|
+
}).find(answer => {
|
|
21982
|
+
// NOTE: "answer.score.correct" indicates a match via the validate function.
|
|
21983
|
+
// It does NOT indicate that the answer itself is correct.
|
|
21984
|
+
return answer.score.correct || answer.status === "correct" && answer.score.empty;
|
|
21985
|
+
});
|
|
21986
|
+
const result = (matchedAnswer == null ? void 0 : matchedAnswer.status) === "correct" ? matchedAnswer.score : {
|
|
21987
|
+
empty: (matchedAnswer == null ? void 0 : matchedAnswer.status) === "ungraded",
|
|
21988
|
+
correct: (matchedAnswer == null ? void 0 : matchedAnswer.status) === "correct",
|
|
21989
|
+
message: (_matchedAnswer$messag = matchedAnswer == null ? void 0 : matchedAnswer.message) != null ? _matchedAnswer$messag : null,
|
|
21990
|
+
guess: localValue
|
|
21991
|
+
};
|
|
22070
21992
|
|
|
22071
21993
|
// TODO(eater): Seems silly to translate result to this
|
|
22072
21994
|
// invalid/points thing and immediately translate it
|
|
@@ -22149,10 +22071,6 @@ class NumericInput extends React.Component {
|
|
|
22149
22071
|
/* c8 ignore next */
|
|
22150
22072
|
return [[]];
|
|
22151
22073
|
};
|
|
22152
|
-
this.getGrammarTypeForPath = inputPath => {
|
|
22153
|
-
/* c8 ignore next */
|
|
22154
|
-
return "number";
|
|
22155
|
-
};
|
|
22156
22074
|
this.setInputValue = (path, newValue, cb) => {
|
|
22157
22075
|
/* c8 ignore next */
|
|
22158
22076
|
this.props.onChange({
|
|
@@ -22339,7 +22257,7 @@ var NumericInput$1 = {
|
|
|
22339
22257
|
* Several widgets don't have "right"/"wrong" validation logic,
|
|
22340
22258
|
* so this just says to move on past those widgets
|
|
22341
22259
|
*
|
|
22342
|
-
* TODO(LEMS-
|
|
22260
|
+
* TODO(LEMS-2543) widgets that use this probably shouldn't have any
|
|
22343
22261
|
* validation logic and the thing validating an exercise
|
|
22344
22262
|
* should just know to skip these
|
|
22345
22263
|
*/
|
|
@@ -24401,7 +24319,7 @@ class Passage extends React.Component {
|
|
|
24401
24319
|
const enabled = this.state.stylesAreApplied;
|
|
24402
24320
|
|
|
24403
24321
|
// Highlights are read-only in review mode.
|
|
24404
|
-
const editable = !this.props.
|
|
24322
|
+
const editable = !this.props.reviewMode;
|
|
24405
24323
|
return /*#__PURE__*/React.createElement(HighlightableContent, {
|
|
24406
24324
|
editable: editable,
|
|
24407
24325
|
enabled: enabled,
|
|
@@ -25042,13 +24960,12 @@ function getA11yText(letter, checked, correct, crossedOut, showCorrectness, stri
|
|
|
25042
24960
|
/**
|
|
25043
24961
|
* Renders a circular selection ring around the child.
|
|
25044
24962
|
*/
|
|
25045
|
-
const FocusRing = function FocusRing(
|
|
25046
|
-
|
|
25047
|
-
|
|
25048
|
-
|
|
25049
|
-
|
|
25050
|
-
|
|
25051
|
-
} = props;
|
|
24963
|
+
const FocusRing = function FocusRing({
|
|
24964
|
+
visible = true,
|
|
24965
|
+
color = kaGreen$1,
|
|
24966
|
+
multipleSelect = false,
|
|
24967
|
+
children
|
|
24968
|
+
}) {
|
|
25052
24969
|
const borderColor = visible ? color : "transparent";
|
|
25053
24970
|
const borderRadius = multipleSelect ? 5 : "50%";
|
|
25054
24971
|
const style = {
|
|
@@ -25061,11 +24978,6 @@ const FocusRing = function FocusRing(props) {
|
|
|
25061
24978
|
style: style
|
|
25062
24979
|
}, children);
|
|
25063
24980
|
};
|
|
25064
|
-
FocusRing.defaultProps = {
|
|
25065
|
-
visible: true,
|
|
25066
|
-
color: kaGreen$1,
|
|
25067
|
-
multipleSelect: false
|
|
25068
|
-
};
|
|
25069
24981
|
const styles$v = StyleSheet.create({
|
|
25070
24982
|
ring: {
|
|
25071
24983
|
margin: "auto",
|
|
@@ -25598,14 +25510,14 @@ var Choice$1 = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React.
|
|
|
25598
25510
|
forwardedRef: ref
|
|
25599
25511
|
})));
|
|
25600
25512
|
|
|
25601
|
-
const _excluded$3 = ["
|
|
25602
|
-
const ChoiceNoneAbove = function ChoiceNoneAbove(
|
|
25603
|
-
|
|
25604
|
-
showContent,
|
|
25513
|
+
const _excluded$3 = ["content", "forwardedRef", "showContent"];
|
|
25514
|
+
const ChoiceNoneAbove = function ChoiceNoneAbove(_ref) {
|
|
25515
|
+
let {
|
|
25605
25516
|
content,
|
|
25606
|
-
forwardedRef
|
|
25607
|
-
|
|
25608
|
-
|
|
25517
|
+
forwardedRef,
|
|
25518
|
+
showContent = true
|
|
25519
|
+
} = _ref,
|
|
25520
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded$3);
|
|
25609
25521
|
const {
|
|
25610
25522
|
strings
|
|
25611
25523
|
} = usePerseusI18n();
|
|
@@ -25632,9 +25544,6 @@ const ChoiceNoneAbove = function ChoiceNoneAbove(props) {
|
|
|
25632
25544
|
ref: forwardedRef
|
|
25633
25545
|
}));
|
|
25634
25546
|
};
|
|
25635
|
-
ChoiceNoneAbove.defaultProps = {
|
|
25636
|
-
showContent: true
|
|
25637
|
-
};
|
|
25638
25547
|
var ChoiceNoneAbove$1 = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React.createElement(ChoiceNoneAbove, _extends({}, props, {
|
|
25639
25548
|
forwardedRef: ref
|
|
25640
25549
|
})));
|
|
@@ -25656,19 +25565,20 @@ function getInstructionsText(multipleSelect, countChoices, numCorrect, strings)
|
|
|
25656
25565
|
}
|
|
25657
25566
|
return strings.chooseOneAnswer;
|
|
25658
25567
|
}
|
|
25659
|
-
const BaseRadio = function BaseRadio(
|
|
25660
|
-
|
|
25661
|
-
|
|
25662
|
-
|
|
25663
|
-
|
|
25664
|
-
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25668
|
-
|
|
25669
|
-
|
|
25670
|
-
|
|
25671
|
-
|
|
25568
|
+
const BaseRadio = function BaseRadio({
|
|
25569
|
+
apiOptions,
|
|
25570
|
+
reviewModeRubric,
|
|
25571
|
+
reviewMode,
|
|
25572
|
+
choices,
|
|
25573
|
+
editMode = false,
|
|
25574
|
+
multipleSelect = false,
|
|
25575
|
+
labelWrap,
|
|
25576
|
+
countChoices,
|
|
25577
|
+
numCorrect,
|
|
25578
|
+
isLastUsedWidget,
|
|
25579
|
+
onChange,
|
|
25580
|
+
registerFocusFunction
|
|
25581
|
+
}) {
|
|
25672
25582
|
const {
|
|
25673
25583
|
strings
|
|
25674
25584
|
} = usePerseusI18n();
|
|
@@ -25725,12 +25635,6 @@ const BaseRadio = function BaseRadio(props) {
|
|
|
25725
25635
|
// contains a boolean value specifying the new checked and crossed-out
|
|
25726
25636
|
// value of this choice.
|
|
25727
25637
|
function updateChoice(choiceIndex, newValues) {
|
|
25728
|
-
const {
|
|
25729
|
-
multipleSelect,
|
|
25730
|
-
choices,
|
|
25731
|
-
onChange
|
|
25732
|
-
} = props;
|
|
25733
|
-
|
|
25734
25638
|
// Get the baseline `checked` values. If we're checking a new answer
|
|
25735
25639
|
// and multiple-select is not on, we should clear all choices to be
|
|
25736
25640
|
// unchecked. Otherwise, we should copy the old checked values.
|
|
@@ -25772,7 +25676,6 @@ const BaseRadio = function BaseRadio(props) {
|
|
|
25772
25676
|
});
|
|
25773
25677
|
|
|
25774
25678
|
// some commonly used shorthands
|
|
25775
|
-
const reviewMode = !!reviewModeRubric;
|
|
25776
25679
|
const isMobile = apiOptions.isMobile;
|
|
25777
25680
|
const firstChoiceHighlighted = choices[0].highlighted;
|
|
25778
25681
|
const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
|
|
@@ -25898,10 +25801,6 @@ const BaseRadio = function BaseRadio(props) {
|
|
|
25898
25801
|
className: css(styles$p.responsiveContainer)
|
|
25899
25802
|
}, fieldset);
|
|
25900
25803
|
};
|
|
25901
|
-
BaseRadio.defaultProps = {
|
|
25902
|
-
editMode: false,
|
|
25903
|
-
multipleSelect: false
|
|
25904
|
-
};
|
|
25905
25804
|
const styles$p = StyleSheet.create({
|
|
25906
25805
|
instructions: {
|
|
25907
25806
|
display: "block",
|
|
@@ -26000,7 +25899,7 @@ function radioValidator(userInput, rubric, strings) {
|
|
|
26000
25899
|
};
|
|
26001
25900
|
}
|
|
26002
25901
|
|
|
26003
|
-
// TODO: should numCorrect actually be on the rubric
|
|
25902
|
+
// TODO(LEMS-2541): should numCorrect actually be on the rubric
|
|
26004
25903
|
// instead of the userInput?
|
|
26005
25904
|
if (userInput.numCorrect && userInput.numCorrect > 1 && numSelected !== userInput.numCorrect) {
|
|
26006
25905
|
return {
|
|
@@ -26010,7 +25909,7 @@ function radioValidator(userInput, rubric, strings) {
|
|
|
26010
25909
|
// If NOTA and some other answer are checked, ...
|
|
26011
25910
|
}
|
|
26012
25911
|
|
|
26013
|
-
// TODO: should noneOfTheAboveSelected be replaced with a
|
|
25912
|
+
// TODO(LEMS-2541): should noneOfTheAboveSelected be replaced with a
|
|
26014
25913
|
// combination of choicesSelected and noneOfTheAboveIndex?
|
|
26015
25914
|
if (userInput.noneOfTheAboveSelected && numSelected > 1) {
|
|
26016
25915
|
return {
|
|
@@ -26020,7 +25919,7 @@ function radioValidator(userInput, rubric, strings) {
|
|
|
26020
25919
|
}
|
|
26021
25920
|
const correct = userInput.choicesSelected.every((selected, i) => {
|
|
26022
25921
|
let isCorrect;
|
|
26023
|
-
// TODO: should noneOfTheAboveIndex actually be on the rubric
|
|
25922
|
+
// TODO(LEMS-2541): should noneOfTheAboveIndex actually be on the rubric
|
|
26024
25923
|
// instead of the userInput?
|
|
26025
25924
|
if (userInput.noneOfTheAboveIndex === i) {
|
|
26026
25925
|
isCorrect = rubric.choices.every((choice, j) => {
|
|
@@ -26201,7 +26100,6 @@ class Radio$1 extends React.Component {
|
|
|
26201
26100
|
let noneOfTheAboveSelected = false;
|
|
26202
26101
|
const choiceStates = props.choiceStates;
|
|
26203
26102
|
const choicesSelected = choiceStates.map(() => false);
|
|
26204
|
-
const countChoices = props.countChoices;
|
|
26205
26103
|
const numCorrect = props.numCorrect;
|
|
26206
26104
|
for (let i = 0; i < choicesSelected.length; i++) {
|
|
26207
26105
|
const index = props.choices[i].originalIndex;
|
|
@@ -26215,7 +26113,6 @@ class Radio$1 extends React.Component {
|
|
|
26215
26113
|
}
|
|
26216
26114
|
}
|
|
26217
26115
|
return {
|
|
26218
|
-
countChoices,
|
|
26219
26116
|
choicesSelected,
|
|
26220
26117
|
numCorrect,
|
|
26221
26118
|
noneOfTheAboveIndex,
|
|
@@ -26231,7 +26128,6 @@ class Radio$1 extends React.Component {
|
|
|
26231
26128
|
let noneOfTheAboveIndex = null;
|
|
26232
26129
|
let noneOfTheAboveSelected = false;
|
|
26233
26130
|
const choicesSelected = [...values];
|
|
26234
|
-
const countChoices = props.countChoices;
|
|
26235
26131
|
const numCorrect = props.numCorrect;
|
|
26236
26132
|
const valuesLength = values.length;
|
|
26237
26133
|
for (let i = 0; i < valuesLength; i++) {
|
|
@@ -26249,7 +26145,6 @@ class Radio$1 extends React.Component {
|
|
|
26249
26145
|
choicesSelected,
|
|
26250
26146
|
noneOfTheAboveIndex,
|
|
26251
26147
|
noneOfTheAboveSelected,
|
|
26252
|
-
countChoices,
|
|
26253
26148
|
numCorrect
|
|
26254
26149
|
};
|
|
26255
26150
|
}
|
|
@@ -26340,6 +26235,7 @@ class Radio$1 extends React.Component {
|
|
|
26340
26235
|
}));
|
|
26341
26236
|
}
|
|
26342
26237
|
const choicesProp = choices.map((choice, i) => {
|
|
26238
|
+
var _this$props$reviewMod;
|
|
26343
26239
|
const content = choice.isNoneOfTheAbove && !choice.content ? strings.noneOfTheAbove : choice.content;
|
|
26344
26240
|
const {
|
|
26345
26241
|
selected,
|
|
@@ -26350,7 +26246,7 @@ class Radio$1 extends React.Component {
|
|
|
26350
26246
|
highlighted,
|
|
26351
26247
|
previouslyAnswered
|
|
26352
26248
|
} = choiceStates[i];
|
|
26353
|
-
const reviewChoice = this.props.reviewModeRubric
|
|
26249
|
+
const reviewChoice = (_this$props$reviewMod = this.props.reviewModeRubric) == null ? void 0 : _this$props$reviewMod.choices[i];
|
|
26354
26250
|
return {
|
|
26355
26251
|
content: this._renderRenderer(content),
|
|
26356
26252
|
checked: selected,
|
|
@@ -26385,6 +26281,7 @@ class Radio$1 extends React.Component {
|
|
|
26385
26281
|
choices: choicesProp,
|
|
26386
26282
|
onChange: this.updateChoices,
|
|
26387
26283
|
reviewModeRubric: this.props.reviewModeRubric,
|
|
26284
|
+
reviewMode: this.props.reviewMode,
|
|
26388
26285
|
deselectEnabled: this.props.deselectEnabled,
|
|
26389
26286
|
apiOptions: this.props.apiOptions,
|
|
26390
26287
|
isLastUsedWidget: this.props.isLastUsedWidget,
|
|
@@ -29121,7 +29018,7 @@ class Group extends React.Component {
|
|
|
29121
29018
|
ref: ref => this.rendererRef = ref,
|
|
29122
29019
|
apiOptions: apiOptions,
|
|
29123
29020
|
findExternalWidgets: this.props.findWidgets,
|
|
29124
|
-
reviewMode:
|
|
29021
|
+
reviewMode: this.props.reviewMode,
|
|
29125
29022
|
onInteractWithWidget: onInteractWithWidget,
|
|
29126
29023
|
linterContext: this.props.linterContext,
|
|
29127
29024
|
strings: this.context.strings
|
|
@@ -29152,23 +29049,23 @@ var Group$1 = {
|
|
|
29152
29049
|
isLintable: true
|
|
29153
29050
|
};
|
|
29154
29051
|
|
|
29155
|
-
function iframeValidator(
|
|
29052
|
+
function iframeValidator(userInput) {
|
|
29156
29053
|
// The iframe can tell us whether it's correct or incorrect,
|
|
29157
29054
|
// and pass an optional message
|
|
29158
|
-
if (
|
|
29055
|
+
if (userInput.status === "correct") {
|
|
29159
29056
|
return {
|
|
29160
29057
|
type: "points",
|
|
29161
29058
|
earned: 1,
|
|
29162
29059
|
total: 1,
|
|
29163
|
-
message:
|
|
29060
|
+
message: userInput.message || null
|
|
29164
29061
|
};
|
|
29165
29062
|
}
|
|
29166
|
-
if (
|
|
29063
|
+
if (userInput.status === "incorrect") {
|
|
29167
29064
|
return {
|
|
29168
29065
|
type: "points",
|
|
29169
29066
|
earned: 0,
|
|
29170
29067
|
total: 1,
|
|
29171
|
-
message:
|
|
29068
|
+
message: userInput.message || null
|
|
29172
29069
|
};
|
|
29173
29070
|
}
|
|
29174
29071
|
return {
|
|
@@ -38983,8 +38880,6 @@ const styles$b = StyleSheet.create({
|
|
|
38983
38880
|
* No diagonals allowed.
|
|
38984
38881
|
*/
|
|
38985
38882
|
|
|
38986
|
-
// TODO: should this be using WidgetProps / PerseusLabelImageWidgetOptions?
|
|
38987
|
-
|
|
38988
38883
|
class LabelImage extends React.Component {
|
|
38989
38884
|
/**
|
|
38990
38885
|
* Test whether point is contained within triangle.
|
|
@@ -40470,9 +40365,9 @@ var Matcher$1 = {
|
|
|
40470
40365
|
validator: matcherValidator
|
|
40471
40366
|
};
|
|
40472
40367
|
|
|
40473
|
-
function matrixValidator(
|
|
40368
|
+
function matrixValidator(userInput, rubric, strings) {
|
|
40474
40369
|
const solution = rubric.answers;
|
|
40475
|
-
const supplied =
|
|
40370
|
+
const supplied = userInput.answers;
|
|
40476
40371
|
const solutionSize = getMatrixSize(solution);
|
|
40477
40372
|
const suppliedSize = getMatrixSize(supplied);
|
|
40478
40373
|
const incorrectSize = solutionSize[0] !== suppliedSize[0] || solutionSize[1] !== suppliedSize[1];
|
|
@@ -40615,9 +40510,6 @@ class Matrix extends React.Component {
|
|
|
40615
40510
|
});
|
|
40616
40511
|
return inputPaths;
|
|
40617
40512
|
};
|
|
40618
|
-
this.getGrammarTypeForPath = inputPath => {
|
|
40619
|
-
return "number";
|
|
40620
|
-
};
|
|
40621
40513
|
this._handleFocus = (row, col) => {
|
|
40622
40514
|
this.props.onFocus(getInputPath$1(row, col));
|
|
40623
40515
|
};
|
|
@@ -41030,7 +40922,7 @@ class Measurer extends React.Component {
|
|
|
41030
40922
|
}
|
|
41031
40923
|
Measurer.defaultProps = {
|
|
41032
40924
|
box: [480, 480],
|
|
41033
|
-
image:
|
|
40925
|
+
image: defaultImage,
|
|
41034
40926
|
showProtractor: true,
|
|
41035
40927
|
protractorX: 7.5,
|
|
41036
40928
|
protractorY: 0.5,
|
|
@@ -42415,11 +42307,6 @@ class NumberLine extends React.Component {
|
|
|
42415
42307
|
}
|
|
42416
42308
|
return null;
|
|
42417
42309
|
}
|
|
42418
|
-
getGrammarTypeForPath(inputPath) {
|
|
42419
|
-
if ((inputPath == null ? void 0 : inputPath.length) === 1 && inputPath[0] === "tick-ctrl") {
|
|
42420
|
-
return "number";
|
|
42421
|
-
}
|
|
42422
|
-
}
|
|
42423
42310
|
getUserInput() {
|
|
42424
42311
|
return {
|
|
42425
42312
|
numLinePosition: this.props.numLinePosition,
|
|
@@ -44513,9 +44400,6 @@ class Table extends React.Component {
|
|
|
44513
44400
|
});
|
|
44514
44401
|
return inputPaths;
|
|
44515
44402
|
};
|
|
44516
|
-
this.getGrammarTypeForPath = inputPath => {
|
|
44517
|
-
return "number";
|
|
44518
|
-
};
|
|
44519
44403
|
this.setInputValue = (path, newValue, cb) => {
|
|
44520
44404
|
// Extract row, column information
|
|
44521
44405
|
const row = getRowFromPath(path);
|
|
@@ -44833,7 +44717,7 @@ const init = function init(options) {
|
|
|
44833
44717
|
|
|
44834
44718
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
44835
44719
|
const libName = "@khanacademy/perseus";
|
|
44836
|
-
const libVersion = "
|
|
44720
|
+
const libVersion = "39.0.1";
|
|
44837
44721
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
44838
44722
|
|
|
44839
44723
|
const apiVersion = {
|
|
@@ -45555,9 +45439,6 @@ class ServerItemRenderer extends React.Component {
|
|
|
45555
45439
|
getDOMNodeForPath(path) {
|
|
45556
45440
|
return this.questionRenderer.getDOMNodeForPath(path);
|
|
45557
45441
|
}
|
|
45558
|
-
getGrammarTypeForPath(path) {
|
|
45559
|
-
return this.questionRenderer.getGrammarTypeForPath(path);
|
|
45560
|
-
}
|
|
45561
45442
|
getInputPaths() {
|
|
45562
45443
|
const questionAreaInputPaths = this.questionRenderer.getInputPaths();
|
|
45563
45444
|
return questionAreaInputPaths;
|
|
@@ -46834,7 +46715,6 @@ const styles = StyleSheet.create({
|
|
|
46834
46715
|
* If you're writing new components, though, consider using the Item and Shape
|
|
46835
46716
|
* types instead.
|
|
46836
46717
|
*/
|
|
46837
|
-
|
|
46838
46718
|
/**
|
|
46839
46719
|
* Return a PropType that accepts Items of the given shape, and rejects other
|
|
46840
46720
|
* objects.
|
|
@@ -47066,6 +46946,21 @@ function violatingWidgets(itemData) {
|
|
|
47066
46946
|
}
|
|
47067
46947
|
|
|
47068
46948
|
/* eslint-disable eqeqeq, @typescript-eslint/no-unused-vars */
|
|
46949
|
+
/*
|
|
46950
|
+
* A class for formatting number to significant digits.
|
|
46951
|
+
* Copyright (C) 2001 Stephen Ostermiller
|
|
46952
|
+
* http://ostermiller.org/contact.pl?regarding?JavaScript+Significant+Figures
|
|
46953
|
+
*
|
|
46954
|
+
* This program is free software; you can redistribute it and/or modify
|
|
46955
|
+
* it under the terms of the GNU General Public License as published by
|
|
46956
|
+
* the Free Software Foundation; either version 2 of the License, or
|
|
46957
|
+
* (at your option) any later version.
|
|
46958
|
+
*
|
|
46959
|
+
* This program is distributed in the hope that it will be useful,
|
|
46960
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
46961
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
46962
|
+
* GNU General Public License for more details.
|
|
46963
|
+
*/
|
|
47069
46964
|
|
|
47070
46965
|
/**
|
|
47071
46966
|
* Format a floating point for display using the specified
|