@khanacademy/perseus 31.1.0 → 32.0.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.
Files changed (86) hide show
  1. package/dist/components/input-with-examples.d.ts +1 -1
  2. package/dist/components/number-input.d.ts +1 -1
  3. package/dist/components/range-input.d.ts +1 -1
  4. package/dist/components/sortable.d.ts +5 -5
  5. package/dist/components/text-input.d.ts +1 -1
  6. package/dist/components/text-list-editor.d.ts +1 -1
  7. package/dist/es/index.js +529 -479
  8. package/dist/es/index.js.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +1348 -1305
  11. package/dist/index.js.map +1 -1
  12. package/dist/perseus-types.d.ts +1 -10
  13. package/dist/widget-container.d.ts +1 -1
  14. package/dist/widgets/__shared__/test-keypad-context-wrapper.d.ts +6 -0
  15. package/dist/widgets/{categorizer.d.ts → categorizer/categorizer.d.ts} +14 -14
  16. package/dist/widgets/categorizer/index.d.ts +1 -0
  17. package/dist/widgets/{cs-program.d.ts → cs-program/cs-program.d.ts} +7 -7
  18. package/dist/widgets/cs-program/index.d.ts +1 -0
  19. package/dist/widgets/{definition.d.ts → definition/definition.d.ts} +11 -11
  20. package/dist/widgets/definition/index.d.ts +1 -0
  21. package/dist/widgets/{dropdown.d.ts → dropdown/dropdown.d.ts} +9 -9
  22. package/dist/widgets/dropdown/index.d.ts +1 -0
  23. package/dist/widgets/{explanation.d.ts → explanation/explanation.d.ts} +14 -14
  24. package/dist/widgets/explanation/index.d.ts +1 -0
  25. package/dist/widgets/{expression.d.ts → expression/expression.d.ts} +66 -66
  26. package/dist/widgets/expression/index.d.ts +1 -0
  27. package/dist/widgets/{graded-group-answer-bar.d.ts → graded-group/graded-group-answer-bar.d.ts} +3 -3
  28. package/dist/widgets/{graded-group.d.ts → graded-group/graded-group.d.ts} +11 -11
  29. package/dist/widgets/graded-group/index.d.ts +1 -0
  30. package/dist/widgets/{graded-group-set.d.ts → graded-group-set/graded-group-set.d.ts} +11 -11
  31. package/dist/widgets/graded-group-set/index.d.ts +1 -0
  32. package/dist/widgets/{grapher.d.ts → grapher/grapher.d.ts} +15 -15
  33. package/dist/widgets/grapher/index.d.ts +1 -0
  34. package/dist/widgets/{group.d.ts → group/group.d.ts} +12 -12
  35. package/dist/widgets/group/index.d.ts +1 -0
  36. package/dist/widgets/{iframe.d.ts → iframe/iframe.d.ts} +10 -10
  37. package/dist/widgets/iframe/index.d.ts +1 -0
  38. package/dist/widgets/{image.d.ts → image/image.d.ts} +12 -12
  39. package/dist/widgets/image/index.d.ts +1 -0
  40. package/dist/widgets/input-number/index.d.ts +1 -0
  41. package/dist/widgets/{input-number.d.ts → input-number/input-number.d.ts} +19 -19
  42. package/dist/widgets/interaction/index.d.ts +1 -0
  43. package/dist/widgets/{interaction.d.ts → interaction/interaction.d.ts} +12 -12
  44. package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +22 -1
  45. package/dist/widgets/interactive-graphs/types.d.ts +1 -0
  46. package/dist/widgets/label-image/index.d.ts +1 -0
  47. package/dist/widgets/{label-image.d.ts → label-image/label-image.d.ts} +24 -24
  48. package/dist/widgets/matcher/index.d.ts +1 -0
  49. package/dist/widgets/{matcher.d.ts → matcher/matcher.d.ts} +11 -11
  50. package/dist/widgets/matrix/index.d.ts +1 -0
  51. package/dist/widgets/{matrix.d.ts → matrix/matrix.d.ts} +12 -12
  52. package/dist/widgets/measurer/index.d.ts +1 -0
  53. package/dist/widgets/measurer/measurer.d.ts +21 -0
  54. package/dist/widgets/molecule/index.d.ts +1 -0
  55. package/dist/widgets/{molecule.d.ts → molecule/molecule.d.ts} +10 -10
  56. package/dist/widgets/number-line/index.d.ts +1 -0
  57. package/dist/widgets/{number-line.d.ts → number-line/number-line.d.ts} +11 -11
  58. package/dist/widgets/numeric-input/index.d.ts +1 -0
  59. package/dist/widgets/{numeric-input.d.ts → numeric-input/numeric-input.d.ts} +13 -13
  60. package/dist/widgets/orderer/index.d.ts +1 -0
  61. package/dist/widgets/{orderer.d.ts → orderer/orderer.d.ts} +10 -10
  62. package/dist/widgets/passage/index.d.ts +2 -0
  63. package/dist/widgets/{passage.d.ts → passage/passage.d.ts} +15 -15
  64. package/dist/widgets/passage-ref/index.d.ts +1 -0
  65. package/dist/widgets/{passage-ref.d.ts → passage-ref/passage-ref.d.ts} +16 -16
  66. package/dist/widgets/passage-ref-target/index.d.ts +1 -0
  67. package/dist/widgets/{passage-ref-target.d.ts → passage-ref-target/passage-ref-target.d.ts} +12 -12
  68. package/dist/widgets/phet-simulation/index.d.ts +1 -0
  69. package/dist/widgets/{phet-simulation.d.ts → phet-simulation/phet-simulation.d.ts} +11 -13
  70. package/dist/widgets/plotter/index.d.ts +1 -0
  71. package/dist/widgets/{plotter.d.ts → plotter/plotter.d.ts} +11 -11
  72. package/dist/widgets/python-program/index.d.ts +1 -0
  73. package/dist/widgets/{python-program.d.ts → python-program/python-program.d.ts} +7 -7
  74. package/dist/widgets/radio/index.d.ts +2 -0
  75. package/dist/widgets/radio/radio-component.d.ts +66 -0
  76. package/dist/widgets/radio/radio.d.ts +22 -66
  77. package/dist/widgets/sorter/index.d.ts +1 -0
  78. package/dist/widgets/{sorter.d.ts → sorter/sorter.d.ts} +8 -8
  79. package/dist/widgets/table/index.d.ts +1 -0
  80. package/dist/widgets/{table.d.ts → table/table.d.ts} +10 -10
  81. package/dist/widgets/video/index.d.ts +1 -0
  82. package/dist/widgets/{video.d.ts → video/video.d.ts} +11 -11
  83. package/package.json +1 -1
  84. package/dist/widgets/measurer.d.ts +0 -21
  85. package/dist/widgets/radio.d.ts +0 -22
  86. /package/dist/widgets/{video-transcript-link.d.ts → video/video-transcript-link.d.ts} +0 -0
package/dist/es/index.js CHANGED
@@ -19467,6 +19467,14 @@ class WidgetContainer extends React.Component {
19467
19467
  }
19468
19468
  }
19469
19469
 
19470
+ UNSAFE_componentWillReceiveProps(nextProps) {
19471
+ if (this.props.type !== nextProps.type) {
19472
+ throw new Error("WidgetContainer can't change widget type; set a different " + "key instead to recreate the container.");
19473
+ }
19474
+ }
19475
+ shouldComponentUpdate(nextProps, nextState) {
19476
+ return this.props.shouldHighlight !== nextProps.shouldHighlight || this.props.type !== nextProps.type || this.state.widgetProps !== nextState.widgetProps || this.state.sizeClass !== nextState.sizeClass;
19477
+ }
19470
19478
  render() {
19471
19479
  let className = classNames({
19472
19480
  "perseus-widget-container": true,
@@ -19557,14 +19565,6 @@ class WidgetContainer extends React.Component {
19557
19565
  style: staticOverlayStyles
19558
19566
  }))));
19559
19567
  }
19560
- UNSAFE_componentWillReceiveProps(nextProps) {
19561
- if (this.props.type !== nextProps.type) {
19562
- throw new Error("WidgetContainer can't change widget type; set a different " + "key instead to recreate the container.");
19563
- }
19564
- }
19565
- shouldComponentUpdate(nextProps, nextState) {
19566
- return this.props.shouldHighlight !== nextProps.shouldHighlight || this.props.type !== nextProps.type || this.state.widgetProps !== nextState.widgetProps || this.state.sizeClass !== nextState.sizeClass;
19567
- }
19568
19568
  }
