@khanacademy/perseus 20.0.1 → 20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -29,11 +29,13 @@ var Button = require('@khanacademy/wonder-blocks-button');
29
29
  var wonderBlocksLayout = require('@khanacademy/wonder-blocks-layout');
30
30
  var Banner = require('@khanacademy/wonder-blocks-banner');
31
31
  var wonderBlocksDropdown = require('@khanacademy/wonder-blocks-dropdown');
32
- var debounce = require('lodash.debounce');
32
+ var debounce$1 = require('lodash.debounce');
33
33
  var mafs = require('mafs');
34
+ var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
35
+ var questionIcon = require('@phosphor-icons/core/regular/question.svg');
36
+ var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
34
37
  var createReactClass = require('create-react-class');
35
38
  var Switch = require('@khanacademy/wonder-blocks-switch');
36
- var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
37
39
  var Pill = require('@khanacademy/wonder-blocks-pill');
38
40
  var reactPopper = require('react-popper');
39
41
  var Link = require('@khanacademy/wonder-blocks-link');
@@ -77,7 +79,8 @@ var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
77
79
  var SimpleMarkdown__default = /*#__PURE__*/_interopDefaultLegacy(SimpleMarkdown);
78
80
  var Button__default = /*#__PURE__*/_interopDefaultLegacy(Button);
79
81
  var Banner__default = /*#__PURE__*/_interopDefaultLegacy(Banner);
80
- var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
82
+ var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce$1);
83
+ var questionIcon__default = /*#__PURE__*/_interopDefaultLegacy(questionIcon);
81
84
  var createReactClass__default = /*#__PURE__*/_interopDefaultLegacy(createReactClass);
82
85
  var Switch__default = /*#__PURE__*/_interopDefaultLegacy(Switch);
83
86
  var Pill__default = /*#__PURE__*/_interopDefaultLegacy(Pill);
@@ -98,6 +101,21 @@ function _extends() {
98
101
  return _extends.apply(this, arguments);
99
102
  }
100
103
 