19569
19569
  WidgetContainer.defaultProps = {
19570
19570
  linterContext: linterContextDefault
@@ -21325,7 +21325,6 @@ Tooltip.defaultProps = {
21325
21325
  targetContainerStyle: {}
21326
21326
  };
21327
21327
 
21328
- /* eslint-disable react/sort-comp */
21329
21328
  const {
21330
21329
  captureScratchpadTouchStart: captureScratchpadTouchStart$2
21331
21330
  } = Util;
@@ -21681,7 +21680,6 @@ var TexWrangler = {
21681
21680
  modifyTex
21682
21681
  };
21683
21682
 
21684
- /* eslint-disable react/sort-comp */
21685
21683
  const ParseTex$1 = TexWrangler.parseTex;
21686
21684
  const answerTypes = {
21687
21685
  number: {
@@ -21819,55 +21817,6 @@ class InputNumber extends React.Component {
21819
21817
  return [strings.yourAnswer].concat(examples);
21820
21818
  };
21821
21819
  }
21822
- render() {
21823
- if (this.props.apiOptions.customKeypad) {
21824
- // TODO(charlie): Support "Review Mode".
21825
- const input = /*#__PURE__*/React.createElement(SimpleKeypadInput
21826
- // eslint-disable-next-line react/no-string-refs
21827
- , {
21828
- ref: "input",
21829
- value: this.props.currentValue,
21830
- keypadElement: this.props.keypadElement,
21831
- onChange: this.handleChange,
21832
- onFocus: this._handleFocus,
21833
- onBlur: this._handleBlur
21834
- });
21835
- if (this.props.rightAlign) {
21836
- return /*#__PURE__*/React.createElement("div", {
21837
- className: "perseus-input-right-align"
21838
- }, input);
21839
- }
21840
- return input;
21841
- }
21842
- // HACK(johnsullivan): Create a function with shared logic between
21843
- // this and NumericInput.
21844
- // TODO(jeremy): Deprecate this widget and prefer numeric-input.
21845
- const rubric = this.props.reviewModeRubric;
21846
-
21847
- // Note: This is _very_ similar to what `numeric-input.jsx` does. If
21848
- // you modify this, double-check if you also need to modify that
21849
- // component.
21850
- const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
21851
- // Unanswered
21852
- if (rubric && !this.props.currentValue) {
21853
- inputStyles.push(styles$A.answerStateUnanswered);
21854
- }
21855
- return /*#__PURE__*/React.createElement(InputWithExamples
21856
- // eslint-disable-next-line react/no-string-refs
21857
- , {
21858
- ref: "input",
21859
- value: this.props.currentValue,
21860
- onChange: this.handleChange,
21861
- style: inputStyles,
21862
- examples: this.examples(),
21863
- shouldShowExamples: this.shouldShowExamples(),
21864
- onFocus: this._handleFocus,
21865
- onBlur: this._handleBlur,
21866
- id: this.props.widgetId,
21867
- disabled: this.props.apiOptions.readOnly,
21868
- linterContext: this.props.linterContext
21869
- });
21870
- }
21871
21820
  static validate(state, rubric, strings, onInputError = () => {}) {
21872
21821
  if (rubric.answerType == null) {
21873
21822
  rubric.answerType = "number";
@@ -21923,6 +21872,55 @@ class InputNumber extends React.Component {
21923
21872
  }
21924
21873
  return answerString;
21925
21874
  }
21875
+ render() {
21876
+ if (this.props.apiOptions.customKeypad) {
21877
+ // TODO(charlie): Support "Review Mode".
21878
+ const input = /*#__PURE__*/React.createElement(SimpleKeypadInput
21879
+ // eslint-disable-next-line react/no-string-refs
21880
+ , {
21881
+ ref: "input",
21882
+ value: this.props.currentValue,
21883
+ keypadElement: this.props.keypadElement,
21884
+ onChange: this.handleChange,
21885
+ onFocus: this._handleFocus,
21886
+ onBlur: this._handleBlur
21887
+ });
21888
+ if (this.props.rightAlign) {
21889
+ return /*#__PURE__*/React.createElement("div", {
21890
+ className: "perseus-input-right-align"
21891
+ }, input);
21892
+ }
21893
+ return input;
21894
+ }
21895
+ // HACK(johnsullivan): Create a function with shared logic between
21896
+ // this and NumericInput.
21897
+ // TODO(jeremy): Deprecate this widget and prefer numeric-input.
21898
+ const rubric = this.props.reviewModeRubric;
21899
+
21900
+ // Note: This is _very_ similar to what `numeric-input.jsx` does. If
21901
+ // you modify this, double-check if you also need to modify that
21902
+ // component.
21903
+ const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
21904
+ // Unanswered
21905
+ if (rubric && !this.props.currentValue) {
21906
+ inputStyles.push(styles$A.answerStateUnanswered);
21907
+ }
21908
+ return /*#__PURE__*/React.createElement(InputWithExamples
21909
+ // eslint-disable-next-line react/no-string-refs
21910
+ , {
21911
+ ref: "input",
21912
+ value: this.props.currentValue,
21913
+ onChange: this.handleChange,
21914
+ style: inputStyles,
21915
+ examples: this.examples(),
21916
+ shouldShowExamples: this.shouldShowExamples(),
21917
+ onFocus: this._handleFocus,
21918
+ onBlur: this._handleBlur,
21919
+ id: this.props.widgetId,
21920
+ disabled: this.props.apiOptions.readOnly,
21921
+ linterContext: this.props.linterContext
21922
+ });
21923
+ }
21926
21924
  }
21927
21925
  InputNumber.contextType = PerseusI18nContext;
21928
21926
  InputNumber.defaultProps = {
@@ -22384,7 +22382,6 @@ var NumericInput$1 = {
22384
22382
  isLintable: true
22385
22383
  };
22386
22384
 
22387
- /* eslint-disable react/sort-comp */
22388
22385
  const EN_DASH$1 = "\u2013";
22389
22386
  class PassageRef extends React.Component {
22390
22387
  constructor(..._args) {
@@ -22436,9 +22433,32 @@ class PassageRef extends React.Component {
22436
22433
  return PassageRef.validate(this.getUserInput(), rubric);
22437
22434
  };
22438
22435
  }
22436
+ static validate(userInput, rubric) {
22437
+ return {
22438
+ type: "points",
22439
+ earned: 0,
22440
+ total: 0,
22441
+ message: null
22442
+ };
22443
+ }
22444
+ componentDidMount() {
22445
+ // TODO(scottgrant): This is a hack to remove the deprecated call to
22446
+ // this.isMounted() but is still considered an anti-pattern.
22447
+ this._isMounted = true;
22448
+ this._deferredUpdateRange();
22449
+ this._throttledUpdateRange = _.throttle(this._deferredUpdateRange, 500);
22450
+ window.addEventListener("resize", this._throttledUpdateRange);
22451
+ }
22439
22452
  shouldComponentUpdate(nextProps, nextState) {
22440
22453
  return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
22441
22454
  }
22455
+ componentDidUpdate() {
22456
+ this._deferredUpdateRange();
22457
+ }
22458
+ componentWillUnmount() {
22459
+ window.removeEventListener("resize", this._throttledUpdateRange);
22460
+ this._isMounted = false;
22461
+ }
22442
22462
  render() {
22443
22463
  const {
22444
22464
  strings
@@ -22472,29 +22492,6 @@ class PassageRef extends React.Component {
22472
22492
  className: "perseus-sr-only"
22473
22493
  }, this.state.content));
22474
22494
  }
22475
- componentDidMount() {
22476
- // TODO(scottgrant): This is a hack to remove the deprecated call to
22477
- // this.isMounted() but is still considered an anti-pattern.
22478
- this._isMounted = true;
22479
- this._deferredUpdateRange();
22480
- this._throttledUpdateRange = _.throttle(this._deferredUpdateRange, 500);
22481
- window.addEventListener("resize", this._throttledUpdateRange);
22482
- }
22483
- componentDidUpdate() {
22484
- this._deferredUpdateRange();
22485
- }
22486
- componentWillUnmount() {
22487
- window.removeEventListener("resize", this._throttledUpdateRange);
22488
- this._isMounted = false;
22489
- }
22490
- static validate(userInput, rubric) {
22491
- return {
22492
- type: "points",
22493
- earned: 0,
22494
- total: 0,
22495
- message: null
22496
- };
22497
- }
22498
22495
  }
22499
22496
  PassageRef.contextType = PerseusI18nContext;
22500
22497
  PassageRef.defaultProps = {
@@ -24434,6 +24431,40 @@ class Categorizer extends React.Component {
24434
24431
  return Categorizer.validate(this.getUserInput(), rubric, this.context.strings);
24435
24432
  };
24436
24433
  }
24434
+ static validate(userInput, rubric, strings) {
24435
+ let completed = true;
24436
+ let allCorrect = true;
24437
+ rubric.values.forEach((value, i) => {
24438
+ if (userInput.values[i] == null) {
24439
+ completed = false;
24440
+ }
24441
+ if (userInput.values[i] !== value) {
24442
+ allCorrect = false;
24443
+ }
24444
+ });
24445
+ if (!completed) {
24446
+ return {
24447
+ type: "invalid",
24448
+ message: strings.invalidSelection
24449
+ };
24450
+ }
24451
+ return {
24452
+ type: "points",
24453
+ earned: allCorrect ? 1 : 0,
24454
+ total: 1,
24455
+ message: null
24456
+ };
24457
+ }
24458
+ static getUserInputFromProps(props) {
24459
+ return WidgetJsonifyDeprecated.getUserInputFromProps(props);
24460
+ }
24461
+ onChange(itemNum, catNum) {
24462
+ const values = [...this.props.values];
24463
+ // @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'never'.
24464
+ values[itemNum] = catNum;
24465
+ this.change("values", values);
24466
+ this.props.trackInteraction();
24467
+ }
24437
24468
  render() {
24438
24469
  const self = this;
24439
24470
 
@@ -24510,40 +24541,6 @@ class Categorizer extends React.Component {
24510
24541
  className: extraClassNames + " " + css(...inlineStyles)
24511
24542
  }, table);
24512
24543
  }
24513
- onChange(itemNum, catNum) {
24514
- const values = [...this.props.values];
24515
- // @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'never'.
24516
- values[itemNum] = catNum;
24517
- this.change("values", values);
24518
- this.props.trackInteraction();
24519
- }
24520
- static validate(userInput, rubric, strings) {
24521
- let completed = true;
24522
- let allCorrect = true;
24523
- rubric.values.forEach((value, i) => {
24524
- if (userInput.values[i] == null) {
24525
- completed = false;
24526
- }
24527
- if (userInput.values[i] !== value) {
24528
- allCorrect = false;
24529
- }
24530
- });
24531
- if (!completed) {
24532
- return {
24533
- type: "invalid",
24534
- message: strings.invalidSelection
24535
- };
24536
- }
24537
- return {
24538
- type: "points",
24539
- earned: allCorrect ? 1 : 0,
24540
- total: 1,
24541
- message: null
24542
- };
24543
- }
24544
- static getUserInputFromProps(props) {
24545
- return WidgetJsonifyDeprecated.getUserInputFromProps(props);
24546
- }
24547
24544
  }
24548
24545
 
24549
24546
  // TODO(benkomalo): inject page-margin into Perseus instead of hardcoding.
@@ -25053,8 +25050,6 @@ var Dropdown$1 = {
25053
25050
  transform: optionsTransform
25054
25051
  };
25055
25052
 
25056
- /* eslint-disable react/sort-comp */
25057
-
25058
25053
  // transform = _.identity
25059
25054
 
25060
25055
  function mediaQueryIsMatched(mediaQuery) {
@@ -26811,20 +26806,48 @@ class Grapher extends React.Component {
26811
26806
  }
26812
26807
  };
26813
26808
  }
26814
- render() {
26815
- const type = this.props.plot.type;
26816
- const coords = this.props.plot.coords;
26817
- const asymptote = this.props.plot.asymptote;
26818
- const typeSelector = /*#__PURE__*/React.createElement("div", {
26819
- style: typeSelectorStyle,
26820
- className: "above-scratchpad"
26821
- }, /*#__PURE__*/React.createElement(ButtonGroup, {
26822
- value: type,
26823
- allowEmpty: true,
26824
- buttons: _.map(this.props.availableTypes, typeToButton),
26825
- onChange: this.handleActiveTypeChange
26826
- }));
26827
- const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
26809
+ static validate(state, rubric) {
26810
+ return validate$1(state, rubric);
26811
+ }
26812
+ static getUserInputFromProps(props) {
26813
+ return props.plot;
26814
+ }
26815
+ _getGridConfig(options) {
26816
+ return options.step.map((step, i) => {
26817
+ return Util.gridDimensionConfig(step, options.range[i], options.box[i], options.gridStep[i]);
26818
+ });
26819
+ }
26820
+ _calculateMobileTickStep(gridStep, step, ranges) {
26821
+ const tickStep = Util.constrainedTickStepsFromTickSteps(step, ranges);
26822
+
26823
+ // According to the graphInit documentation in graphie.js, tickStep is
26824
+ // relative to the grid units so we need to adjust all values by the
26825
+ // grid step.
26826
+ tickStep[0] = tickStep[0] / gridStep[0];
26827
+ tickStep[1] = tickStep[1] / gridStep[1];
26828
+ return tickStep;
26829
+ }
26830
+ simpleValidate(rubric) {
26831
+ return validate$1(this.getUserInput(), rubric);
26832
+ }
26833
+ getUserInput() {
26834
+ return Grapher.getUserInputFromProps(this.props);
26835
+ }
26836
+ focus() {}
26837
+ render() {
26838
+ const type = this.props.plot.type;
26839
+ const coords = this.props.plot.coords;
26840
+ const asymptote = this.props.plot.asymptote;
26841
+ const typeSelector = /*#__PURE__*/React.createElement("div", {
26842
+ style: typeSelectorStyle,
26843
+ className: "above-scratchpad"
26844
+ }, /*#__PURE__*/React.createElement(ButtonGroup, {
26845
+ value: type,
26846
+ allowEmpty: true,
26847
+ buttons: _.map(this.props.availableTypes, typeToButton),
26848
+ onChange: this.handleActiveTypeChange
26849
+ }));
26850
+ const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
26828
26851
 
26829
26852
  // Calculate additional graph properties so that the same values are
26830
26853
  // passed in to both FunctionGrapher and Graphie.
@@ -26861,34 +26884,6 @@ class Grapher extends React.Component {
26861
26884
  };
26862
26885
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(FunctionGrapher, grapherProps), this.props.availableTypes.length > 1 && typeSelector);
26863
26886
  }
26864
- _getGridConfig(options) {
26865
- return options.step.map((step, i) => {
26866
- return Util.gridDimensionConfig(step, options.range[i], options.box[i], options.gridStep[i]);
26867
- });
26868
- }
26869
- _calculateMobileTickStep(gridStep, step, ranges) {
26870
- const tickStep = Util.constrainedTickStepsFromTickSteps(step, ranges);
26871
-
26872
- // According to the graphInit documentation in graphie.js, tickStep is
26873
- // relative to the grid units so we need to adjust all values by the
26874
- // grid step.
26875
- tickStep[0] = tickStep[0] / gridStep[0];
26876
- tickStep[1] = tickStep[1] / gridStep[1];
26877
- return tickStep;
26878
- }
26879
- simpleValidate(rubric) {
26880
- return validate$1(this.getUserInput(), rubric);
26881
- }
26882
- getUserInput() {
26883
- return Grapher.getUserInputFromProps(this.props);
26884
- }
26885
- focus() {}
26886
- static validate(state, rubric) {
26887
- return validate$1(state, rubric);
26888
- }
26889
- static getUserInputFromProps(props) {
26890
- return props.plot;
26891
- }
26892
26887
  }
26893
26888
  Grapher.defaultProps = DEFAULT_GRAPHER_PROPS;
26894
26889
  const propTransform$2 = editorProps => {
@@ -27234,7 +27229,6 @@ var Iframe$1 = {
27234
27229
  hidden: true
27235
27230
  };
27236
27231
 
27237
- /* eslint-disable react/sort-comp */
27238
27232
  const defaultBoxSize = 400;
27239
27233
  const defaultRange = [0, 10];
27240
27234
  const defaultBackgroundImage$2 = {
@@ -27261,6 +27255,14 @@ class ImageWidget extends React.Component {
27261
27255
  };
27262
27256
  this.focus = () => {};
27263
27257
  }
27258
+ static validate(userInput, rubric) {
27259
+ return {
27260
+ type: "points",
27261
+ earned: 0,
27262
+ total: 0,
27263
+ message: null
27264
+ };
27265
+ }
27264
27266
  // no-op
27265
27267
 
27266
27268
  render() {
@@ -27392,14 +27394,6 @@ class ImageWidget extends React.Component {
27392
27394
  }
27393
27395
  }, title, image, caption);