104
+ const debounce = (func, delay) => {
105
+ let timer = null;
106
+ return function () {
107
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
108
+ args[_key] = arguments[_key];
109
+ }
110
+ if (timer) {
111
+ clearTimeout(timer);
112
+ }
113
+ timer = window.setTimeout(() => {
114
+ func(...args);
115
+ }, delay);
116
+ };
117
+ };
118
+
101
119
  const customKeyTranslator = {
102
120
  ...mathInput.keyTranslator,
103
121
  // If there's something in the input that can become part of a
@@ -173,7 +191,7 @@ class MathInput extends React__namespace.Component {
173
191
  this.__mathField = mathInput.createMathField(this.__mathFieldWrapperRef, baseConfig => ({
174
192
  ...baseConfig,
175
193
  handlers: {
176
- edit: mathField => {
194
+ edit: debounce(mathField => {
177
195
  // This handler is guaranteed to be called on change, but
178
196
  // unlike React it sometimes generates false positives.
179
197
  // One of these is on initialization (with an empty string
@@ -209,7 +227,7 @@ class MathInput extends React__namespace.Component {
209
227
  this.setState({
210
228
  cursorContext: mathInput.getCursorContext(mathField)
211
229
  });
212
- },
230
+ }, 100),
213
231
  enter: () => {
214
232
  // NOTE(kevinb): This isn't how answers to exercises are
215
233
  // submitted. The actual mechanism for this can be found
@@ -279,7 +297,7 @@ class MathInput extends React__namespace.Component {
279
297
  className = className + " " + this.props.className;
280
298
  }
281
299
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
282
- style: [styles$C.outerWrapper, this.state.focused && styles$C.wrapperFocused, this.props.hasError && styles$C.wrapperError]
300
+ style: [styles$D.outerWrapper, this.state.focused && styles$D.wrapperFocused, this.props.hasError && styles$D.wrapperError]
283
301
  }, /*#__PURE__*/React__namespace.createElement("div", {
284
302
  style: {
285
303
  display: "flex",
@@ -310,7 +328,7 @@ class MathInput extends React__namespace.Component {
310
328
  dismissEnabled: true,
311
329
  content: () => /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContentCore, {
312
330
  closeButtonVisible: true,
313
- style: styles$C.popoverContent
331
+ style: styles$D.popoverContent
314
332
  }, /*#__PURE__*/React__namespace.createElement(mathInput.DesktopKeypad, _extends({
315
333
  onAnalyticsEvent: this.props.analytics.onAnalyticsEvent,
316
334
  extraKeys: this.props.extraKeys,
@@ -350,9 +368,9 @@ const MathInputIcon = _ref => {
350
368
  color = Color__default["default"].offBlack;
351
369
  break;
352
370
  }
353
- const dynamicClass = active || focused ? styles$C.iconActive : styles$C.iconInactive;
371
+ const dynamicClass = active || focused ? styles$D.iconActive : styles$D.iconInactive;
354
372
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
355
- style: [styles$C.iconContainer, dynamicClass]
373
+ style: [styles$D.iconContainer, dynamicClass]
356
374
  }, /*#__PURE__*/React__namespace.createElement("svg", {
357
375
  xmlns: "http://www.w3.org/2000/svg",
358
376
  width: "16",
@@ -397,7 +415,7 @@ const inputFocused = {
397
415
  borderColor: Color__default["default"].blue,
398
416
  margin: -1
399
417
  };
400
- const styles$C = aphrodite.StyleSheet.create({
418
+ const styles$D = aphrodite.StyleSheet.create({
401
419
  iconContainer: {
402
420
  display: "flex",
403
421
  justifyContent: "center",
@@ -17916,33 +17934,33 @@ class Lint extends React__namespace.Component {
17916
17934
  let warningText;
17917
17935
  let warningTextStyle;
17918
17936
  if (this.props.severity === Severity.Error) {
17919
- severityStyle = styles$B.indicatorError;
17937
+ severityStyle = styles$C.indicatorError;
17920
17938
  warningText = "Error";
17921
- warningTextStyle = styles$B.publishBlockingError;
17939
+ warningTextStyle = styles$C.publishBlockingError;
17922
17940
  } else if (this.props.severity === Severity.Warning) {
17923
- severityStyle = styles$B.indicatorWarning;
17941
+ severityStyle = styles$C.indicatorWarning;
17924
17942
  warningText = "Warning";
17925
- warningTextStyle = styles$B.warning;
17943
+ warningTextStyle = styles$C.warning;
17926
17944
  } else {
17927
- severityStyle = styles$B.indicatorGuideline;
17945
+ severityStyle = styles$C.indicatorGuideline;
17928
17946
  warningText = "Recommendation";
17929
- warningTextStyle = styles$B.warning;
17947
+ warningTextStyle = styles$C.warning;
17930
17948
  }
17931
17949
  return /*#__PURE__*/React__namespace.createElement("a", {
17932
17950
  href: `https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,
17933
17951
  target: "lint-help-window",
17934
17952
  className: aphrodite.css(style)
17935
17953
  }, /*#__PURE__*/React__namespace.createElement("span", {
17936
- className: aphrodite.css(styles$B.indicator, severityStyle)
17954
+ className: aphrodite.css(styles$C.indicator, severityStyle)
17937
17955
  }, this.props.severity === 1 && /*#__PURE__*/React__namespace.createElement(InlineIcon, exclamationIcon)), /*#__PURE__*/React__namespace.createElement("div", {
17938
- className: aphrodite.css(styles$B.tooltip, tooltipAbove && styles$B.tooltipAbove)
17956
+ className: aphrodite.css(styles$C.tooltip, tooltipAbove && styles$C.tooltipAbove)
17939
17957
  }, this.props.message.split("\n\n").map((m, i) => /*#__PURE__*/React__namespace.createElement("p", {
17940
17958
  key: i,
17941
- className: aphrodite.css(styles$B.tooltipParagraph)
17959
+ className: aphrodite.css(styles$C.tooltipParagraph)
17942
17960
  }, /*#__PURE__*/React__namespace.createElement("span", {
17943
17961
  className: aphrodite.css(warningTextStyle)
17944
17962
  }, warningText, ":", " "), m)), /*#__PURE__*/React__namespace.createElement("div", {
17945
- className: aphrodite.css(styles$B.tail, tooltipAbove && styles$B.tailAbove)
17963
+ className: aphrodite.css(styles$C.tail, tooltipAbove && styles$C.tailAbove)
17946
17964
  })));
17947
17965
  };
17948
17966
 
@@ -17970,20 +17988,20 @@ class Lint extends React__namespace.Component {
17970
17988
  }
17971
17989
  if (blockHighlight) {
17972
17990
  return /*#__PURE__*/React__namespace.createElement("span", {
17973
- className: aphrodite.css(styles$B.lintContainer, styles$B.lintContainerBlock)
17974
- }, this.renderLink(styles$B.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17991
+ className: aphrodite.css(styles$C.lintContainer, styles$C.lintContainerBlock)
17992
+ }, this.renderLink(styles$C.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17975
17993
  }
17976
17994
  if (inline) {
17977
17995
  return /*#__PURE__*/React__namespace.createElement("span", {
17978
- className: aphrodite.css(styles$B.lintContainer)
17979
- }, this.renderLink(styles$B.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17996
+ className: aphrodite.css(styles$C.lintContainer)
17997
+ }, this.renderLink(styles$C.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17980
17998
  }
17981
17999
  return /*#__PURE__*/React__namespace.createElement("div", {
17982
- className: aphrodite.css(styles$B.lintContainer)
17983
- }, this.renderLink(styles$B.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
18000
+ className: aphrodite.css(styles$C.lintContainer)
18001
+ }, this.renderLink(styles$C.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
17984
18002
  }
17985
18003
  }
17986
- const styles$B = aphrodite.StyleSheet.create({
18004
+ const styles$C = aphrodite.StyleSheet.create({
17987
18005
  // This is the class of the outermost element.
17988
18006
  // We use relative positioning so that the lint indicator can be
17989
18007
  // positioned absolutely relative to the position of the linty container.
@@ -20107,7 +20125,7 @@ class Renderer extends React__namespace.Component {
20107
20125
  };
20108
20126
  const mobileInnerStyle = {
20109
20127
  ...innerStyle,
20110
- ...styles$A.mobileZoomableParentFix
20128
+ ...styles$B.mobileZoomableParentFix
20111
20129
  };
20112
20130
  return /*#__PURE__*/React__namespace.createElement("div", {
20113
20131
  key: state.key,
@@ -20244,7 +20262,7 @@ class Renderer extends React__namespace.Component {
20244
20262
  };
20245
20263
  const mobileInnerStyle = {
20246
20264
  ...innerStyle,
20247
- ...styles$A.mobileZoomableParentFix
20265
+ ...styles$B.mobileZoomableParentFix
20248
20266
  };
20249
20267
  const wrappedOutput = /*#__PURE__*/React__namespace.createElement("div", {
20250
20268
  style: {
@@ -20752,7 +20770,7 @@ class Renderer extends React__namespace.Component {
20752
20770
  return this.lastRenderedMarkdown;
20753
20771
  }
20754
20772
  }
20755
- const styles$A = {
20773
+ const styles$B = {
20756
20774
  mobileZoomableParentFix: {
20757
20775
  // NOTE(abdul): There is an issue where transform animations will
20758
20776
  // cause the Zoomable component to disappear when running on the
@@ -21687,10 +21705,10 @@ class InputNumber extends React__namespace.Component {
21687
21705
  // Note: This is _very_ similar to what `numeric-input.jsx` does. If
21688
21706
  // you modify this, double-check if you also need to modify that
21689
21707
  // component.
21690
- const inputStyles = [styles$z.default, this.props.size === "small" ? styles$z.small : null, this.props.rightAlign ? styles$z.rightAlign : styles$z.leftAlign];
21708
+ const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
21691
21709
  // Unanswered
21692
21710
  if (rubric && !this.props.currentValue) {
21693
- inputStyles.push(styles$z.answerStateUnanswered);
21711
+ inputStyles.push(styles$A.answerStateUnanswered);
21694
21712
  }
21695
21713
  return /*#__PURE__*/React__namespace.createElement(InputWithExamples
21696
21714
  // eslint-disable-next-line react/no-string-refs
@@ -21829,7 +21847,7 @@ class InputNumber extends React__namespace.Component {
21829
21847
  return answerString;
21830
21848
  }
21831
21849
  }
21832
- const styles$z = aphrodite.StyleSheet.create({
21850
+ const styles$A = aphrodite.StyleSheet.create({
21833
21851
  default: {
21834
21852
  width: 80,
21835
21853
  height: "auto"
@@ -22818,7 +22836,7 @@ const FocusRing = function (props) {
22818
22836
  };
22819
22837
  return /*#__PURE__*/React__namespace.createElement("span", {
22820
22838
  "data-test-id": "focus-ring",
22821
- className: aphrodite.css(styles$y.ring),
22839
+ className: aphrodite.css(styles$z.ring),
22822
22840
  style: style
22823
22841
  }, children);
22824
22842
  };
@@ -22827,7 +22845,7 @@ FocusRing.defaultProps = {
22827
22845
  color: kaGreen$1,
22828
22846
  multipleSelect: false
22829
22847
  };
22830
- const styles$y = aphrodite.StyleSheet.create({
22848
+ const styles$z = aphrodite.StyleSheet.create({
22831
22849
  ring: {
22832
22850
  margin: "auto",
22833
22851
  display: "inline-block",
@@ -22864,7 +22882,7 @@ function getChoiceLetter(pos) {
22864
22882
  }
22865
22883
 
22866
22884
  const CHOICE_ICON_SIZE = 24;
22867
- const styles$x = aphrodite.StyleSheet.create({
22885
+ const styles$y = aphrodite.StyleSheet.create({
22868
22886
  iconWrapper: {
22869
22887
  display: "inline-block",
22870
22888
  position: "relative"
@@ -22887,7 +22905,7 @@ const CrossOutLine = function (props) {
22887
22905
  width: CROSS_OUT_LINE_SIZE,
22888
22906
  height: CROSS_OUT_LINE_SIZE,
22889
22907
  viewBox: `0 0 ${CROSS_OUT_LINE_SIZE} ${CROSS_OUT_LINE_SIZE}`,
22890
- className: aphrodite.css(styles$w.crossOutLine),
22908
+ className: aphrodite.css(styles$x.crossOutLine),
22891
22909
  "data-test-id": "choice-icon__cross-out-line"
22892
22910
  }, /*#__PURE__*/React__namespace.createElement("line", {
22893
22911
  // The line stretches from the bottom-left to top-right.
@@ -22902,7 +22920,7 @@ const CrossOutLine = function (props) {
22902
22920
  strokeLinecap: "round"
22903
22921
  }));
22904
22922
  };
22905
- const styles$w = aphrodite.StyleSheet.create({
22923
+ const styles$x = aphrodite.StyleSheet.create({
22906
22924
  crossOutLine: {
22907
22925
  // Center the icon within the container.
22908
22926
  position: "absolute",
@@ -22983,7 +23001,7 @@ const ChoiceIcon = function (props) {
22983
23001
  } = props;
22984
23002
  const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct);
22985
23003
  return /*#__PURE__*/React__namespace.createElement("div", {
22986
- className: aphrodite.css(styles$x.iconWrapper)
23004
+ className: aphrodite.css(styles$y.iconWrapper)
22987
23005
  }, /*#__PURE__*/React__namespace.createElement(FocusRing, {
22988
23006
  color: Color__default["default"].blue,
22989
23007
  visible: focused || hovered,
@@ -22992,13 +23010,13 @@ const ChoiceIcon = function (props) {
22992
23010
  // @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
22993
23011
  style: dynamicStyles,
22994
23012
  "data-test-id": "choice-icon__library-choice-icon",
22995
- className: aphrodite.css(styles$v.circle, showCorrectness && correct && styles$v.circleCorrect, showCorrectness && !correct && styles$v.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$v.circleIncorrectAnswered)
23013
+ className: aphrodite.css(styles$w.circle, showCorrectness && correct && styles$w.circleCorrect, showCorrectness && !correct && styles$w.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$w.circleIncorrectAnswered)
22996
23014
  // used in BaseRadio editMode to check
22997
23015
  // if we actually clicked on the radio icon
22998
23016
  ,
22999
23017
  "data-is-radio-icon": true
23000
23018
  }, /*#__PURE__*/React__namespace.createElement("div", {
23001
- className: aphrodite.css(styles$v.innerWrapper)
23019
+ className: aphrodite.css(styles$w.innerWrapper)
23002
23020
  }, /*#__PURE__*/React__namespace.createElement(ChoiceInner, {
23003
23021
  pos: pos,
23004
23022
  showCorrectness: showCorrectness,
@@ -23007,7 +23025,7 @@ const ChoiceIcon = function (props) {
23007
23025
  color: dynamicStyles.borderColor
23008
23026
  }));
23009
23027
  };
23010
- const styles$v = aphrodite.StyleSheet.create({
23028
+ const styles$w = aphrodite.StyleSheet.create({
23011
23029
  innerWrapper: {
23012
23030
  width: CHOICE_ICON_SIZE,
23013
23031
  height: CHOICE_ICON_SIZE,
@@ -23099,19 +23117,19 @@ const OptionStatus = function (props) {
23099
23117
  }
23100
23118
  let textStyle;
23101
23119
  if (correct) {
23102
- textStyle = styles$u.correct;
23120
+ textStyle = styles$v.correct;
23103
23121
  } else {
23104
23122
  if (checked || previouslyAnswered) {
23105
- textStyle = styles$u.incorrectAnswered;
23123
+ textStyle = styles$v.incorrectAnswered;
23106
23124
  } else {
23107
- textStyle = styles$u.incorrect;
23125
+ textStyle = styles$v.incorrect;
23108
23126
  }
23109
23127
  }
23110
23128
  return /*#__PURE__*/React__namespace.createElement("div", {
23111
- className: aphrodite.css(styles$u.text, textStyle)
23129
+ className: aphrodite.css(styles$v.text, textStyle)
23112
23130
  }, renderText(checked, correct, crossedOut));
23113
23131
  };
23114
- const styles$u = aphrodite.StyleSheet.create({
23132
+ const styles$v = aphrodite.StyleSheet.create({
23115
23133
  text: {
23116
23134
  alignItems: "center",
23117
23135
  display: "flex",
@@ -23185,8 +23203,8 @@ const Choice = function (props) {
23185
23203
  crossedOut: updatedCrossedOut
23186
23204
  });
23187
23205
  }
23188
- const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$t.description));
23189
- const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$t.rationale));
23206
+ const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$u.description));
23207
+ const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$u.rationale));
23190
23208
 
23191
23209
  // We want to show the choices as dimmed out when the choices are disabled.
23192
23210
  // However, we don't want to do this when we're in review mode in the
@@ -23357,7 +23375,7 @@ const Choice = function (props) {
23357
23375
  "data-test-id": `perseus-radio-rationale-content-${pos}`
23358
23376
  }, rationale));
23359
23377
  };
23360
- const styles$t = aphrodite.StyleSheet.create({
23378
+ const styles$u = aphrodite.StyleSheet.create({
23361
23379
  description: {
23362
23380
  display: "inline-block",
23363
23381
  width: "100%"
@@ -23549,10 +23567,10 @@ const BaseRadio = function (props) {
23549
23567
  const isMobile = apiOptions.isMobile;
23550
23568
  const firstChoiceHighlighted = choices[0].highlighted;
23551
23569
  const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
23552
- const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$s.radio, styles$s.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$s.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$s.radioContainerLastHighlighted));
23553
- const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$s.instructions, isMobile && styles$s.instructionsMobile));
23570
+ const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$t.radio, styles$t.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$t.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$t.radioContainerLastHighlighted));
23571
+ const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$t.instructions, isMobile && styles$t.instructionsMobile));
23554
23572
  const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect);
23555
- const responsiveClassName = aphrodite.css(styles$s.responsiveFieldset);
23573
+ const responsiveClassName = aphrodite.css(styles$t.responsiveFieldset);
23556
23574
  const fieldset = /*#__PURE__*/React__namespace.createElement("fieldset", {
23557
23575
  className: `perseus-widget-radio-fieldset ${responsiveClassName}`
23558
23576
  }, /*#__PURE__*/React__namespace.createElement("legend", {
@@ -23603,7 +23621,7 @@ const BaseRadio = function (props) {
23603
23621
  const aphroditeClassName = checked => {
23604
23622
  // Whether or not to show correctness borders
23605
23623
  // for this choice and the next choice.
23606
- return aphrodite.css(sharedStyles.aboveScratchpad, styles$s.item, styles$s.responsiveItem, checked && styles$s.selectedItem, checked && choice.highlighted && styles$s.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$s.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$s.nextHighlighted);
23624
+ return aphrodite.css(sharedStyles.aboveScratchpad, styles$t.item, styles$t.responsiveItem, checked && styles$t.selectedItem, checked && choice.highlighted && styles$t.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$t.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$t.nextHighlighted);
23607
23625
  };
23608
23626
 
23609
23627
  // HACK(abdulrahman): Preloads the selection-state
@@ -23677,14 +23695,14 @@ const BaseRadio = function (props) {
23677
23695
  // Allow for horizontal scrolling if content is too wide, which may be
23678
23696
  // an issue especially on phones.
23679
23697
  return /*#__PURE__*/React__namespace.createElement("div", {
23680
- className: aphrodite.css(styles$s.responsiveContainer)
23698
+ className: aphrodite.css(styles$t.responsiveContainer)
23681
23699
  }, fieldset);
23682
23700
  };
23683
23701
  BaseRadio.defaultProps = {
23684
23702
  editMode: false,
23685
23703
  multipleSelect: false
23686
23704
  };
23687
- const styles$s = aphrodite.StyleSheet.create({
23705
+ const styles$t = aphrodite.StyleSheet.create({
23688
23706
  instructions: {
23689
23707
  display: "block",
23690
23708
  color: gray17,
@@ -24343,9 +24361,9 @@ class Categorizer extends React__namespace.Component {
24343
24361
  indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
24344
24362
  }
24345
24363
  const table = /*#__PURE__*/React__namespace.createElement("table", {
24346
- className: "categorizer-table " + aphrodite.css(styles$r.mobileTable)
24364
+ className: "categorizer-table " + aphrodite.css(styles$s.mobileTable)
24347
24365
  }, /*#__PURE__*/React__namespace.createElement("thead", null, /*#__PURE__*/React__namespace.createElement("tr", null, /*#__PURE__*/React__namespace.createElement("td", {
24348
- className: aphrodite.css(styles$r.emptyHeaderCell)
24366
+ className: aphrodite.css(styles$s.emptyHeaderCell)
24349
24367
  }), this.props.categories.map((category, i) => {
24350
24368
  // Array index is the correct key here, as that's
24351
24369
  // how category grading actually works -- no way
@@ -24353,7 +24371,7 @@ class Categorizer extends React__namespace.Component {
24353
24371
  // middle. (If we later add that, this should be
24354
24372
  // fixed.)
24355
24373
  return /*#__PURE__*/React__namespace.createElement("th", {
24356
- className: aphrodite.css(styles$r.header),
24374
+ className: aphrodite.css(styles$s.header),
24357
24375
  key: i
24358
24376
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
24359
24377
  content: category,
@@ -24373,7 +24391,7 @@ class Categorizer extends React__namespace.Component {
24373
24391
  })), self.props.categories.map((catName, catNum) => {
24374
24392
  const selected = self.props.values[itemNum] === catNum;
24375
24393
  return /*#__PURE__*/React__namespace.createElement("td", {
24376
- className: "category " + aphrodite.css(styles$r.cell),
24394
+ className: "category " + aphrodite.css(styles$s.cell),
24377
24395
  key: catNum
24378
24396
  }, /*#__PURE__*/React__namespace.createElement("div", {
24379
24397
  className: ClassNames.INTERACTIVE,
@@ -24388,7 +24406,7 @@ class Categorizer extends React__namespace.Component {
24388
24406
  onChange: () => this.onChange(itemNum, catNum),
24389
24407
  onClick: e => e.stopPropagation()
24390
24408
  }), !isMobile && /*#__PURE__*/React__namespace.createElement("span", {
24391
- className: aphrodite.css(styles$r.radioSpan, selected && styles$r.checkedRadioSpan, this.props.static && selected && styles$r.staticCheckedRadioSpan)
24409
+ className: aphrodite.css(styles$s.radioSpan, selected && styles$s.checkedRadioSpan, this.props.static && selected && styles$s.staticCheckedRadioSpan)
24392
24410
  }, selected ? /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircle) : /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircleThin))));
24393
24411
  }));
24394
24412
  /* eslint-enable max-len */
@@ -24400,7 +24418,7 @@ class Categorizer extends React__namespace.Component {
24400
24418
  "categorizer-container": true,
24401
24419
  "static-mode": this.props.static
24402
24420
  });
24403
- const inlineStyles = this.props.apiOptions.isMobile ? [styles$r.fullBleedContainer] : [];
24421
+ const inlineStyles = this.props.apiOptions.isMobile ? [styles$s.fullBleedContainer] : [];
24404
24422
  return /*#__PURE__*/React__namespace.createElement("div", {
24405
24423
  className: extraClassNames + " " + aphrodite.css(...inlineStyles)
24406
24424
  }, table);
@@ -24449,7 +24467,7 @@ const pageMargin = 16;
24449
24467
 
24450
24468
  // Stylesheets aren't directly testable
24451
24469
  /* c8 ignore next */
24452
- const styles$r = aphrodite.StyleSheet.create({
24470
+ const styles$s = aphrodite.StyleSheet.create({
24453
24471
  mobileTable: {
24454
24472
  [mediaQueries.smOrSmaller]: {
24455
24473
  minWidth: "auto"
@@ -24712,7 +24730,7 @@ class CSProgram extends React__namespace.Component {
24712
24730
  // creator "went wild".
24713
24731
  // http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
24714
24732
  return /*#__PURE__*/React__namespace.createElement("div", {
24715
- className: aphrodite.css(styles$q.widthOverride, styleContainer && styles$q.container)
24733
+ className: aphrodite.css(styles$r.widthOverride, styleContainer && styles$r.container)
24716
24734
  }, /*#__PURE__*/React__namespace.createElement("iframe", {
24717
24735
  sandbox: sandboxOptions,
24718
24736
  src: url,
@@ -24722,7 +24740,7 @@ class CSProgram extends React__namespace.Component {
24722
24740
  }));
24723
24741
  }
24724
24742
  }
24725
- const styles$q = aphrodite.StyleSheet.create({
24743
+ const styles$r = aphrodite.StyleSheet.create({
24726
24744
  // Override the inherited width from the perseus paragraph class
24727
24745
  // 820 is minimum width for 420px editor and 400px canvas
24728
24746
  widthOverride: {
@@ -24770,7 +24788,7 @@ class Definition extends React__namespace.Component {
24770
24788
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.Popover, {
24771
24789
  content: /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContentCore, {
24772
24790
  color: "white",
24773
- style: styles$p.tooltipBody,
24791
+ style: styles$q.tooltipBody,
24774
24792
  closeButtonVisible: true
24775
24793
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
24776
24794
  apiOptions: this.props.apiOptions,
@@ -24801,7 +24819,7 @@ class Definition extends React__namespace.Component {
24801
24819
  });
24802
24820
  }
24803
24821
  }
24804
- const styles$p = {
24822
+ const styles$q = {
24805
24823
  tooltipBody: {
24806
24824
  color: Color__default["default"].offBlack,
24807
24825
  fontSize: 20,
@@ -25002,15 +25020,15 @@ class Explanation extends React__namespace.Component {
25002
25020
  const onClick = this._onClick;
25003
25021
  if (isMobile) {
25004
25022
  promptContainer = /*#__PURE__*/React__namespace.createElement("div", {
25005
- className: aphrodite.css(styles$o.linkContainer)
25023
+ className: aphrodite.css(styles$p.linkContainer)
25006
25024
  }, /*#__PURE__*/React__namespace.createElement("a", {
25007
- className: aphrodite.css(styles$o.mobileExplanationLink),
25025
+ className: aphrodite.css(styles$p.mobileExplanationLink),
25008
25026
  href: href,
25009
25027
  onClick: onClick,
25010
25028
  role: "button",
25011
25029
  "aria-expanded": this.state.expanded
25012
25030
  }, promptText), this.state.expanded && /*#__PURE__*/React__namespace.createElement("svg", {
25013
- className: aphrodite.css(styles$o.disclosureArrow)
25031
+ className: aphrodite.css(styles$p.disclosureArrow)
25014
25032
  }, /*#__PURE__*/React__namespace.createElement("polygon", {
25015
25033
  style: {
25016
25034
  fill: backgroundColor
@@ -25018,7 +25036,7 @@ class Explanation extends React__namespace.Component {
25018
25036
  points: `0,${arrowHeight} ` + `${arrowWidth},${arrowHeight} ` + `${arrowWidth / 2},0`
25019
25037
  })));
25020
25038
  } else {
25021
- const viewStyling = isArticle ? [styles$o.explanationLink, styles$o.articleLink] : [styles$o.explanationLink, styles$o.exerciseLink];
25039
+ const viewStyling = isArticle ? [styles$p.explanationLink, styles$p.articleLink] : [styles$p.explanationLink, styles$p.exerciseLink];
25022
25040
  promptContainer = /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
25023
25041
  onClick: onClick,
25024
25042
  "aria-expanded": this.state.expanded
@@ -25026,11 +25044,11 @@ class Explanation extends React__namespace.Component {
25026
25044
  style: viewStyling
25027
25045
  }, `[${promptText}]`));
25028
25046
  }
25029
- const expandedStyle = isMobile ? styles$o.contentExpandedMobile : styles$o.contentExpanded;
25047
+ const expandedStyle = isMobile ? styles$p.contentExpandedMobile : styles$p.contentExpanded;
25030
25048
  return /*#__PURE__*/React__namespace.createElement("div", {
25031
- className: aphrodite.css(styles$o.container)
25049
+ className: aphrodite.css(styles$p.container)
25032
25050
  }, promptContainer, this.state.expanded && /*#__PURE__*/React__namespace.createElement("div", {
25033
- className: aphrodite.css(styles$o.content, isMobile && styles$o.contentMobile, this.state.expanded && expandedStyle)
25051
+ className: aphrodite.css(styles$p.content, isMobile && styles$p.contentMobile, this.state.expanded && expandedStyle)
25034
25052
  // eslint-disable-next-line react/no-string-refs
25035
25053
  ,
25036
25054
  ref: "content"
@@ -25053,7 +25071,7 @@ const verticalContentPadding = 10;
25053
25071
  const arrowWidth = 30;
25054
25072
  const arrowHeight = 14;
25055
25073
  const backgroundColor = gray95;
25056
- const styles$o = aphrodite.StyleSheet.create({
25074
+ const styles$p = aphrodite.StyleSheet.create({
25057
25075
  container: {
25058
25076
  display: "inline",
25059
25077
  position: "relative"
@@ -25159,15 +25177,15 @@ class GradedGroupAnswerBar extends React__namespace.Component {
25159
25177
  onNextQuestion
25160
25178
  } = this.props;
25161
25179
  const answerBarStyle = {
25162
- ...styles$n.answerBar,
25180
+ ...styles$o.answerBar,
25163
25181
  backgroundColor: answerBarState === "CORRECT" ? Color__default["default"].offWhite : "white",
25164
25182
  // Center the "Correct!" message only when there's no next question
25165
25183
  justifyContent: answerBarState === "CORRECT" && !onNextQuestion ? "center" : "space-between"
25166
25184
  };
25167
25185
  const message = answerBarState === "INCORRECT" ? /*#__PURE__*/React__namespace.createElement("span", {
25168
- style: styles$n.text
25186
+ style: styles$o.text
25169
25187
  }, /*#__PURE__*/React__namespace.createElement("span", {
25170
- style: styles$n.tryAgainIcon
25188
+ style: styles$o.tryAgainIcon
25171
25189
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconTryAgain)), /*#__PURE__*/React__namespace.createElement("span", {
25172
25190
  style: {
25173
25191
  marginLeft: 8
@@ -25186,7 +25204,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
25186
25204
  return /*#__PURE__*/React__namespace.createElement("div", {
25187
25205
  style: answerBarStyle
25188
25206
  }, /*#__PURE__*/React__namespace.createElement("span", {
25189
- style: styles$n.text
25207
+ style: styles$o.text
25190
25208
  }, /*#__PURE__*/React__namespace.createElement("span", {
25191
25209
  style: {
25192
25210
  fontSize: 28,
@@ -25208,7 +25226,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
25208
25226
  }
25209
25227
  }
25210
25228
  const fontSize = 17;
25211
- const styles$n = {
25229
+ const styles$o = {
25212
25230
  answerBar: {
25213
25231
  display: "flex",
25214
25232
  alignItems: "center",
@@ -25408,7 +25426,7 @@ class GradedGroup extends React__namespace.Component {
25408
25426
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
25409
25427
  gradeStatus = i18n__namespace._("Incorrect");
25410
25428
  }
25411
- const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$m.gradedGroupInSet) : aphrodite.css(styles$m.gradedGroup);
25429
+ const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$n.gradedGroupInSet) : aphrodite.css(styles$n.gradedGroup);
25412
25430
  const classes = classNames__default["default"]({
25413
25431
  [mobileClass]: apiOptions.isMobile,
25414
25432
  "perseus-graded-group": true,
@@ -25427,7 +25445,7 @@ class GradedGroup extends React__namespace.Component {
25427
25445
  return /*#__PURE__*/React__namespace.createElement("div", {
25428
25446
  className: classes
25429
25447
  }, !!this.props.title && /*#__PURE__*/React__namespace.createElement("div", {
25430
- className: aphrodite.css(styles$m.title)
25448
+ className: aphrodite.css(styles$n.title)
25431
25449
  }, this.props.title), /*#__PURE__*/React__namespace.createElement(Renderer, _extends({}, this.props, {
25432
25450
  // eslint-disable-next-line react/no-string-refs
25433
25451
  ref: "renderer",
@@ -25460,7 +25478,7 @@ class GradedGroup extends React__namespace.Component {
25460
25478
  }, i18n__namespace._("Next question")), this.props.hint && this.props.hint.content && (this.state.showHint ? /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("button", {
25461
25479
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
25462
25480
  tabIndex: "0",
25463
- className: aphrodite.css(styles$m.explanationTitle),
25481
+ className: aphrodite.css(styles$n.explanationTitle),
25464
25482
  onClick: () => this.setState({
25465
25483
  showHint: false
25466
25484
  }),
@@ -25492,7 +25510,7 @@ class GradedGroup extends React__namespace.Component {
25492
25510
  showHint: true
25493
25511
  });
25494
25512
  },
25495
- className: aphrodite.css(styles$m.showHintLink)
25513
+ className: aphrodite.css(styles$n.showHintLink)
25496
25514
  }, i18n__namespace._("Explain"))), apiOptions.isMobile && answerBarState !== "HIDDEN" && /*#__PURE__*/React__namespace.createElement(GradedGroupAnswerBar, {
25497
25515
  apiOptions: apiOptions,
25498
25516
  answerBarState: answerBarState,
@@ -25504,7 +25522,7 @@ class GradedGroup extends React__namespace.Component {
25504
25522
  const traverseChildWidgets$2 = function (props, traverseRenderer) {
25505
25523
  return ___default["default"].extend({}, props, traverseRenderer(props));
25506
25524
  };
25507
- const styles$m = aphrodite.StyleSheet.create({
25525
+ const styles$n = aphrodite.StyleSheet.create({
25508
25526
  gradedGroupInSet: {
25509
25527
  // Reset a few desktop-only styles that come from graded-group.less
25510
25528
  marginLeft: 0,
@@ -25574,20 +25592,20 @@ class Indicators extends React__namespace.Component {
25574
25592
  return /*#__PURE__*/React__namespace.createElement("ul", {
25575
25593
  // reduntantly add class name for use in .less files--
25576
25594
  // the styles object key gets hashed
25577
- className: classNames__default["default"](aphrodite.css(styles$l.indicatorContainer), "indicatorContainer")
25595
+ className: classNames__default["default"](aphrodite.css(styles$m.indicatorContainer), "indicatorContainer")
25578
25596
  }, this.props.gradedGroups.map((_ref, i) => {
25579
25597
  let {
25580
25598
  title
25581
25599
  } = _ref;
25582
25600
  return /*#__PURE__*/React__namespace.createElement("li", {
25583
- className: aphrodite.css(styles$l.indicator),
25601
+ className: aphrodite.css(styles$m.indicator),
25584
25602
  key: title
25585
25603
  }, /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
25586
25604
  role: "button",
25587
25605
  "aria-label": i18n__namespace._("Skip to %(title)s", {
25588
25606
  title
25589
25607
  }),
25590
- style: styles$l.indicatorButton,
25608
+ style: styles$m.indicatorButton,
25591
25609
  onClick: () => this.props.onChangeCurrentGroup(i),
25592
25610
  onKeyDown: e => this.handleKeyDown(e, i)
25593
25611
  }, _ref2 => {
@@ -25597,9 +25615,9 @@ class Indicators extends React__namespace.Component {
25597
25615
  pressed
25598
25616
  } = _ref2;
25599
25617
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
25600
- style: [styles$l.indicatorDot, (hovered || focused || pressed) && styles$l.indicatorDotFocused]
25618
+ style: [styles$m.indicatorDot, (hovered || focused || pressed) && styles$m.indicatorDotFocused]
25601
25619
  }, i === this.props.currentGroup && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
25602
- style: styles$l.indicatorDotActive
25620
+ style: styles$m.indicatorDotActive
25603
25621
  }, /*#__PURE__*/React__namespace.createElement("span", {
25604
25622
  className: aphrodite.css(a11y.srOnly)
25605
25623
  }, i18n__namespace._("Current"))));
@@ -25675,7 +25693,7 @@ class GradedGroupSet extends React__namespace.Component {
25675
25693
  } = getDependencies();
25676
25694
  if (JIPT.useJIPT && this.props.gradedGroups.length > 1) {
25677
25695
  return /*#__PURE__*/React__namespace.createElement("div", {
25678
- className: aphrodite.css(styles$l.container)
25696
+ className: aphrodite.css(styles$m.container)
25679
25697
  }, this.props.gradedGroups.map((gradedGroup, i) => {
25680
25698
  return (
25681
25699
  /*#__PURE__*/
@@ -25698,13 +25716,13 @@ class GradedGroupSet extends React__namespace.Component {
25698
25716
  const numGroups = this.props.gradedGroups.length;
25699
25717
  const handleNextQuestion = this.state.currentGroup < numGroups - 1 ? this.handleNextQuestion : null;
25700
25718
  return /*#__PURE__*/React__namespace.createElement("div", {
25701
- className: aphrodite.css(styles$l.container)
25719
+ className: aphrodite.css(styles$m.container)
25702
25720
  }, /*#__PURE__*/React__namespace.createElement("div", {
25703
- className: aphrodite.css(styles$l.top)
25721
+ className: aphrodite.css(styles$m.top)
25704
25722
  }, /*#__PURE__*/React__namespace.createElement("div", {
25705
- className: aphrodite.css(styles$l.title)
25723
+ className: aphrodite.css(styles$m.title)
25706
25724
  }, currentGroup.title), /*#__PURE__*/React__namespace.createElement("div", {
25707
- className: aphrodite.css(styles$l.spacer)
25725
+ className: aphrodite.css(styles$m.spacer)
25708
25726
  }), /*#__PURE__*/React__namespace.createElement(Indicators, {
25709
25727
  currentGroup: this.state.currentGroup,
25710
25728
  gradedGroups: this.props.gradedGroups,
@@ -25742,7 +25760,7 @@ var GradedGroupSet$1 = {
25742
25760
  tracking: "all",
25743
25761
  isLintable: true
25744
25762
  };
25745
- const styles$l = aphrodite.StyleSheet.create({
25763
+ const styles$m = aphrodite.StyleSheet.create({
25746
25764
  top: {
25747
25765
  display: "flex",
25748
25766
  flexDirection: "row"
@@ -25847,7 +25865,7 @@ class ButtonGroup extends React__namespace.Component {
25847
25865
  id: "" + i,
25848
25866
  ref: "button" + i,
25849
25867
  key: "" + i,
25850
- className: aphrodite.css(styles$k.buttonStyle, button.value === value && styles$k.selectedStyle),
25868
+ className: aphrodite.css(styles$l.buttonStyle, button.value === value && styles$l.selectedStyle),
25851
25869
  onClick: () => this.toggleSelect(button.value)
25852
25870
  }, button.content || "" + button.value);
25853
25871
  });
@@ -25860,7 +25878,7 @@ class ButtonGroup extends React__namespace.Component {
25860
25878
  }, buttons);
25861
25879
  }
25862
25880
  }
25863
- const styles$k = aphrodite.StyleSheet.create({
25881
+ const styles$l = aphrodite.StyleSheet.create({
25864
25882
  buttonStyle: {
25865
25883
  backgroundColor: "white",
25866
25884
  border: "1px solid #ccc",
@@ -28379,18 +28397,51 @@ const SegmentGraph = props => {
28379
28397
  })));
28380
28398
  };
28381
28399
  const SegmentView = props => {
28382
- const [pt1, pt2] = props.segment;
28400
+ const {
28401
+ onMoveSegment,
28402
+ segment: [pt1, pt2]
28403
+ } = props;
28383
28404
  const midpoint = mafs.vec.midpoint(pt1, pt2);
28384
- return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Line.Segment, {
28385
- point1: pt1,
28386
- point2: pt2
28387
- }), /*#__PURE__*/React__namespace.createElement(mafs.MovablePoint, {
28405
+ const segment = React.useRef(null);
28406
+ const {
28407
+ dragging: isDraggingSegment
28408
+ } = mafs.useMovable({
28409
+ gestureTarget: segment,
28388
28410
  point: midpoint,
28389
- color: Color__default["default"].blue,
28390
28411
  onMove: newPoint => {
28391
- props.onMoveSegment(mafs.vec.sub(newPoint, midpoint));
28412
+ onMoveSegment(mafs.vec.sub(newPoint, midpoint));
28413
+ },
28414
+ constrain: p => p
28415
+ });
28416
+ const {
28417
+ viewTransform,
28418
+ userTransform
28419
+ } = mafs.useTransformContext();
28420
+ const transform = mafs.vec.matrixMult(viewTransform, userTransform);
28421
+ const scaledPoint1 = mafs.vec.transform(pt1, transform);
28422
+ const scaledPoint2 = mafs.vec.transform(pt2, transform);
28423
+ return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("g", {
28424
+ ref: segment,
28425
+ tabIndex: 0,
28426
+ className: "movable-segment",
28427
+ style: {
28428
+ cursor: isDraggingSegment ? "grabbing" : "grab"
28392
28429
  }
28393
- }), /*#__PURE__*/React__namespace.createElement(mafs.MovablePoint, {
28430
+ }, /*#__PURE__*/React__namespace.createElement(SVGLine, {
28431
+ start: scaledPoint1,
28432
+ end: scaledPoint2,
28433
+ style: {
28434
+ stroke: "transparent",
28435
+ strokeWidth: 30
28436
+ }
28437
+ }), /*#__PURE__*/React__namespace.createElement(SVGLine, {
28438
+ start: scaledPoint1,
28439
+ end: scaledPoint2,
28440
+ style: {
28441
+ stroke: "var(--mafs-segment-stroke-color)",
28442
+ strokeWidth: "var(--mafs-segment-stroke-weight)"
28443
+ }
28444
+ })), /*#__PURE__*/React__namespace.createElement(mafs.MovablePoint, {
28394
28445
  point: pt1,
28395
28446
  color: Color__default["default"].blue,
28396
28447
  onMove: newPoint => {
@@ -28404,6 +28455,20 @@ const SegmentView = props => {
28404
28455
  }
28405
28456
  }));
28406
28457
  };
28458
+ function SVGLine(props) {
28459
+ const {
28460
+ start,
28461
+ end,
28462
+ style
28463
+ } = props;
28464
+ return /*#__PURE__*/React__namespace.createElement("line", {
28465
+ x1: start[0],
28466
+ y1: start[1],
28467
+ x2: end[0],
28468
+ y2: end[1],
28469
+ style: style
28470
+ });
28471
+ }
28407
28472
 
28408
28473
  const renderLineLabel = (n, _ref) => {
28409
28474
  let [min, max] = _ref;
@@ -28581,7 +28646,7 @@ const VisibleIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
28581
28646
  width: "24",
28582
28647
  height: "24",
28583
28648
  viewBox: "0 0 24 24",
28584
- className: aphrodite.css(styles$j.icon)
28649
+ className: aphrodite.css(styles$k.icon)
28585
28650
  }, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("path", {
28586
28651
  id: "a",
28587
28652
  d: "M7.401 10.035c-1.424.748-2.599 1.905-3.544 " + "3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 " + "12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 " + "1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-" + "3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 " + "0 0 0 0 6z"
@@ -28612,7 +28677,7 @@ const HiddenIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
28612
28677
  width: "24",
28613
28678
  height: "24",
28614
28679
  viewBox: "0 0 24 24",
28615
- className: aphrodite.css(styles$j.icon)
28680
+ className: aphrodite.css(styles$k.icon)
28616
28681
  }, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("path", {
28617
28682
  id: "a",
28618
28683
  d: "M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 " + "7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 " + "1.028c-.945-1.574-2.12-2.73-3.544-3.48.258." + "604.401 1.268.401 1.966 0 1.02-.305 " + "1.967-.828 2.757l2.535 2.536a1 1 0 0 " + "1-1.414 1.414l-12-12a1 1 0 0 1 " + "1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 " + "0-4.001-4.001l4 4.001zM6.072 8.486l2.976 " + "2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 " + "0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 " + "3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 " + "2.363-3.085 3.929-4z"
@@ -28647,20 +28712,20 @@ const HUD = _ref => {
28647
28712
  let state;
28648
28713
  let icon;
28649
28714
  if (enabled) {
28650
- state = styles$j.enabled;
28715
+ state = styles$k.enabled;
28651
28716
  icon = /*#__PURE__*/React__namespace.createElement(VisibleIcon, null);
28652
28717
  } else {
28653
- state = styles$j.disabled;
28718
+ state = styles$k.disabled;
28654
28719
  icon = /*#__PURE__*/React__namespace.createElement(HiddenIcon, null);
28655
28720
  }
28656
28721
  return /*#__PURE__*/React__namespace.createElement("button", {
28657
- className: aphrodite.css(styles$j.hud, fixedPosition && styles$j.hudFixedPosition, state),
28722
+ className: aphrodite.css(styles$k.hud, fixedPosition && styles$k.hudFixedPosition, state),
28658
28723
  onClick: e => {
28659
28724
  onClick();
28660
28725
  }
28661
28726
  }, icon, message);
28662
28727
  };
28663
- const styles$j = aphrodite.StyleSheet.create({
28728
+ const styles$k = aphrodite.StyleSheet.create({
28664
28729
  hud: {
28665
28730
  boxSizing: "border-box",
28666
28731
  height: 36,
@@ -28724,7 +28789,7 @@ const triangleBeforeAfter = {
28724
28789
  top: "0",
28725
28790
  width: "0"
28726
28791
  };
28727
- const styles$i = aphrodite.StyleSheet.create({
28792
+ const styles$j = aphrodite.StyleSheet.create({
28728
28793
  infoTip: {
28729
28794
  display: "inline-block",
28730
28795
  marginLeft: "5px",
@@ -28765,7 +28830,6 @@ const styles$i = aphrodite.StyleSheet.create({
28765
28830
  width: "240px"
28766
28831
  }
28767
28832
  });
28768
- const questionMark = "data:image/png;base64," + "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBB" + "ZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/" + "eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+" + "IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2Jl" + "IFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAg" + "ICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5" + "LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9" + "IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHht" + "bG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3Vy" + "Y2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHht" + "cE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo2N2M3NTAxYS04YmVlLTQ0M2Mt" + "YmRiNS04OGM2N2IxN2NhYzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUJCRTk4" + "Qjc4NjAwMTFFMzg3QUJDNEI4Mzk2QTRGQkQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5p" + "aWQ6OUJCRTk4QjY4NjAwMTFFMzg3QUJDNEI4Mzk2QTRGQkQiIHhtcDpDcmVhdG9yVG9v" + "bD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRG" + "cm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NGE5ZDI0OTMtODk1NC00OGFkLTlh" + "MTgtZDAwM2MwYWNjNDJlIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY3Yzc1MDFh" + "LThiZWUtNDQzYy1iZGI1LTg4YzY3YjE3Y2FjMSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4g" + "PC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pqm89uYAAADM" + "SURBVHjaXJA9DoJAEIUH1M4TUHIFsCMGen9OwCGw1YRGW2ntKel0exsojHIBC0ouQAyU" + "viFDstmXfNmZeS+zm7XSNCXRFiRgJf0bXIHixpbhGdxBBJYC1w/xaA424MhNEATkui71" + "fU9KqfEU78UbD9PdbJRlOdae55GmhIP+1NV1TcMwkOM41DSNHvRtMhTHMRVFQW3b6mOL" + "gx99kue5GRp/gIOZuZGvNpTNwjD8oliANU+qqqKu6/TQBdymN57AHjzBT+B6Jx79BRgA" + "vc49kQA4yxgAAAAASUVORK5CYII=";
28769
28833
  class InfoTip$1 extends React__namespace.Component {
28770
28834
  state = {
28771
28835
  hover: false
@@ -28782,23 +28846,22 @@ class InfoTip$1 extends React__namespace.Component {
28782
28846
  };
28783
28847
  render() {
28784
28848
  return /*#__PURE__*/React__namespace.createElement("div", {
28785
- className: aphrodite.css(styles$i.infoTip)
28786
- }, /*#__PURE__*/React__namespace.createElement("img", {
28787
- alt: "",
28788
- width: 10,
28789
- height: 10,
28790
- src: questionMark,
28849
+ className: aphrodite.css(styles$j.infoTip)
28850
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
28791
28851
  onMouseEnter: this.handleMouseEnter,
28792
28852
  onMouseLeave: this.handleMouseLeave
28793
- }), /*#__PURE__*/React__namespace.createElement("div", {
28794
- className: aphrodite.css(styles$i.infoTipContainer),
28853
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
28854
+ size: "small",
28855
+ icon: questionIcon__default["default"]
28856
+ })), /*#__PURE__*/React__namespace.createElement("div", {
28857
+ className: aphrodite.css(styles$j.infoTipContainer),
28795
28858
  style: {
28796
28859
  display: this.state.hover ? "block" : "none"
28797
28860
  }
28798
28861
  }, /*#__PURE__*/React__namespace.createElement("div", {
28799
- className: aphrodite.css(styles$i.infoTipTriangle)
28862
+ className: aphrodite.css(styles$j.infoTipTriangle)
28800
28863
  }), /*#__PURE__*/React__namespace.createElement("div", {
28801
- className: aphrodite.css(styles$i.verticalShadow, styles$i.infoTipContentContainer)
28864
+ className: aphrodite.css(styles$j.verticalShadow, styles$j.infoTipContentContainer)
28802
28865
  }, this.props.children)));
28803
28866
  }
28804
28867
  }
@@ -28870,7 +28933,7 @@ class MultiButtonGroup extends React__namespace.Component {
28870
28933
  id: "" + i,
28871
28934
  key: "" + i,
28872
28935
  ref: "button" + i,
28873
- className: aphrodite.css(styles$h.buttonStyle, selected && styles$h.selectedStyle),
28936
+ className: aphrodite.css(styles$i.buttonStyle, selected && styles$i.selectedStyle),
28874
28937
  onClick: () => this.toggleSelect(button.value)
28875
28938
  }, button.content || "" + button.value);
28876
28939
  });
@@ -28882,7 +28945,7 @@ class MultiButtonGroup extends React__namespace.Component {
28882
28945
  }, buttons);
28883
28946
  }
28884
28947
  }
28885
- const styles$h = aphrodite.StyleSheet.create({
28948
+ const styles$i = aphrodite.StyleSheet.create({
28886
28949
  buttonStyle: {
28887
28950
  backgroundColor: "white",
28888
28951
  border: "1px solid #ccc",
@@ -29147,11 +29210,12 @@ const PropCheckBox = createReactClass__default["default"]({
29147
29210
  },
29148
29211
  render: function () {
29149
29212
  const propName = this.propName();
29150
- return /*#__PURE__*/React__namespace.createElement("label", null, this._labelAlignLeft() && this.props.label, /*#__PURE__*/React__namespace.createElement("input", {
29151
- type: "checkbox",
29213
+ return /*#__PURE__*/React__namespace.createElement("label", {
29214
+ className: aphrodite.css(styles$h.labeledCheckbox)
29215
+ }, this._labelAlignLeft() && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, null, this.props.label), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
29152
29216
  checked: this.props[propName],
29153
29217
  onChange: this.toggle
29154
- }), !this._labelAlignLeft() && this.props.label);
29218
+ }), !this._labelAlignLeft() && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, null, this.props.label));
29155
29219
  },
29156
29220
  toggle: function () {
29157
29221
  const propName = this.propName();
@@ -29160,6 +29224,13 @@ const PropCheckBox = createReactClass__default["default"]({
29160
29224
  this.props.onChange(changes);
29161
29225
  }
29162
29226
  });
29227
+ const styles$h = aphrodite.StyleSheet.create({
29228
+ labeledCheckbox: {
29229
+ display: "flex",
29230
+ flexDirection: "row",
29231
+ alignItems: "center"
29232
+ }
29233
+ });
29163
29234
 
29164
29235
  const truth = () => true;
29165
29236
 
@@ -41296,7 +41367,7 @@ const init = function (options) {
41296
41367
 
41297
41368
  // This file is processed by a Rollup plugin (replace) to inject the production
41298
41369
  const libName = "@khanacademy/perseus";
41299
- const libVersion = "20.0.1";
41370
+ const libVersion = "20.1.0";
41300
41371
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
41301
41372
 
41302
41373
  const apiVersion = {