27394
27396
  }
27395
- static validate(userInput, rubric) {
27396
- return {
27397
- type: "points",
27398
- earned: 0,
27399
- total: 0,
27400
- message: null
27401
- };
27402
- }
27403
27397
  }
27404
27398
  ImageWidget.contextType = PerseusI18nContext;
27405
27399
  ImageWidget.defaultProps = {
@@ -27587,6 +27581,14 @@ class Interaction extends React.Component {
27587
27581
  return Interaction.validate(this.getUserInput(), rubric);
27588
27582
  };
27589
27583
  }
27584
+ static validate(state, rubric) {
27585
+ return {
27586
+ type: "points",
27587
+ earned: 0,
27588
+ total: 0,
27589
+ message: null
27590
+ };
27591
+ }
27590
27592
  UNSAFE_componentWillReceiveProps(nextProps) {
27591
27593
  // HACK(michaelpolyak): This widget is not wired to use the Perseus
27592
27594
  // `onChange` callback to save user changes. Perseus re-rendering of the
@@ -27932,14 +27934,6 @@ class Interaction extends React.Component {
27932
27934
  }
27933
27935
  }, this));
27934
27936
  }
27935
- static validate(state, rubric) {
27936
- return {
27937
- type: "points",
27938
- earned: 0,
27939
- total: 0,
27940
- message: null
27941
- };
27942
- }
27943
27937
  }
27944
27938
  Interaction.defaultProps = {
27945
27939
  graph: {
@@ -29539,6 +29533,11 @@ class NumberInput extends React.Component {
29539
29533
  $(ReactDOM__default.findDOMNode(this.refs.input)).val(toNumericString(val, format));
29540
29534
  };
29541
29535
  }
29536
+ componentDidUpdate(prevProps) {
29537
+ if (!number.equal(this.getValue(), this.props.value)) {
29538
+ this._setValue(this.props.value, this.state.format);
29539
+ }
29540
+ }
29542
29541
  render() {
29543
29542
  let classes = classNames({
29544
29543
  "number-input": true,
@@ -29570,11 +29569,6 @@ class NumberInput extends React.Component {
29570
29569
  value: undefined
29571
29570
  }));
29572
29571
  }
29573
- componentDidUpdate(prevProps) {
29574
- if (!number.equal(this.getValue(), this.props.value)) {
29575
- this._setValue(this.props.value, this.state.format);
29576
- }
29577
- }
29578
29572
  }
29579
29573
  NumberInput.contextType = PerseusI18nContext;
29580
29574
  NumberInput.propTypes = {
@@ -29802,12 +29796,6 @@ const ItemExtras = [
29802
29796
 
29803
29797
  // prettier-ignore
29804
29798
 
29805
- // prettier-ignore
29806
-
29807
- // prettier-ignore
29808
-
29809
- // prettier-ignore
29810
-
29811
29799
  //prettier-ignore
29812
29800
 
29813
29801
  // A background image applied to various widgets.
@@ -30208,6 +30196,9 @@ const GraphLockedLayer = props => {
30208
30196
  };
30209
30197
 
30210
30198
  const actions = {
30199
+ global: {
30200
+ deleteIntent
30201
+ },
30211
30202
  angle: {
30212
30203
  movePoint
30213
30204
  },
@@ -30226,7 +30217,9 @@ const actions = {
30226
30217
  pointGraph: {
30227
30218
  movePoint,
30228
30219
  addPoint,
30229
- removePoint
30220
+ removePoint,
30221
+ focusPoint,
30222
+ blurPoint
30230
30223
  },
30231
30224
  polygon: {
30232
30225
  movePoint,
@@ -30247,6 +30240,12 @@ const actions = {
30247
30240
  movePoint
30248
30241
  }
30249
30242
  };
30243
+ const DELETE_INTENT = "delete-intent";
30244
+ function deleteIntent() {
30245
+ return {
30246
+ type: DELETE_INTENT
30247
+ };
30248
+ }
30250
30249
  const MOVE_LINE = "move-line";
30251
30250
  function moveLine(itemIndex, delta) {
30252
30251
  return {
@@ -30269,6 +30268,19 @@ function removePoint(index) {
30269
30268
  index
30270
30269
  };
30271
30270
  }
30271
+ const FOCUS_POINT = "focus-point";
30272
+ function focusPoint(index) {
30273
+ return {
30274
+ type: FOCUS_POINT,
30275
+ index
30276
+ };
30277
+ }
30278
+ const BLUR_POINT = "blur-point";
30279
+ function blurPoint() {
30280
+ return {
30281
+ type: BLUR_POINT
30282
+ };
30283
+ }
30272
30284
  const MOVE_ALL = "move-all";
30273
30285
  function moveAll(delta) {
30274
30286
  return {
@@ -31863,7 +31875,14 @@ function UnlimitedPointGraph(props) {
31863
31875
  }), props.graphState.coords.map((point, i) => /*#__PURE__*/React.createElement(MovablePoint$1, {
31864
31876
  key: i,
31865
31877
  point: point,
31866
- onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination))
31878
+ onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination)),
31879
+ onFocusChange: isFocused => {
31880
+ if (isFocused) {
31881
+ dispatch(actions.pointGraph.focusPoint(i));
31882
+ } else {
31883
+ dispatch(actions.pointGraph.blurPoint());
31884
+ }
31885
+ }
31867
31886
  })));
31868
31887
  }
31869
31888
  function PointGraph(props) {
@@ -32019,6 +32038,7 @@ const MafsGraph = props => {
32019
32038
  } = props;
32020
32039
  const [width, height] = props.box;
32021
32040
  const tickStep = props.step;
32041
+ const graphRef = React.useRef(null);
32022
32042
  return /*#__PURE__*/React.createElement(GraphConfigContext.Provider, {
32023
32043
  value: {
32024
32044
  range: state.range,
@@ -32036,16 +32056,25 @@ const MafsGraph = props => {
32036
32056
  }, /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, {
32037
32057
  className: "mafs-graph",
32038
32058
  style: {
32039
- height,
32040
- width: "intrinsic",
32041
32059
  position: "relative",
32042
32060
  padding: "25px 25px 0 0",
32043
32061
  boxSizing: "content-box",
32044
32062
  marginLeft: "20px",
32045
32063
  marginBottom: "20px",
32046
32064
  pointerEvents: props.static ? "none" : "auto",
32047
- userSelect: "none"
32048
- }
32065
+ userSelect: "none",
32066
+ width,
32067
+ height
32068
+ },
32069
+ onKeyUp: event => {
32070
+ if (event.key === "Backspace") {
32071
+ var _graphRef$current;
32072
+ dispatch(actions.global.deleteIntent());
32073
+ (_graphRef$current = graphRef.current) == null || _graphRef$current.focus();
32074
+ }
32075
+ },
32076
+ ref: graphRef,
32077
+ tabIndex: 0
32049
32078
  }, /*#__PURE__*/React.createElement(LegacyGrid, {
32050
32079
  box: props.box,
32051
32080
  backgroundImage: props.backgroundImage
@@ -32226,7 +32255,8 @@ function initializeGraphState(params) {
32226
32255
  return _extends({}, shared, {
32227
32256
  type: graph.type,
32228
32257
  coords: getPointCoords(graph, range, step),
32229
- numPoints: graph.numPoints || 0
32258
+ numPoints: graph.numPoints || 0,
32259
+ focusedPointIndex: null
32230
32260
  });
32231
32261
  case "circle":
32232
32262
  return _extends({}, shared, {
@@ -32484,10 +32514,47 @@ function interactiveGraphReducer(state, action) {
32484
32514
  return doAddPoint(state, action);
32485
32515
  case REMOVE_POINT:
32486
32516
  return doRemovePoint(state, action);
32517
+ case FOCUS_POINT:
32518
+ return doFocusPoint(state, action);
32519
+ case BLUR_POINT:
32520
+ return doBlurPoint(state);
32521
+ case DELETE_INTENT:
32522
+ return doDeleteIntent(state);
32487
32523
  default:
32488
32524
  throw new UnreachableCaseError(action);
32489
32525
  }
32490
32526
  }
32527
+ function doDeleteIntent(state, action) {
32528
+ // For unlimited point graphs
32529
+ if (state.type === "point" && state.numPoints === "unlimited") {
32530
+ // if there's a focused point
32531
+ if (state.focusedPointIndex !== null) {
32532
+ // Remove the focused focus
32533
+ return doRemovePoint(state, actions.pointGraph.removePoint(state.focusedPointIndex));
32534
+ }
32535
+ }
32536
+ return state;
32537
+ }
32538
+ function doFocusPoint(state, action) {
32539
+ switch (state.type) {
32540
+ case "point":
32541
+ return _extends({}, state, {
32542
+ focusedPointIndex: action.index
32543
+ });
32544
+ default:
32545
+ return state;
32546
+ }
32547
+ }
32548
+ function doBlurPoint(state, action) {
32549
+ switch (state.type) {
32550
+ case "point":
32551
+ return _extends({}, state, {
32552
+ focusedPointIndex: null
32553
+ });
32554
+ default:
32555
+ return state;
32556
+ }
32557
+ }
32491
32558
  function doMovePointInFigure(state, action) {
32492
32559
  switch (state.type) {
32493
32560
  case "segment":
@@ -32836,7 +32903,8 @@ function doRemovePoint(state, action) {
32836
32903
  return state;
32837
32904
  }
32838
32905
  return _extends({}, state, {
32839
- coords: state.coords.filter((_, i) => i !== action.index)
32906
+ coords: state.coords.filter((_, i) => i !== action.index),
32907
+ focusedPointIndex: null
32840
32908
  });
32841
32909
  }
32842
32910
  const getDeltaVertex = (maxMoves, minMoves, delta) => {
@@ -37278,6 +37346,27 @@ class Draggable extends React.Component {
37278
37346
  passive: false
37279
37347
  } : false);
37280
37348
  }
37349
+ componentDidUpdate(prevProps) {
37350
+ if (this.props.state === prevProps.state) {
37351
+ return;
37352
+ }
37353
+ if (this.props.state === ItemState.ANIMATING && this.props.endPosition) {
37354
+ // Start animating
37355
+ const current = this.getCurrentPosition();
37356
+ const duration = 15 * Math.sqrt(Math.sqrt(Math.pow(this.props.endPosition.left - current.left, 2) + Math.pow(this.props.endPosition.top - current.top, 2)));
37357
+
37358
+ // @ts-expect-error - TS2769 - No overload matches this call. | TS2339 - Property 'animate' does not exist on type 'JQueryStatic'.
37359
+ $(ReactDOM__default.findDOMNode(this)).animate(this.props.endPosition, {
37360
+ duration: Math.max(duration, 1),
37361
+ // Animating -> Static
37362
+ complete: this.props.onAnimationEnd
37363
+ });
37364
+ } else if (this.props.state === ItemState.STATIC) {
37365
+ // Ensure that any animations are done
37366
+ // @ts-expect-error - TS2769 - No overload matches this call. | TS2339 - Property 'finish' does not exist on type 'JQueryStatic'.
37367
+ $(ReactDOM__default.findDOMNode(this)).finish();
37368
+ }
37369
+ }
37281
37370
  componentWillUnmount() {
37282
37371
  this._mounted = false;
37283
37372
  // Event handlers should be unbound before component unmounting, but
@@ -37339,27 +37428,6 @@ class Draggable extends React.Component {
37339
37428
  strings: this.context.strings
37340
37429
  }));
37341
37430
  }
37342
- componentDidUpdate(prevProps) {
37343
- if (this.props.state === prevProps.state) {
37344
- return;
37345
- }
37346
- if (this.props.state === ItemState.ANIMATING && this.props.endPosition) {
37347
- // Start animating
37348
- const current = this.getCurrentPosition();
37349
- const duration = 15 * Math.sqrt(Math.sqrt(Math.pow(this.props.endPosition.left - current.left, 2) + Math.pow(this.props.endPosition.top - current.top, 2)));
37350
-
37351
- // @ts-expect-error - TS2769 - No overload matches this call. | TS2339 - Property 'animate' does not exist on type 'JQueryStatic'.
37352
- $(ReactDOM__default.findDOMNode(this)).animate(this.props.endPosition, {
37353
- duration: Math.max(duration, 1),
37354
- // Animating -> Static
37355
- complete: this.props.onAnimationEnd
37356
- });
37357
- } else if (this.props.state === ItemState.STATIC) {
37358
- // Ensure that any animations are done
37359
- // @ts-expect-error - TS2769 - No overload matches this call. | TS2339 - Property 'finish' does not exist on type 'JQueryStatic'.
37360
- $(ReactDOM__default.findDOMNode(this)).finish();
37361
- }
37362
- }
37363
37431
  }
37364
37432
  Draggable.contextType = PerseusI18nContext;
37365
37433
  Draggable.defaultProps = {
@@ -37368,6 +37436,26 @@ Draggable.defaultProps = {
37368
37436
  linterContext: PerseusLinter.linterContextDefault
37369
37437
  };
37370
37438
  class Sortable extends React.Component {
37439
+ static itemsFromProps(props) {
37440
+ const state = props.disabled ? ItemState.DISABLED : ItemState.STATIC;
37441
+ return props.options.map((option, i) => {
37442
+ return {
37443
+ option: option,
37444
+ key: i,
37445
+ state,
37446
+ width: 0,
37447
+ height: 0
37448
+ };
37449
+ });
37450
+ }
37451
+ static clearItemMeasurements(items) {
37452
+ return items.map(item => {
37453
+ return _extends({}, item, {
37454
+ width: 0,
37455
+ height: 0
37456
+ });
37457
+ });
37458
+ }
37371
37459
  constructor(props) {
37372
37460
  super(props);
37373
37461
  // Don't call this.setState() here!
@@ -37407,26 +37495,6 @@ class Sortable extends React.Component {
37407
37495
  }, 0);
37408
37496
  }
37409
37497
  }
37410
- static itemsFromProps(props) {
37411
- const state = props.disabled ? ItemState.DISABLED : ItemState.STATIC;
37412
- return props.options.map((option, i) => {
37413
- return {
37414
- option: option,
37415
- key: i,
37416
- state,
37417
- width: 0,
37418
- height: 0
37419
- };
37420
- });
37421
- }
37422
- static clearItemMeasurements(items) {
37423
- return items.map(item => {
37424
- return _extends({}, item, {
37425
- width: 0,
37426
- height: 0
37427
- });
37428
- });
37429
- }
37430
37498
  measureItems() {
37431
37499
  // Measure all items and cache what their dimensions should be, taking
37432
37500
  // into account constraints and the current layout. This allows syncing
@@ -37478,124 +37546,6 @@ class Sortable extends React.Component {
37478
37546
  });
37479
37547
  });
37480
37548
  }
37481
- render() {
37482
- var _this$props$constrain, _this$props$constrain2;
37483
- // To minimize layout shift, we display a spinner until our math
37484
- // renderer is ready to render the math inside the sortable. To
37485
- // do this, we:
37486
- // - render a dummy TeX component to force the math renderer to load
37487
- // - display a spinner until the TeX component calls its onRender
37488
- // callback, signifying that the math is rendered (from which we can
37489
- // infer that the math renderer has loaded)
37490
- //
37491
- // If we didn't do this, the user might see a sortable with empty
37492
- // cells on first render, and then the math would pop in a few moments
37493
- // later once the rendering library loaded.
37494
- if (this.props.waitForTexRendererToLoad && !this.state.texRendererLoaded) {
37495
- const {
37496
- TeX
37497
- } = getDependencies();
37498
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CircularSpinner, null), /*#__PURE__*/React.createElement("div", {
37499
- style: {
37500
- display: "none"
37501
- }
37502
- }, /*#__PURE__*/React.createElement(TeX, {
37503
- onRender: () => this.setState({
37504
- texRendererLoaded: true
37505
- })
37506
- }, "1")));
37507
- }
37508
- const cards = [];
37509
- const {
37510
- layout
37511
- } = this.props;
37512
- // We need to keep backwards compatbility with rules specified directly
37513
- // in CSS. See sortable.less for details.
37514
- const className = css(styles$d.sortable) + " perseus-sortable";
37515
- const syncWidth = ((_this$props$constrain = this.props.constraints) == null ? void 0 : _this$props$constrain.width) || layout === Layout.VERTICAL;
37516
- const syncHeight = ((_this$props$constrain2 = this.props.constraints) == null ? void 0 : _this$props$constrain2.height) || layout === Layout.HORIZONTAL;
37517
- _.each(this.state.items, function (item, i, items) {
37518
- const isLast = i === items.length - 1;
37519
- const isStatic = item.state === ItemState.STATIC || item.state === ItemState.DISABLED;
37520
- let margin;
37521
-
37522
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37523
- if (this.props.layout === Layout.HORIZONTAL) {
37524
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37525
- margin = "0 " + this.props.margin + "px 0 0"; // right
37526
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37527
- } else if (this.props.layout === Layout.VERTICAL) {
37528
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37529
- margin = "0 0 " + this.props.margin + "px 0"; // bottom
37530
- }
37531
-
37532
- cards.push( /*#__PURE__*/React.createElement(Draggable, {
37533
- content: item.option,
37534
- key: item.key,
37535
- state: item.state
37536
- // @ts-expect-error - TS2769 - No overload matches this call.
37537
- ,
37538
- ref: item.key,
37539
- width: syncWidth ? item.width : undefined,
37540
- height: syncHeight ? item.height : undefined,
37541
- layout: layout
37542
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37543
- ,
37544
- includePadding: this.props.padding,
37545
- margin: isLast && isStatic ? 0 : margin,
37546
- endPosition: item.endPosition,
37547
- linterContext: PerseusLinter.pushContextStack(
37548
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37549
- this.props.linterContext, "sortable")
37550
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37551
- ,
37552
- onRender: this.remeasureItems
37553
- // eslint-disable-next-line react/jsx-no-bind
37554
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37555
- ,
37556
- onMouseDown: this.onMouseDown.bind(this, item.key)
37557
- // eslint-disable-next-line react/jsx-no-bind
37558
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37559
- ,
37560
- onMouseMove: this.onMouseMove.bind(this, item.key)
37561
- // eslint-disable-next-line react/jsx-no-bind
37562
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37563
- ,
37564
- onMouseUp: this.onMouseUp.bind(this, item.key)
37565
- // eslint-disable-next-line react/jsx-no-bind
37566
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37567
- ,
37568
- onTouchMove: this.onMouseMove.bind(this, item.key)
37569
- // eslint-disable-next-line react/jsx-no-bind
37570
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37571
- ,
37572
- onTouchEnd: this.onMouseUp.bind(this, item.key)
37573
- // eslint-disable-next-line react/jsx-no-bind
37574
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37575
- ,
37576
- onTouchCancel: this.onMouseUp.bind(this, item.key)
37577
- // eslint-disable-next-line react/jsx-no-bind
37578
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37579
- ,
37580
- onAnimationEnd: this.onAnimationEnd.bind(
37581
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37582
- this, item.key)
37583
- }));
37584
- if (item.state === ItemState.DRAGGING || item.state === ItemState.ANIMATING) {
37585
- cards.push( /*#__PURE__*/React.createElement(Placeholder, {
37586
- key: "placeholder_" + item.key,
37587
- ref: "placeholder_" + item.key,
37588
- width: item.width,
37589
- height: item.height,
37590
- layout: layout,
37591
- margin: isLast ? 0 : margin
37592
- }));
37593
- }
37594
- }, this);
37595
- return /*#__PURE__*/React.createElement("ul", {
37596
- className: className
37597
- }, cards);
37598
- }
37599
37549
  onMouseDown(key) {
37600
37550
  // Static -> Dragging
37601
37551
  const items = _.map(this.state.items, function (item) {
@@ -37723,23 +37673,141 @@ class Sortable extends React.Component {
37723
37673
  this.props.onChange && this.props.onChange({});
37724
37674
  });
37725
37675
 
37726
- // @ts-expect-error - TS2339 - Property 'animationFrameRequest' does not exist on type 'Sortable'.
37727
- this.animationFrameRequest = nextAnimationFrame;
37728
- }
37729
- onAnimationEnd(key) {
37730
- // Animating -> Static
37731
- const items = _.map(this.state.items, function (item) {
37732
- if (item.key === key) {
37733
- item.state = ItemState.STATIC;
37676
+ // @ts-expect-error - TS2339 - Property 'animationFrameRequest' does not exist on type 'Sortable'.
37677
+ this.animationFrameRequest = nextAnimationFrame;
37678
+ }
37679
+ onAnimationEnd(key) {
37680
+ // Animating -> Static
37681
+ const items = _.map(this.state.items, function (item) {
37682
+ if (item.key === key) {
37683
+ item.state = ItemState.STATIC;
37684
+ }
37685
+ return item;
37686
+ });
37687
+ this.setState({
37688
+ items: items
37689
+ });
37690
+ }
37691
+ getOptions() {
37692
+ return _.pluck(this.state.items, "option");
37693
+ }
37694
+ render() {
37695
+ var _this$props$constrain, _this$props$constrain2;
37696
+ // To minimize layout shift, we display a spinner until our math
37697
+ // renderer is ready to render the math inside the sortable. To
37698
+ // do this, we:
37699
+ // - render a dummy TeX component to force the math renderer to load
37700
+ // - display a spinner until the TeX component calls its onRender
37701
+ // callback, signifying that the math is rendered (from which we can
37702
+ // infer that the math renderer has loaded)
37703
+ //
37704
+ // If we didn't do this, the user might see a sortable with empty
37705
+ // cells on first render, and then the math would pop in a few moments
37706
+ // later once the rendering library loaded.
37707
+ if (this.props.waitForTexRendererToLoad && !this.state.texRendererLoaded) {
37708
+ const {
37709
+ TeX
37710
+ } = getDependencies();
37711
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CircularSpinner, null), /*#__PURE__*/React.createElement("div", {
37712
+ style: {
37713
+ display: "none"
37714
+ }
37715
+ }, /*#__PURE__*/React.createElement(TeX, {
37716
+ onRender: () => this.setState({
37717
+ texRendererLoaded: true
37718
+ })
37719
+ }, "1")));
37720
+ }
37721
+ const cards = [];
37722
+ const {
37723
+ layout
37724
+ } = this.props;
37725
+ // We need to keep backwards compatbility with rules specified directly
37726
+ // in CSS. See sortable.less for details.
37727
+ const className = css(styles$d.sortable) + " perseus-sortable";
37728
+ const syncWidth = ((_this$props$constrain = this.props.constraints) == null ? void 0 : _this$props$constrain.width) || layout === Layout.VERTICAL;
37729
+ const syncHeight = ((_this$props$constrain2 = this.props.constraints) == null ? void 0 : _this$props$constrain2.height) || layout === Layout.HORIZONTAL;
37730
+ _.each(this.state.items, function (item, i, items) {
37731
+ const isLast = i === items.length - 1;
37732
+ const isStatic = item.state === ItemState.STATIC || item.state === ItemState.DISABLED;
37733
+ let margin;
37734
+
37735
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37736
+ if (this.props.layout === Layout.HORIZONTAL) {
37737
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37738
+ margin = "0 " + this.props.margin + "px 0 0"; // right
37739
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37740
+ } else if (this.props.layout === Layout.VERTICAL) {
37741
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37742
+ margin = "0 0 " + this.props.margin + "px 0"; // bottom
37743
+ }
37744
+
37745
+ cards.push( /*#__PURE__*/React.createElement(Draggable, {
37746
+ content: item.option,
37747
+ key: item.key,
37748
+ state: item.state
37749
+ // @ts-expect-error - TS2769 - No overload matches this call.
37750
+ ,
37751
+ ref: item.key,
37752
+ width: syncWidth ? item.width : undefined,
37753
+ height: syncHeight ? item.height : undefined,
37754
+ layout: layout
37755
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37756
+ ,
37757
+ includePadding: this.props.padding,
37758
+ margin: isLast && isStatic ? 0 : margin,
37759
+ endPosition: item.endPosition,
37760
+ linterContext: PerseusLinter.pushContextStack(
37761
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37762
+ this.props.linterContext, "sortable")
37763
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37764
+ ,
37765
+ onRender: this.remeasureItems
37766
+ // eslint-disable-next-line react/jsx-no-bind
37767
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37768
+ ,
37769
+ onMouseDown: this.onMouseDown.bind(this, item.key)
37770
+ // eslint-disable-next-line react/jsx-no-bind
37771
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37772
+ ,
37773
+ onMouseMove: this.onMouseMove.bind(this, item.key)
37774
+ // eslint-disable-next-line react/jsx-no-bind
37775
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37776
+ ,
37777
+ onMouseUp: this.onMouseUp.bind(this, item.key)
37778
+ // eslint-disable-next-line react/jsx-no-bind
37779
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37780
+ ,
37781
+ onTouchMove: this.onMouseMove.bind(this, item.key)
37782
+ // eslint-disable-next-line react/jsx-no-bind
37783
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37784
+ ,
37785
+ onTouchEnd: this.onMouseUp.bind(this, item.key)
37786
+ // eslint-disable-next-line react/jsx-no-bind
37787
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37788
+ ,
37789
+ onTouchCancel: this.onMouseUp.bind(this, item.key)
37790
+ // eslint-disable-next-line react/jsx-no-bind
37791
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37792
+ ,
37793
+ onAnimationEnd: this.onAnimationEnd.bind(
37794
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
37795
+ this, item.key)
37796
+ }));
37797
+ if (item.state === ItemState.DRAGGING || item.state === ItemState.ANIMATING) {
37798
+ cards.push( /*#__PURE__*/React.createElement(Placeholder, {
37799
+ key: "placeholder_" + item.key,
37800
+ ref: "placeholder_" + item.key,
37801
+ width: item.width,
37802
+ height: item.height,
37803
+ layout: layout,
37804
+ margin: isLast ? 0 : margin
37805
+ }));
37734
37806
  }
37735
- return item;
37736
- });
37737
- this.setState({
37738
- items: items
37739
- });
37740
- }
37741
- getOptions() {
37742
- return _.pluck(this.state.items, "option");
37807
+ }, this);
37808
+ return /*#__PURE__*/React.createElement("ul", {
37809
+ className: className
37810
+ }, cards);
37743
37811
  }
37744
37812
  }
37745
37813
  Sortable.defaultProps = {
@@ -38504,7 +38572,7 @@ var Matrix$1 = {
38504
38572
  isLintable: true
38505
38573
  };
38506
38574
 
38507
- /* eslint-disable @babel/no-invalid-this, react/sort-comp */
38575
+ /* eslint-disable @babel/no-invalid-this */
38508
38576
  const defaultImage = {
38509
38577
  url: null,
38510
38578
  top: 0,
@@ -38546,30 +38614,6 @@ const Measurer = createReactClass({
38546
38614
  getInitialState: function () {
38547
38615
  return {};
38548
38616
  },
38549
- render: function () {
38550
- const image = _.extend({}, defaultImage, this.props.image);
38551
-
38552
- // TODO(scottgrant): This isn't a11y-friendly! We should insist on
38553
- // finding some valid alt text when this widget is used.
38554
- return /*#__PURE__*/React.createElement("div", {
38555
- className: "perseus-widget perseus-widget-measurer " + "graphie-container above-scratchpad",
38556
- style: {
38557
- width: this.props.box[0],
38558
- height: this.props.box[1]
38559
- }
38560
- }, image.url && /*#__PURE__*/React.createElement("div", {
38561
- style: {
38562
- position: "relative",
38563
- top: image.top,
38564
- left: image.left
38565
- }
38566
- }, /*#__PURE__*/React.createElement(SvgImage, {
38567
- src: image.url
38568
- })), /*#__PURE__*/React.createElement("div", {
38569
- className: "graphie",
38570
- ref: "graphieDiv"
38571
- }));
38572
- },
38573
38617
  componentDidMount: function () {
38574
38618
  this.setupGraphie();
38575
38619
  },
@@ -38627,7 +38671,31 @@ const Measurer = createReactClass({
38627
38671
  // TODO(joel) - I don't understand how this is useful!
38628
38672
  return Measurer.validate(this.getUserInput(), rubric);
38629
38673
  },
38630
- focus: $.noop
38674
+ focus: $.noop,
38675
+ render: function () {
38676
+ const image = _.extend({}, defaultImage, this.props.image);
38677
+
38678
+ // TODO(scottgrant): This isn't a11y-friendly! We should insist on
38679
+ // finding some valid alt text when this widget is used.
38680
+ return /*#__PURE__*/React.createElement("div", {
38681
+ className: "perseus-widget perseus-widget-measurer " + "graphie-container above-scratchpad",
38682
+ style: {
38683
+ width: this.props.box[0],
38684
+ height: this.props.box[1]
38685
+ }
38686
+ }, image.url && /*#__PURE__*/React.createElement("div", {
38687
+ style: {
38688
+ position: "relative",
38689
+ top: image.top,
38690
+ left: image.left
38691
+ }
38692
+ }, /*#__PURE__*/React.createElement(SvgImage, {
38693
+ src: image.url
38694
+ })), /*#__PURE__*/React.createElement("div", {
38695
+ className: "graphie",
38696
+ ref: "graphieDiv"
38697
+ }));
38698
+ }
38631
38699
  });
38632
38700
  _.extend(Measurer, {
38633
38701
  validate: function (state, rubric) {
@@ -40228,55 +40296,6 @@ class Card extends React.Component {
40228
40296
  }
40229
40297
  };
40230
40298
  }
40231
- render() {
40232
- let style = {};
40233
- if (this.props.floating) {
40234
- style = {
40235
- position: "absolute",
40236
- left: this.props.startOffset.left,
40237
- top: this.props.startOffset.top
40238
- };
40239
- }
40240
- if (this.props.width) {
40241
- style.width = this.props.width;
40242
- }
40243
- const className = ["card"];
40244
- if (this.props.stack) {
40245
- className.push("stack");
40246
- }
40247
- if (this.props.floating && !this.props.animating) {
40248
- className.push("dragging");
40249
- style.left += this.props.mouse.left - this.props.startMouse.left;
40250
- style.top += this.props.mouse.top - this.props.startMouse.top;
40251
- }
40252
-
40253
- // Pull out the content to get rendered
40254
- const rendererProps = _.pick(this.props, "content");
40255
- const onMouseDown = this.props.animating ? $.noop : this.onMouseDown;
40256
- return /*#__PURE__*/React.createElement("div", {
40257
- className: "card-wrap " + ClassNames.INTERACTIVE,
40258
- style: style,
40259
- onMouseDown: onMouseDown,
40260
- onTouchStart: onMouseDown,
40261
- onTouchEnd: this.onMouseUp,
40262
- onTouchCancel: this.onMouseUp
40263
- }, /*#__PURE__*/React.createElement("div", {
40264
- className: className.join(" ")
40265
- }, /*#__PURE__*/React.createElement(Renderer, _extends({}, rendererProps, {
40266
- linterContext: this.props.linterContext,
40267
- strings: this.context.strings
40268
- }))));
40269
- }
40270
- shouldComponentUpdate(nextProps, nextState) {
40271
- // Cards in the bank or drag list don't usually change -- they only
40272
- // reorder themselves -- so we want to skip the update to things a
40273
- // little faster. We also need to re-render if the content changes,
40274
- // which happens only in the editor. (We do want to update the floating
40275
- // card on mouse move to update its position.)
40276
- return this.props.floating || nextProps.floating || this.props.content !== nextProps.content ||
40277
- // TODO(alpert): Remove ref here after fixing facebook/react#1392.
40278
- this.props.fakeRef !== nextProps.fakeRef;
40279
- }
40280
40299
  componentDidMount() {
40281
40300
  this.mouseMoveUpBound = false;
40282
40301
 
@@ -40295,6 +40314,16 @@ class Card extends React.Component {
40295
40314
  passive: false
40296
40315
  } : false);
40297
40316
  }
40317
+ shouldComponentUpdate(nextProps, nextState) {
40318
+ // Cards in the bank or drag list don't usually change -- they only
40319
+ // reorder themselves -- so we want to skip the update to things a
40320
+ // little faster. We also need to re-render if the content changes,
40321
+ // which happens only in the editor. (We do want to update the floating
40322
+ // card on mouse move to update its position.)
40323
+ return this.props.floating || nextProps.floating || this.props.content !== nextProps.content ||
40324
+ // TODO(alpert): Remove ref here after fixing facebook/react#1392.
40325
+ this.props.fakeRef !== nextProps.fakeRef;
40326
+ }
40298
40327
  componentDidUpdate(prevProps, prevState) {
40299
40328
  if (this.props.animating && !prevProps.animating) {
40300
40329
  // If we just were changed into animating, start the animation.
@@ -40316,6 +40345,45 @@ class Card extends React.Component {
40316
40345
  }
40317
40346
  document.removeEventListener("touchmove", this.onMouseMove);
40318
40347
  }
40348
+ render() {
40349
+ let style = {};
40350
+ if (this.props.floating) {
40351
+ style = {
40352
+ position: "absolute",
40353
+ left: this.props.startOffset.left,
40354
+ top: this.props.startOffset.top
40355
+ };
40356
+ }
40357
+ if (this.props.width) {
40358
+ style.width = this.props.width;
40359
+ }
40360
+ const className = ["card"];
40361
+ if (this.props.stack) {
40362
+ className.push("stack");
40363
+ }
40364
+ if (this.props.floating && !this.props.animating) {
40365
+ className.push("dragging");
40366
+ style.left += this.props.mouse.left - this.props.startMouse.left;
40367
+ style.top += this.props.mouse.top - this.props.startMouse.top;
40368
+ }
40369
+
40370
+ // Pull out the content to get rendered
40371
+ const rendererProps = _.pick(this.props, "content");
40372
+ const onMouseDown = this.props.animating ? $.noop : this.onMouseDown;
40373
+ return /*#__PURE__*/React.createElement("div", {
40374
+ className: "card-wrap " + ClassNames.INTERACTIVE,
40375
+ style: style,
40376
+ onMouseDown: onMouseDown,
40377
+ onTouchStart: onMouseDown,
40378
+ onTouchEnd: this.onMouseUp,
40379
+ onTouchCancel: this.onMouseUp
40380
+ }, /*#__PURE__*/React.createElement("div", {
40381
+ className: className.join(" ")
40382
+ }, /*#__PURE__*/React.createElement(Renderer, _extends({}, rendererProps, {
40383
+ linterContext: this.props.linterContext,
40384
+ strings: this.context.strings
40385
+ }))));
40386
+ }
40319
40387
  }
40320
40388
  Card.contextType = PerseusI18nContext;
40321
40389
  Card.propTypes = {
@@ -41522,7 +41590,6 @@ class HighlightSetRenderer extends React.PureComponent {
41522
41590
  hoveredHighlightKey: null,
41523
41591
  hoveringTooltipFor: null
41524
41592
  };
41525
- // eslint-disable-next-line react/sort-comp
41526
41593
  this._highlightRenderers = {};
41527
41594
  this._handleMouseMove = e => {
41528
41595
  const mouseClientPosition = {
@@ -41866,8 +41933,6 @@ class WordIndexer extends React.PureComponent {
41866
41933
  super(...args);
41867
41934
  this._container = void 0;
41868
41935
  }
41869
- /* eslint-enable react/sort-comp */
41870
-
41871
41936
  componentDidMount() {
41872
41937
  this._sendWordsUpdate();
41873
41938
  }
@@ -42537,6 +42602,14 @@ class Passage extends React.Component {
42537
42602
  });
42538
42603
  };
42539
42604
  }
42605
+ static validate(state, rubric) {
42606
+ return {
42607
+ type: "points",
42608
+ earned: 0,
42609
+ total: 0,
42610
+ message: null
42611
+ };
42612
+ }
42540
42613
  componentDidMount() {
42541
42614
  this._updateState();
42542
42615
 
@@ -42754,17 +42827,6 @@ class Passage extends React.Component {
42754
42827
  return Passage.validate(this.getUserInput(), rubric);
42755
42828
  }
42756
42829
 
42757
- /* eslint-disable react/sort-comp */
42758
- static validate(state, rubric) {
42759
- return {
42760
- type: "points",
42761
- earned: 0,
42762
- total: 0,
42763
- message: null
42764
- };
42765
- }
42766
- /* eslint-enable react/sort-comp */
42767
-
42768
42830
  /**
42769
42831
  * Rendering
42770
42832
  *
@@ -42994,14 +43056,6 @@ class PhetSimulation extends React.Component {
42994
43056
  url: null,
42995
43057
  banner: null
42996
43058
  };
42997
- this.change = (...args) => {
42998
- // @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
42999
- return change.apply(this, args);
43000
- };
43001
- this.simpleValidate = rubric => {
43002
- // @ts-expect-error - TS2339 - Property 'validate' does not exist on type 'typeof PhetSimulation'.
43003
- return PhetSimulation.validate(this.getUserInput(), rubric);
43004
- };
43005
43059
  // kaLocales and PhET locales use different formats and abbreviations.
43006
43060
  // PhET accepts different formats, i.e. kaLocale's hyphens, but it does not accept
43007
43061
  // different abbreviations, so in points of divergence of abbreviations, we need to
@@ -43124,8 +43178,7 @@ class PhetSimulation extends React.Component {
43124
43178
  title: this.props.description,
43125
43179
  sandbox: sandboxProperties,
43126
43180
  style: {
43127
- minWidth: 400,
43128
- height: 360,
43181
+ height: 225,
43129
43182
  width: "100%",
43130
43183
  borderWidth: 0
43131
43184
  },
@@ -43167,17 +43220,16 @@ const styles$6 = StyleSheet.create({
43167
43220
  borderRadius: borderRadiusLarge,
43168
43221
  borderWidth: 1,
43169
43222
  borderColor: basicBorderColor,
43170
- padding: phoneMargin,
43223
+ padding: spacing.medium_16,
43171
43224
  paddingBottom: 0,
43172
- width: 650
43225
+ // Include space for medium_16 padding on each side
43226
+ width: 400 + spacing.xLarge_32
43173
43227
  }
43174
43228
  });
43175
43229
  var PhetSimulation$1 = {
43176
43230
  name: "phet-simulation",
43177
43231
  displayName: "PhET Simulation",
43178
43232
  widget: PhetSimulation,
43179
- // Hides widget from content creators until full release
43180
- hidden: true,
43181
43233
  isLintable: true
43182
43234
  };
43183
43235
 
@@ -44685,7 +44737,7 @@ const init = function init(options) {
44685
44737
 
44686
44738
  // This file is processed by a Rollup plugin (replace) to inject the production
44687
44739
  const libName = "@khanacademy/perseus";
44688
- const libVersion = "31.1.0";
44740
+ const libVersion = "32.0.0";
44689
44741
  addLibraryVersionToPerseusDebug(libName, libVersion);
44690
44742
 
44691
44743
  const apiVersion = {
@@ -46498,8 +46550,6 @@ class MultiRenderer extends React.Component {
46498
46550
  // Keep state in sync with props.
46499
46551
  this.state = this._tryMakeRendererState(this.props);
46500
46552
  }
46501
- /* eslint-enable react/sort-comp */
46502
-
46503
46553
  UNSAFE_componentWillReceiveProps(nextProps) {
46504
46554
  // Keep state in sync with props.
46505
46555
  if (nextProps.item !== this.props.item) {
@@ -48272,5 +48322,5 @@ const EditorJsonify = {
48272
48322
  }
48273
48323
  };
48274
48324
 
48275
- export { ApiOptions, ArrowPicker, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, ColorPicker, DashPicker, dependencies as Dependencies, EditorJsonify, ElementContainer, Expression, util as GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, sizingUtils as SizingUtils, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, WidgetJsonifyDeprecated, widgets$1 as Widgets, addWidget, apiVersion, buildEmptyItemTreeForShape, buildMapper, components, constants, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAngleCoords, getAnswerFromUserInput, getAnswersFromWidgets, getCircleCoords, getCorrectAnswerForWidgetId, getLineCoords, getLinearSystemCoords, getPointCoords, getPolygonCoords, getQuadraticCoords, getSegmentCoords, getSinusoidCoords, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, globalConstants, globalStyles, iconPaths as icons, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedFigureColors, lockedFigureFillStyles, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
48325
+ export { ApiOptions, ArrowPicker, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, ColorPicker, DashPicker, dependencies as Dependencies, EditorJsonify, ElementContainer, Expression, util as GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, sizingUtils as SizingUtils, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, WidgetJsonifyDeprecated, widgets$1 as Widgets, addWidget, apiVersion, buildEmptyItemTreeForShape, buildMapper, components, constants, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAngleCoords, getAnswerFromUserInput, getAnswersFromWidgets, getCircleCoords, getCorrectAnswerForWidgetId, getLineCoords, getLinearSystemCoords, getPointCoords, getPolygonCoords, getQuadraticCoords, getSegmentCoords, getSinusoidCoords, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, globalConstants, globalStyles, iconPaths as icons, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedFigureColors, lockedFigureFillStyles, makeSafeUrl, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
48276
48326
  //# sourceMappingURL=index.js.map