@khanacademy/perseus-editor 14.0.1 → 14.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -33,6 +33,8 @@ var caretDoubleUpIcon = require('@phosphor-icons/core/bold/caret-double-up-bold.
33
33
  var caretDownIcon = require('@phosphor-icons/core/bold/caret-down-bold.svg');
34
34
  var caretUpIcon = require('@phosphor-icons/core/bold/caret-up-bold.svg');
35
35
  var trashIcon = require('@phosphor-icons/core/bold/trash-bold.svg');
36
+ var copyIcon = require('@phosphor-icons/core/assets/regular/copy.svg');
37
+ var autoPasteIcon = require('@phosphor-icons/core/assets/regular/note-pencil.svg');
36
38
  var arrowFatDown = require('@phosphor-icons/core/regular/arrow-fat-down.svg');
37
39
  var arrowFatLeft = require('@phosphor-icons/core/regular/arrow-fat-left.svg');
38
40
  var arrowFatRight = require('@phosphor-icons/core/regular/arrow-fat-right.svg');
@@ -80,6 +82,8 @@ var caretDoubleUpIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretDoubleU
80
82
  var caretDownIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretDownIcon);
81
83
  var caretUpIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretUpIcon);
82
84
  var trashIcon__default = /*#__PURE__*/_interopDefaultLegacy(trashIcon);
85
+ var copyIcon__default = /*#__PURE__*/_interopDefaultLegacy(copyIcon);
86
+ var autoPasteIcon__default = /*#__PURE__*/_interopDefaultLegacy(autoPasteIcon);
83
87
  var arrowFatDown__default = /*#__PURE__*/_interopDefaultLegacy(arrowFatDown);
84
88
  var arrowFatLeft__default = /*#__PURE__*/_interopDefaultLegacy(arrowFatLeft);
85
89
  var arrowFatRight__default = /*#__PURE__*/_interopDefaultLegacy(arrowFatRight);
@@ -91,7 +95,7 @@ var arrowCounterClockwise__default = /*#__PURE__*/_interopDefaultLegacy(arrowCou
91
95
 
92
96
  // This file is processed by a Rollup plugin (replace) to inject the production
93
97
  const libName = "@khanacademy/perseus-editor";
94
- const libVersion = "14.0.1";
98
+ const libVersion = "14.1.1";
95
99
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
96
100
 
97
101
  function _extends() {
@@ -268,7 +272,7 @@ const JsonEditor = createReactClass__default["default"]({
268
272
  });
269
273
 
270
274
  const {
271
- InlineIcon: InlineIcon$a
275
+ InlineIcon: InlineIcon$b
272
276
  } = perseus.components;
273
277
  class SectionControlButton extends React__namespace.Component {
274
278
  render() {
@@ -286,13 +290,13 @@ class SectionControlButton extends React__namespace.Component {
286
290
  role: "button",
287
291
  hideDefaultFocusRing: true,
288
292
  "aria-label": title,
289
- style: styles$T.button
293
+ style: styles$U.button
290
294
  }, _ref => {
291
- return /*#__PURE__*/React__namespace.createElement(InlineIcon$a, icon);
295
+ return /*#__PURE__*/React__namespace.createElement(InlineIcon$b, icon);
292
296
  });
293
297
  }
294
298
  }
295
- const styles$T = aphrodite.StyleSheet.create({
299
+ const styles$U = aphrodite.StyleSheet.create({
296
300
  button: {
297
301
  backgroundColor: wonderBlocksTokens.color.gold,
298
302
  margin: 2,
@@ -20673,11 +20677,11 @@ class Spring extends React__namespace.Component {
20673
20677
  } = this.props;
20674
20678
  return React__namespace.createElement(wonderBlocksCore.View, {
20675
20679
  "aria-hidden": "true",
20676
- style: [styles$S.grow, style]
20680
+ style: [styles$T.grow, style]
20677
20681
  });
20678
20682
  }
20679
20683
  }
20680
- const styles$S = aphrodite.StyleSheet.create({
20684
+ const styles$T = aphrodite.StyleSheet.create({
20681
20685
  grow: {
20682
20686
  flexGrow: 1
20683
20687
  }
@@ -20720,7 +20724,7 @@ const Spacing = {
20720
20724
  };
20721
20725
 
20722
20726
  const {
20723
- InlineIcon: InlineIcon$9
20727
+ InlineIcon: InlineIcon$a
20724
20728
  } = perseus.components;
20725
20729
  const {
20726
20730
  iconChevronDown: iconChevronDown$1,
@@ -20830,7 +20834,7 @@ class WidgetEditor extends React__namespace.Component {
20830
20834
  className: "perseus-widget-editor-title-id",
20831
20835
  href: "#",
20832
20836
  onClick: this._toggleWidget
20833
- }, this.props.id, this.state.showWidget ? /*#__PURE__*/React__namespace.createElement(InlineIcon$9, iconChevronDown$1) : /*#__PURE__*/React__namespace.createElement(InlineIcon$9, iconChevronRight)), supportsStaticMode && /*#__PURE__*/React__namespace.createElement(LabeledSwitch$1, {
20837
+ }, this.props.id, this.state.showWidget ? /*#__PURE__*/React__namespace.createElement(InlineIcon$a, iconChevronDown$1) : /*#__PURE__*/React__namespace.createElement(InlineIcon$a, iconChevronRight)), supportsStaticMode && /*#__PURE__*/React__namespace.createElement(LabeledSwitch$1, {
20834
20838
  label: "Static",
20835
20839
  checked: !!widgetInfo.static,
20836
20840
  onChange: this._setStatic
@@ -20914,13 +20918,13 @@ class WidgetSelect extends React__namespace.Component {
20914
20918
  * that collapse a region.
20915
20919
  */
20916
20920
  function ToggleableCaret(props) {
20917
- const iconStyle = props.isExpanded ? styles$R.expanded : styles$R.collapsed;
20921
+ const iconStyle = props.isExpanded ? styles$S.expanded : styles$S.collapsed;
20918
20922
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
20919
20923
  icon: caretRight__default["default"],
20920
20924
  style: iconStyle
20921
20925
  });
20922
20926
  }
20923
- const styles$R = aphrodite.StyleSheet.create({
20927
+ const styles$S = aphrodite.StyleSheet.create({
20924
20928
  collapsed: {
20925
20929
  transition: ".15s"
20926
20930
  },
@@ -20950,16 +20954,16 @@ class TexErrorView extends React__namespace.Component {
20950
20954
  showErrors
20951
20955
  } = this.state;
20952
20956
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20953
- style: styles$Q.errorContainer
20957
+ style: styles$R.errorContainer
20954
20958
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20955
- style: styles$Q.title,
20959
+ style: styles$R.title,
20956
20960
  onClick: this.handleToggleTexErrors
20957
20961
  }, /*#__PURE__*/React__namespace.createElement(ToggleableCaret, {
20958
20962
  isExpanded: showErrors
20959
20963
  }), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20960
- style: styles$Q.errorExplanation
20964
+ style: styles$R.errorExplanation
20961
20965
  }, "If your math doesn't display correctly, these errors might help you troubleshoot. Message #content-kitchen for help."), showErrors && errorList.map((e, index) => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20962
- style: styles$Q.error,
20966
+ style: styles$R.error,
20963
20967
  key: index
20964
20968
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20965
20969
  style: {
@@ -20968,7 +20972,7 @@ class TexErrorView extends React__namespace.Component {
20968
20972
  }, e.math), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, e.message))));
20969
20973
  }
20970
20974
  }
20971
- const styles$Q = aphrodite.StyleSheet.create({
20975
+ const styles$R = aphrodite.StyleSheet.create({
20972
20976
  title: {
20973
20977
  backgroundColor: "#eee",
20974
20978
  fontSize: "1.25em",
@@ -21951,7 +21955,7 @@ class IframeContentRenderer extends React__namespace.Component {
21951
21955
 
21952
21956
  const {
21953
21957
  HUD: HUD$1,
21954
- InlineIcon: InlineIcon$8
21958
+ InlineIcon: InlineIcon$9
21955
21959
  } = perseus.components;
21956
21960
  const {
21957
21961
  iconCircleArrowDown: iconCircleArrowDown$1,
@@ -22106,7 +22110,7 @@ class ArticleEditor extends React__namespace.Component {
22106
22110
  onClick: () => {
22107
22111
  this._handleAddSectionAfter(this._sections().length - 1);
22108
22112
  }
22109
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$8, iconPlus$4), " Add a section")));
22113
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$9, iconPlus$4), " Add a section")));
22110
22114
  }
22111
22115
  _renderLinterHUD() {
22112
22116
  return /*#__PURE__*/React__namespace.createElement(HUD$1, {
@@ -22258,8 +22262,8 @@ class ArticleEditor extends React__namespace.Component {
22258
22262
  * Renders three buttons: "Phone", "Tablet", and "Desktop".
22259
22263
  */
22260
22264
  const {
22261
- ButtonGroup: ButtonGroup$5,
22262
- InlineIcon: InlineIcon$7
22265
+ ButtonGroup: ButtonGroup$8,
22266
+ InlineIcon: InlineIcon$8
22263
22267
  } = perseus.components;
22264
22268
  const {
22265
22269
  devices
@@ -22270,14 +22274,14 @@ const {
22270
22274
  iconTablet
22271
22275
  } = perseus.icons;
22272
22276
  const ViewportResizer = props => {
22273
- const phoneButtonContents = /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconMobilePhone), " Phone");
22274
- const tabletButtonContents = /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconTablet), " Tablet");
22275
- const desktopButtonContents = /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconDesktop), " Desktop");
22277
+ const phoneButtonContents = /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(InlineIcon$8, iconMobilePhone), " Phone");
22278
+ const tabletButtonContents = /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(InlineIcon$8, iconTablet), " Tablet");
22279
+ const desktopButtonContents = /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(InlineIcon$8, iconDesktop), " Desktop");
22276
22280
 
22277
22281
  // TODO(david): Allow input of custom viewport sizes.
22278
22282
  return /*#__PURE__*/React__namespace.createElement("span", {
22279
22283
  className: "viewport-resizer"
22280
- }, "Viewport:", " ", /*#__PURE__*/React__namespace.createElement(ButtonGroup$5, {
22284
+ }, "Viewport:", " ", /*#__PURE__*/React__namespace.createElement(ButtonGroup$8, {
22281
22285
  value: props.deviceType,
22282
22286
  allowEmpty: false,
22283
22287
  buttons: [{
@@ -23606,7 +23610,7 @@ class StructuredItemDiff extends React__namespace.Component {
23606
23610
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
23607
23611
  const {
23608
23612
  InfoTip: InfoTip$m,
23609
- InlineIcon: InlineIcon$6
23613
+ InlineIcon: InlineIcon$7
23610
23614
  } = perseus.components;
23611
23615
  const {
23612
23616
  iconCircleArrowDown,
@@ -23675,11 +23679,11 @@ class HintEditor extends React__namespace.Component {
23675
23679
  type: "button",
23676
23680
  className: this.props.isLast ? "hidden" : "",
23677
23681
  onClick: ___default["default"].partial(this.props.onMove, 1)
23678
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconCircleArrowDown)), " ", /*#__PURE__*/React__namespace.createElement("button", {
23682
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconCircleArrowDown)), " ", /*#__PURE__*/React__namespace.createElement("button", {
23679
23683
  type: "button",
23680
23684
  className: this.props.isFirst ? "hidden" : "",
23681
23685
  onClick: ___default["default"].partial(this.props.onMove, -1)
23682
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React__namespace.createElement(InfoTip$m, null, /*#__PURE__*/React__namespace.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React__namespace.createElement("input", {
23686
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React__namespace.createElement(InfoTip$m, null, /*#__PURE__*/React__namespace.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React__namespace.createElement("input", {
23683
23687
  type: "checkbox"
23684
23688
  // @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
23685
23689
  ,
@@ -23689,7 +23693,7 @@ class HintEditor extends React__namespace.Component {
23689
23693
  type: "button",
23690
23694
  className: "remove-hint simple-button orange",
23691
23695
  onClick: this.props.onRemove
23692
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconTrash$5), "Remove this hint", " ")));
23696
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconTrash$5), "Remove this hint", " ")));
23693
23697
  }
23694
23698
  }
23695
23699
  /* A single hint-row containing a hint editor and preview */
@@ -23901,7 +23905,7 @@ class CombinedHintsEditor extends React__namespace.Component {
23901
23905
  type: "button",
23902
23906
  className: "add-hint simple-button orange",
23903
23907
  onClick: this.addHint
23904
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconPlus$3), " Add a hint"))));
23908
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconPlus$3), " Add a hint"))));
23905
23909
  /* eslint-enable max-len */
23906
23910
  }
23907
23911
  }
@@ -24045,7 +24049,7 @@ class ItemExtrasEditor extends React__namespace.Component {
24045
24049
  }
24046
24050
  }
24047
24051
  const ItemExtraCheckbox = props => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
24048
- style: [styles$P.checkbox, props.indent ? styles$P.indented : undefined]
24052
+ style: [styles$Q.checkbox, props.indent ? styles$Q.indented : undefined]
24049
24053
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
24050
24054
  label: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
24051
24055
  style: {
@@ -24055,7 +24059,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React__namespace.createElement(w
24055
24059
  checked: props.checked,
24056
24060
  onChange: newCheckedState => props.onChange(newCheckedState)
24057
24061
  }));
24058
- const styles$P = aphrodite.StyleSheet.create({
24062
+ const styles$Q = aphrodite.StyleSheet.create({
24059
24063
  indented: {
24060
24064
  marginInlineStart: wonderBlocksTokens.spacing.large_24
24061
24065
  }
@@ -24718,12 +24722,12 @@ class SimpleButton extends React__namespace.Component {
24718
24722
  ...otherProps
24719
24723
  } = this.props;
24720
24724
  return /*#__PURE__*/React__namespace.createElement("div", _extends({
24721
- className: aphrodite.css(styles$O.baseButton, color === "green" && styles$O.green, color === "orange" && styles$O.orange),
24725
+ className: aphrodite.css(styles$P.baseButton, color === "green" && styles$P.green, color === "orange" && styles$P.orange),
24722
24726
  onClick: onClick
24723
24727
  }, otherProps), children);
24724
24728
  }
24725
24729
  }
24726
- const styles$O = aphrodite.StyleSheet.create({
24730
+ const styles$P = aphrodite.StyleSheet.create({
24727
24731
  baseButton: {
24728
24732
  top: "0",
24729
24733
  fontSize: "11px",
@@ -24768,7 +24772,7 @@ const styles$O = aphrodite.StyleSheet.create({
24768
24772
  });
24769
24773
 
24770
24774
  const {
24771
- InlineIcon: InlineIcon$5
24775
+ InlineIcon: InlineIcon$6
24772
24776
  } = perseus.components;
24773
24777
  const {
24774
24778
  iconChevronDown,
@@ -24936,23 +24940,23 @@ const LeafContainer = _ref2 => {
24936
24940
  } = _ref2;
24937
24941
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
24938
24942
  const previewHeading = hasPreviewHeading && /*#__PURE__*/React__namespace.createElement("div", {
24939
- className: aphrodite.css(styles$N.containerHeader)
24943
+ className: aphrodite.css(styles$O.containerHeader)
24940
24944
  }, /*#__PURE__*/React__namespace.createElement(Header, {
24941
24945
  depth: path.length,
24942
- className: aphrodite.css(styles$N.containerTitle)
24946
+ className: aphrodite.css(styles$O.containerTitle)
24943
24947
  }, capitalize(name)));
24944
24948
  return /*#__PURE__*/React__namespace.createElement("div", {
24945
- className: aphrodite.css(styles$N.container)
24949
+ className: aphrodite.css(styles$O.container)
24946
24950
  }, /*#__PURE__*/React__namespace.createElement("span", {
24947
- className: aphrodite.css(styles$N.row, styles$N.rowHeading)
24951
+ className: aphrodite.css(styles$O.row, styles$O.rowHeading)
24948
24952
  }, /*#__PURE__*/React__namespace.createElement("div", {
24949
- className: aphrodite.css(styles$N.columnLeft)
24953
+ className: aphrodite.css(styles$O.columnLeft)
24950
24954
  }, /*#__PURE__*/React__namespace.createElement("div", {
24951
- className: "pod-title " + aphrodite.css(styles$N.containerHeader)
24955
+ className: "pod-title " + aphrodite.css(styles$O.containerHeader)
24952
24956
  }, /*#__PURE__*/React__namespace.createElement("div", {
24953
- className: aphrodite.css(styles$N.containerTitle)
24957
+ className: aphrodite.css(styles$O.containerTitle)
24954
24958
  }, capitalize(name)), controls)), /*#__PURE__*/React__namespace.createElement("div", {
24955
- className: aphrodite.css(styles$N.columnRight)
24959
+ className: aphrodite.css(styles$O.columnRight)
24956
24960
  }, previewHeading)), children);
24957
24961
  };
24958
24962
  const ArrayContainer = props => {
@@ -24965,11 +24969,11 @@ const ArrayContainer = props => {
24965
24969
  actions
24966
24970
  } = props;
24967
24971
  return /*#__PURE__*/React__namespace.createElement("div", {
24968
- className: aphrodite.css(styles$N.container)
24972
+ className: aphrodite.css(styles$O.container)
24969
24973
  }, controls && /*#__PURE__*/React__namespace.createElement("div", {
24970
- className: aphrodite.css(styles$N.columnLeft, styles$N.containerHeader)
24974
+ className: aphrodite.css(styles$O.columnLeft, styles$O.containerHeader)
24971
24975
  }, controls), /*#__PURE__*/React__namespace.createElement("div", null, children), /*#__PURE__*/React__namespace.createElement("div", {
24972
- className: aphrodite.css(styles$N.columnLeft)
24976
+ className: aphrodite.css(styles$O.columnLeft)
24973
24977
  }, /*#__PURE__*/React__namespace.createElement("a", {
24974
24978
  href: "javascript:void 0",
24975
24979
  onClick: () => actions.addArrayElement(path, shape.elementShape)
@@ -24983,28 +24987,28 @@ const ObjectContainer = _ref3 => {
24983
24987
  path
24984
24988
  } = _ref3;
24985
24989
  const headingEditor = /*#__PURE__*/React__namespace.createElement("div", {
24986
- className: aphrodite.css(styles$N.containerHeader)
24990
+ className: aphrodite.css(styles$O.containerHeader)
24987
24991
  }, /*#__PURE__*/React__namespace.createElement(Header, {
24988
24992
  depth: path.length,
24989
- className: aphrodite.css(styles$N.containerTitle)
24993
+ className: aphrodite.css(styles$O.containerTitle)
24990
24994
  }, capitalize(name)), controls);
24991
24995
  const headingPreview = (name || controls) && /*#__PURE__*/React__namespace.createElement("div", {
24992
- className: aphrodite.css(styles$N.containerHeader, styles$N.previewCollectionHeader)
24996
+ className: aphrodite.css(styles$O.containerHeader, styles$O.previewCollectionHeader)
24993
24997
  }, /*#__PURE__*/React__namespace.createElement(Header, {
24994
24998
  depth: path.length,
24995
- className: aphrodite.css(styles$N.containerTitle)
24999
+ className: aphrodite.css(styles$O.containerTitle)
24996
25000
  }, capitalize(name)));
24997
25001
  const hasBothHeadings = headingEditor && headingPreview;
24998
25002
  return /*#__PURE__*/React__namespace.createElement("div", {
24999
- className: aphrodite.css(styles$N.container)
25003
+ className: aphrodite.css(styles$O.container)
25000
25004
  }, hasBothHeadings && /*#__PURE__*/React__namespace.createElement("span", {
25001
- className: aphrodite.css(styles$N.row)
25005
+ className: aphrodite.css(styles$O.row)
25002
25006
  }, /*#__PURE__*/React__namespace.createElement("div", {
25003
- className: aphrodite.css(styles$N.columnLeft)
25007
+ className: aphrodite.css(styles$O.columnLeft)
25004
25008
  }, headingEditor), /*#__PURE__*/React__namespace.createElement("div", {
25005
- className: aphrodite.css(styles$N.columnRight)
25009
+ className: aphrodite.css(styles$O.columnRight)
25006
25010
  }, headingPreview)), /*#__PURE__*/React__namespace.createElement("div", {
25007
- className: aphrodite.css(path.length > 0 && styles$N.contentIndent)
25011
+ className: aphrodite.css(path.length > 0 && styles$O.contentIndent)
25008
25012
  }, children));
25009
25013
  };
25010
25014
 
@@ -25124,11 +25128,11 @@ const ItemNodeContent = withStickiness(props => {
25124
25128
  className: "framework-perseus"
25125
25129
  }, lens(renderers).get(path));
25126
25130
  return /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("div", {
25127
- className: aphrodite.css(styles$N.row)
25131
+ className: aphrodite.css(styles$O.row)
25128
25132
  }, /*#__PURE__*/React__namespace.createElement("div", {
25129
- className: aphrodite.css(styles$N.columnLeft)
25133
+ className: aphrodite.css(styles$O.columnLeft)
25130
25134
  }, /*#__PURE__*/React__namespace.createElement("div", {
25131
- className: aphrodite.css(sticky && styles$N.sticky)
25135
+ className: aphrodite.css(sticky && styles$O.sticky)
25132
25136
  },
25133
25137
  /*#__PURE__*/
25134
25138
  // @ts-expect-error - TS2769 - No overload matches this call.
@@ -25136,9 +25140,9 @@ const ItemNodeContent = withStickiness(props => {
25136
25140
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25137
25141
  apiOptions: apiOptions
25138
25142
  })))), /*#__PURE__*/React__namespace.createElement("div", {
25139
- className: aphrodite.css(styles$N.columnRight)
25143
+ className: aphrodite.css(styles$O.columnRight)
25140
25144
  }, /*#__PURE__*/React__namespace.createElement("div", {
25141
- className: aphrodite.css(sticky && styles$N.sticky)
25145
+ className: aphrodite.css(sticky && styles$O.sticky)
25142
25146
  }, preview))));
25143
25147
  });
25144
25148
  const HintNodeContent = withStickiness(props => {
@@ -25154,13 +25158,13 @@ const HintNodeContent = withStickiness(props => {
25154
25158
  className: "framework-perseus"
25155
25159
  }, lens(renderers).get(path));
25156
25160
  return /*#__PURE__*/React__namespace.createElement("div", {
25157
- className: aphrodite.css(styles$N.row)
25161
+ className: aphrodite.css(styles$O.row)
25158
25162
  }, /*#__PURE__*/React__namespace.createElement("div", {
25159
- className: aphrodite.css(styles$N.columnLeft)
25163
+ className: aphrodite.css(styles$O.columnLeft)
25160
25164
  }, /*#__PURE__*/React__namespace.createElement("div", {
25161
- className: aphrodite.css(sticky && styles$N.sticky)
25165
+ className: aphrodite.css(sticky && styles$O.sticky)
25162
25166
  }, /*#__PURE__*/React__namespace.createElement(HintEditor, _extends({}, data, {
25163
- className: aphrodite.css(styles$N.hintEditor),
25167
+ className: aphrodite.css(styles$O.hintEditor),
25164
25168
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25165
25169
  apiOptions: apiOptions,
25166
25170
  showTitle: false,
@@ -25175,9 +25179,9 @@ const HintNodeContent = withStickiness(props => {
25175
25179
  isFirst: true,
25176
25180
  isLast: true
25177
25181
  })))), /*#__PURE__*/React__namespace.createElement("div", {
25178
- className: aphrodite.css(styles$N.columnRight)
25182
+ className: aphrodite.css(styles$O.columnRight)
25179
25183
  }, /*#__PURE__*/React__namespace.createElement("div", {
25180
- className: aphrodite.css(sticky && styles$N.sticky)
25184
+ className: aphrodite.css(sticky && styles$O.sticky)
25181
25185
  }, preview)));
25182
25186
  });
25183
25187
  const TagsNodeContent = props => {
@@ -25194,9 +25198,9 @@ const TagsNodeContent = props => {
25194
25198
  return null;
25195
25199
  }
25196
25200
  return /*#__PURE__*/React__namespace.createElement("div", {
25197
- className: aphrodite.css(styles$N.columnLeft)
25201
+ className: aphrodite.css(styles$O.columnLeft)
25198
25202
  }, /*#__PURE__*/React__namespace.createElement("div", {
25199
- className: aphrodite.css(styles$N.tagsEditor)
25203
+ className: aphrodite.css(styles$O.tagsEditor)
25200
25204
  }, /*#__PURE__*/React__namespace.createElement(GroupMetadataEditor, {
25201
25205
  value: data,
25202
25206
  onChange: newVal => actions.setValueAtPath(path, newVal),
@@ -25227,31 +25231,31 @@ const ArrayNodeContent = props => {
25227
25231
  const subpath = path.concat(i);
25228
25232
  const controls = [i > 0 && /*#__PURE__*/React__namespace.createElement("div", {
25229
25233
  key: "moveArrayElementUp",
25230
- className: aphrodite.css(styles$N.control)
25234
+ className: aphrodite.css(styles$O.control)
25231
25235
  }, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
25232
25236
  color: "orange",
25233
25237
  title: "Move up",
25234
25238
  onClick: () => actions.moveArrayElementUp(subpath)
25235
25239
  }, /*#__PURE__*/React__namespace.createElement("div", {
25236
- className: aphrodite.css(styles$N.verticalFlip)
25237
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$5, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React__namespace.createElement("div", {
25240
+ className: aphrodite.css(styles$O.verticalFlip)
25241
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React__namespace.createElement("div", {
25238
25242
  key: "moveArrayElementDown",
25239
- className: aphrodite.css(styles$N.control)
25243
+ className: aphrodite.css(styles$O.control)
25240
25244
  }, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
25241
25245
  color: "orange",
25242
25246
  title: "Move down",
25243
25247
  onClick: () => actions.moveArrayElementDown(subpath)
25244
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$5, iconChevronDown))), /*#__PURE__*/React__namespace.createElement("div", {
25248
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React__namespace.createElement("div", {
25245
25249
  key: "removeArrayElement",
25246
- className: aphrodite.css(styles$N.control)
25250
+ className: aphrodite.css(styles$O.control)
25247
25251
  }, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
25248
25252
  color: "orange",
25249
25253
  title: "Delete",
25250
25254
  onClick: () => actions.removeArrayElement(subpath)
25251
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$5, iconTrash$4)))];
25255
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconTrash$4)))];
25252
25256
  return /*#__PURE__*/React__namespace.createElement("div", {
25253
25257
  key: i,
25254
- className: aphrodite.css(styles$N.arrayElement, !elementIsLeaf && styles$N.arrayElementAndNotLeaf)
25258
+ className: aphrodite.css(styles$O.arrayElement, !elementIsLeaf && styles$O.arrayElementAndNotLeaf)
25255
25259
  }, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
25256
25260
  key: i,
25257
25261
  shape: shape.elementShape,
@@ -25277,7 +25281,7 @@ const ObjectNodeContent = props => {
25277
25281
  // made sense to the shape's author is the order in which we'll iterate :)
25278
25282
  const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React__namespace.createElement("div", {
25279
25283
  key: subkey,
25280
- className: aphrodite.css(styles$N.objectElement)
25284
+ className: aphrodite.css(styles$O.objectElement)
25281
25285
  }, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
25282
25286
  shape: shape.shape[subkey],
25283
25287
  data: data[subkey],
@@ -25447,7 +25451,7 @@ class MultiRendererEditor extends React__namespace.Component {
25447
25451
  }, this._renderContent());
25448
25452
  }
25449
25453
  }
25450
- const styles$N = aphrodite.StyleSheet.create({
25454
+ const styles$O = aphrodite.StyleSheet.create({
25451
25455
  // This is used in a number of places throughout this file.
25452
25456
  container: {},
25453
25457
  // eslint-disable-next-line react-native/no-unused-styles
@@ -26027,7 +26031,7 @@ class DeprecatedStandinEditor extends React__namespace.Component {
26027
26031
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
26028
26032
  const {
26029
26033
  InfoTip: InfoTip$j,
26030
- InlineIcon: InlineIcon$4
26034
+ InlineIcon: InlineIcon$5
26031
26035
  } = perseus.components;
26032
26036
  const {
26033
26037
  iconPlus: iconPlus$2,
@@ -26159,14 +26163,14 @@ class DropdownEditor extends React__namespace.Component {
26159
26163
  this, i)
26160
26164
  }, /*#__PURE__*/React__namespace.createElement("span", {
26161
26165
  className: "remove-choice"
26162
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, iconTrash$3)))));
26166
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$5, iconTrash$3)))));
26163
26167
  }, this)), /*#__PURE__*/React__namespace.createElement("div", {
26164
26168
  className: "add-choice-container"
26165
26169
  }, /*#__PURE__*/React__namespace.createElement("a", {
26166
26170
  href: "#",
26167
26171
  className: "simple-button orange",
26168
26172
  onClick: this.addChoice
26169
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, iconPlus$2), " Add a choice", " ")));
26173
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$5, iconPlus$2), " Add a choice", " ")));
26170
26174
  }
26171
26175
  }
26172
26176
 
@@ -26417,7 +26421,7 @@ const SortableItem = createReactClass__default["default"]({
26417
26421
  }
26418
26422
  return /*#__PURE__*/React__namespace.createElement("li", {
26419
26423
  draggable: this.props.draggable,
26420
- className: [dragState, aphrodite.css(styles$M.sortableListItem)].join(" "),
26424
+ className: [dragState, aphrodite.css(styles$N.sortableListItem)].join(" "),
26421
26425
  onDragStart: this.handleDragStart,
26422
26426
  onDrop: this.handleDrop,
26423
26427
  onDragEnter: this.handleDragEnter,
@@ -26425,7 +26429,7 @@ const SortableItem = createReactClass__default["default"]({
26425
26429
  }, this.props.component);
26426
26430
  }
26427
26431
  });
26428
- const styles$M = aphrodite.StyleSheet.create({
26432
+ const styles$N = aphrodite.StyleSheet.create({
26429
26433
  sortableListItem: {
26430
26434
  margin: "5px 0"
26431
26435
  }
@@ -26685,13 +26689,13 @@ class ExpressionEditor extends React__namespace.Component {
26685
26689
  onChange: this.handleToggleDiv
26686
26690
  }));
26687
26691
  return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingSmall, null, "Global Options"), /*#__PURE__*/React__namespace.createElement("div", {
26688
- className: aphrodite.css(styles$L.paddedY)
26692
+ className: aphrodite.css(styles$M.paddedY)
26689
26693
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
26690
26694
  label: "Visible label",
26691
26695
  value: this.props.visibleLabel || "",
26692
26696
  onChange: this.change("visibleLabel")
26693
26697
  }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."))), /*#__PURE__*/React__namespace.createElement("div", {
26694
- className: aphrodite.css(styles$L.paddedY)
26698
+ className: aphrodite.css(styles$M.paddedY)
26695
26699
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
26696
26700
  label: "Aria label",
26697
26701
  value: this.props.ariaLabel || "",
@@ -26700,13 +26704,13 @@ class ExpressionEditor extends React__namespace.Component {
26700
26704
  href: "https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",
26701
26705
  target: "_blank"
26702
26706
  }, "this article.")))), /*#__PURE__*/React__namespace.createElement("div", {
26703
- className: aphrodite.css(styles$L.paddedY)
26707
+ className: aphrodite.css(styles$M.paddedY)
26704
26708
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
26705
26709
  label: "Function variables",
26706
26710
  value: this.state.functionsInternal,
26707
26711
  onChange: this.handleFunctions
26708
26712
  }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React__namespace.createElement("div", {
26709
- className: aphrodite.css(styles$L.paddedY)
26713
+ className: aphrodite.css(styles$M.paddedY)
26710
26714
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
26711
26715
  label: "Use \xD7 instead of \u22C5 for multiplication",
26712
26716
  checked: this.props.times,
@@ -26716,7 +26720,7 @@ class ExpressionEditor extends React__namespace.Component {
26716
26720
  });
26717
26721
  }
26718
26722
  }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React__namespace.createElement("div", {
26719
- className: aphrodite.css(styles$L.paddedY)
26723
+ className: aphrodite.css(styles$M.paddedY)
26720
26724
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingXSmall, null, "Button Sets"), buttonSetChoices), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingSmall, null, "Answers"), /*#__PURE__*/React__namespace.createElement("p", {
26721
26725
  style: {
26722
26726
  margin: "4px 0"
@@ -26783,18 +26787,18 @@ class AnswerOption extends React__namespace.Component {
26783
26787
  color: "destructive",
26784
26788
  light: true
26785
26789
  }, "Delete");
26786
- const answerStatusCss = aphrodite.css(styles$L.answerStatus, this.props.considered === "wrong" && styles$L.answerStatusWrong, this.props.considered === "correct" && styles$L.answerStatusCorrect, this.props.considered === "ungraded" && styles$L.answerStatusUngraded);
26790
+ const answerStatusCss = aphrodite.css(styles$M.answerStatus, this.props.considered === "wrong" && styles$M.answerStatusWrong, this.props.considered === "correct" && styles$M.answerStatusCorrect, this.props.considered === "ungraded" && styles$M.answerStatusUngraded);
26787
26791
  return /*#__PURE__*/React__namespace.createElement("div", {
26788
- className: aphrodite.css(styles$L.answerOption)
26792
+ className: aphrodite.css(styles$M.answerOption)
26789
26793
  }, /*#__PURE__*/React__namespace.createElement("div", {
26790
- className: aphrodite.css(styles$L.answerHandle)
26794
+ className: aphrodite.css(styles$M.answerHandle)
26791
26795
  }), /*#__PURE__*/React__namespace.createElement("div", {
26792
- className: aphrodite.css(styles$L.answerBody)
26796
+ className: aphrodite.css(styles$M.answerBody)
26793
26797
  }, /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("button", {
26794
26798
  onClick: this.toggleConsidered,
26795
26799
  className: answerStatusCss
26796
26800
  }, this.props.considered), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(perseus.Expression, this.props.expressionProps))), /*#__PURE__*/React__namespace.createElement("div", {
26797
- className: aphrodite.css(styles$L.paddedY, styles$L.paddedX)
26801
+ className: aphrodite.css(styles$M.paddedY, styles$M.paddedX)
26798
26802
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
26799
26803
  label: "Answer expression must have the same form.",
26800
26804
  checked: this.props.form,
@@ -26804,7 +26808,7 @@ class AnswerOption extends React__namespace.Component {
26804
26808
  });
26805
26809
  }
26806
26810
  }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React__namespace.createElement("div", {
26807
- className: aphrodite.css(styles$L.paddedY, styles$L.paddedX)
26811
+ className: aphrodite.css(styles$M.paddedY, styles$M.paddedX)
26808
26812
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
26809
26813
  label: "Answer expression must be fully expanded and simplified.",
26810
26814
  checked: this.props.simplify,
@@ -26814,11 +26818,11 @@ class AnswerOption extends React__namespace.Component {
26814
26818
  });
26815
26819
  }
26816
26820
  }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React__namespace.createElement("div", {
26817
- className: aphrodite.css(styles$L.buttonRow, styles$L.paddedY)
26821
+ className: aphrodite.css(styles$M.buttonRow, styles$M.paddedY)
26818
26822
  }, removeButton)));
26819
26823
  }
26820
26824
  }
26821
- const styles$L = aphrodite.StyleSheet.create({
26825
+ const styles$M = aphrodite.StyleSheet.create({
26822
26826
  paddedX: {
26823
26827
  paddingLeft: wonderBlocksTokens.spacing.xSmall_8,
26824
26828
  paddingRight: wonderBlocksTokens.spacing.xSmall_8
@@ -26864,7 +26868,7 @@ const styles$L = aphrodite.StyleSheet.create({
26864
26868
 
26865
26869
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
26866
26870
  const {
26867
- InlineIcon: InlineIcon$3,
26871
+ InlineIcon: InlineIcon$4,
26868
26872
  TextInput: TextInput$5
26869
26873
  } = perseus.components;
26870
26874
  const {
@@ -26930,10 +26934,10 @@ class GradedGroupEditor extends React__namespace.Component {
26930
26934
  }, /*#__PURE__*/React__namespace.createElement("div", {
26931
26935
  className: "perseus-widget-row"
26932
26936
  }, /*#__PURE__*/React__namespace.createElement("label", {
26933
- className: aphrodite.css(styles$K.title)
26937
+ className: aphrodite.css(styles$L.title)
26934
26938
  }, "Title:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$5, {
26935
26939
  value: this.props.title,
26936
- className: aphrodite.css(styles$K.input)
26940
+ className: aphrodite.css(styles$L.input)
26937
26941
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26938
26942
  ,
26939
26943
  onChange: this.change("title")
@@ -26955,10 +26959,10 @@ class GradedGroupEditor extends React__namespace.Component {
26955
26959
  },
26956
26960
  className: "add-hint simple-button orange",
26957
26961
  onClick: this.handleAddHint
26958
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$3, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React__namespace.createElement("div", {
26962
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React__namespace.createElement("div", {
26959
26963
  className: "perseus-hint-editor"
26960
26964
  }, /*#__PURE__*/React__namespace.createElement("div", {
26961
- className: aphrodite.css(styles$K.hintsTitle)
26965
+ className: aphrodite.css(styles$L.hintsTitle)
26962
26966
  }, "Hint"), /*#__PURE__*/React__namespace.createElement(Editor, {
26963
26967
  ref: this.hintEditor,
26964
26968
  content: this.props.hint ? this.props.hint.content : "",
@@ -26977,10 +26981,10 @@ class GradedGroupEditor extends React__namespace.Component {
26977
26981
  type: "button",
26978
26982
  className: "remove-hint simple-button orange",
26979
26983
  onClick: this.handleRemoveHint
26980
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$3, iconTrash$2), " Remove this hint")));
26984
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, iconTrash$2), " Remove this hint")));
26981
26985
  }
26982
26986
  }
26983
- const styles$K = aphrodite.StyleSheet.create({
26987
+ const styles$L = aphrodite.StyleSheet.create({
26984
26988
  title: {
26985
26989
  fontSize: 18,
26986
26990
  fontWeight: "bold"
@@ -27066,7 +27070,7 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
27066
27070
 
27067
27071
  /* eslint-disable react/forbid-prop-types, react/no-unsafe */
27068
27072
  const {
27069
- ButtonGroup: ButtonGroup$4,
27073
+ ButtonGroup: ButtonGroup$7,
27070
27074
  InfoTip: InfoTip$h,
27071
27075
  RangeInput: RangeInput$6
27072
27076
  } = perseus.components;
@@ -27486,7 +27490,7 @@ const GraphSettings = createReactClass__default["default"]({
27486
27490
  onChange: this.changeSnapStep
27487
27491
  }))), /*#__PURE__*/React__namespace.createElement("div", {
27488
27492
  className: "perseus-widget-row"
27489
- }, /*#__PURE__*/React__namespace.createElement("label", null, "Markings: "), /*#__PURE__*/React__namespace.createElement(ButtonGroup$4, {
27493
+ }, /*#__PURE__*/React__namespace.createElement("label", null, "Markings: "), /*#__PURE__*/React__namespace.createElement(ButtonGroup$7, {
27490
27494
  value: this.props.markings,
27491
27495
  allowEmpty: false,
27492
27496
  buttons: [{
@@ -27932,7 +27936,7 @@ class IframeEditor extends React__namespace.Component {
27932
27936
  /* eslint-disable jsx-a11y/anchor-is-valid */
27933
27937
  const {
27934
27938
  InfoTip: InfoTip$f,
27935
- InlineIcon: InlineIcon$2,
27939
+ InlineIcon: InlineIcon$3,
27936
27940
  RangeInput: RangeInput$5
27937
27941
  } = perseus.components;
27938
27942
  const defaultBoxSize = 400;
@@ -28016,7 +28020,7 @@ class ImageEditor extends React__namespace.Component {
28016
28020
  // eslint-disable-next-line react/jsx-no-bind
28017
28021
  ,
28018
28022
  onClick: this.removeLabel.bind(this, i)
28019
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$2, perseus.icons.iconTrash))));
28023
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$3, perseus.icons.iconTrash))));
28020
28024
  }
28021
28025
  change() {
28022
28026
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
@@ -28320,6 +28324,111 @@ class InputNumberEditor extends React__namespace.Component {
28320
28324
  }
28321
28325
  }
28322
28326
 
28327
+ /* eslint-disable jsx-a11y/anchor-is-valid */
28328
+ const {
28329
+ InlineIcon: InlineIcon$2
28330
+ } = perseus.components;
28331
+ class ElementContainer extends React__namespace.Component {
28332
+ static defaultProps = {
28333
+ initiallyVisible: false,
28334
+ title: "More"
28335
+ };
28336
+ constructor(props) {
28337
+ super(props);
28338
+ this.state = {
28339
+ show: props.initiallyVisible
28340
+ };
28341
+ }
28342
+ toggle = e => {
28343
+ e.preventDefault();
28344
+ this.setState({
28345
+ show: !this.state.show
28346
+ });
28347
+ };
28348
+ render() {
28349
+ return /*#__PURE__*/React__namespace.createElement("div", {
28350
+ className: "perseus-interaction-element"
28351
+ }, /*#__PURE__*/React__namespace.createElement("a", {
28352
+ href: "#",
28353
+ className: "perseus-interaction-element-title " + (this.state.show ? "open" : "closed"),
28354
+ onClick: this.toggle
28355
+ }, this.state.show ? /*#__PURE__*/React__namespace.createElement(InlineIcon$2, perseus.icons.iconChevronDown) : /*#__PURE__*/React__namespace.createElement(InlineIcon$2, perseus.icons.iconChevronRight), this.props.title), /*#__PURE__*/React__namespace.createElement("div", {
28356
+ className: "perseus-interaction-element-content " + (this.state.show ? "enter" : "leave")
28357
+ }, this.props.children, (this.props.onUp != null || this.props.onDown != null || this.props.onDelete != null) && /*#__PURE__*/React__namespace.createElement("div", {
28358
+ className: "edit-controls"
28359
+ }, this.props.onUp != null && /*#__PURE__*/React__namespace.createElement("button", {
28360
+ onClick: this.props.onUp
28361
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$2, perseus.icons.iconCircleArrowUp)), this.props.onDown != null && /*#__PURE__*/React__namespace.createElement("button", {
28362
+ onClick: this.props.onDown
28363
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$2, perseus.icons.iconCircleArrowDown)), this.props.onDelete != null && /*#__PURE__*/React__namespace.createElement("button", {
28364
+ onClick: this.props.onDelete
28365
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$2, perseus.icons.iconTrash)))));
28366
+ }
28367
+ }
28368
+
28369
+ const {
28370
+ ButtonGroup: ButtonGroup$6
28371
+ } = perseus.components;
28372
+ const COLORS = [perseus.KhanColors.BLACK, perseus.KhanColors.BLUE, perseus.KhanColors.GREEN, perseus.KhanColors.PINK, perseus.KhanColors.PURPLE, perseus.KhanColors.RED, perseus.KhanColors.GRAY];
28373
+ const LIGHT_COLORS = [perseus.KhanColors.LIGHT_BLUE, perseus.KhanColors.LIGHT_ORANGE, perseus.KhanColors.LIGHT_PINK, perseus.KhanColors.LIGHT_GREEN, perseus.KhanColors.LIGHT_PURPLE, perseus.KhanColors.LIGHT_RED, "#fff"];
28374
+ class ColorPicker extends React__namespace.Component {
28375
+ static defaultProps = {
28376
+ value: perseus.KhanColors.BLACK,
28377
+ lightColors: false
28378
+ };
28379
+ render() {
28380
+ const colors = this.props.lightColors ? LIGHT_COLORS : COLORS;
28381
+ return /*#__PURE__*/React__namespace.createElement(ButtonGroup$6, {
28382
+ value: this.props.value,
28383
+ allowEmpty: false,
28384
+ buttons: ___default["default"].map(colors, color => {
28385
+ return {
28386
+ value: color,
28387
+ content: /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("span", {
28388
+ className: "colorpicker-circle",
28389
+ style: {
28390
+ background: color
28391
+ }
28392
+ }), "\xA0")
28393
+ };
28394
+ }),
28395
+ onChange: this.props.onChange
28396
+ });
28397
+ }
28398
+ }
28399
+
28400
+ const {
28401
+ ButtonGroup: ButtonGroup$5
28402
+ } = perseus.components;
28403
+ class DashPicker extends React__namespace.Component {
28404
+ static defaultProps = {
28405
+ value: ""
28406
+ };
28407
+ render() {
28408
+ return /*#__PURE__*/React__namespace.createElement(ButtonGroup$5, {
28409
+ value: this.props.value,
28410
+ allowEmpty: false,
28411
+ buttons: [{
28412
+ value: "",
28413
+ content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2014")
28414
+ }, {
28415
+ value: "-",
28416
+ content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2013\u2013\u2013")
28417
+ }, {
28418
+ value: "- ",
28419
+ content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2013\xA0\xA0\u2013")
28420
+ }, {
28421
+ value: ".",
28422
+ content: /*#__PURE__*/React__namespace.createElement("span", null, "\xB7\xB7\xB7\xB7")
28423
+ }, {
28424
+ value: ". ",
28425
+ content: /*#__PURE__*/React__namespace.createElement("span", null, "\xB7 \xB7 \xB7")
28426
+ }],
28427
+ onChange: this.props.onChange
28428
+ });
28429
+ }
28430
+ }
28431
+
28323
28432
  /**
28324
28433
  * A simple Mathquill MathField input for the InteractionEditor.
28325
28434
  * Unlike our other uses of Mathquill, we're not using a keypad here;
@@ -28366,13 +28475,13 @@ function MathquillInput(props) {
28366
28475
  }
28367
28476
  });
28368
28477
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
28369
- style: styles$J.outerWrapper
28478
+ style: styles$K.outerWrapper
28370
28479
  }, /*#__PURE__*/React__namespace.createElement("span", {
28371
28480
  ref: mathFieldWrapperRef,
28372
28481
  className: "perseus-math-input mq-editable-field mq-math-mode"
28373
28482
  }));
28374
28483
  }
28375
- const styles$J = aphrodite.StyleSheet.create({
28484
+ const styles$K = aphrodite.StyleSheet.create({
28376
28485
  outerWrapper: {
28377
28486
  display: "inline-block",
28378
28487
  borderStyle: "solid",
@@ -28432,12 +28541,12 @@ class FunctionEditor extends React__namespace.Component {
28432
28541
  onChange: this.change("rangeMax")
28433
28542
  }), /*#__PURE__*/React__namespace.createElement(TeX, null, "\\Large)")), /*#__PURE__*/React__namespace.createElement("div", {
28434
28543
  className: "perseus-widget-row"
28435
- }, /*#__PURE__*/React__namespace.createElement(perseus.ColorPicker, {
28544
+ }, /*#__PURE__*/React__namespace.createElement(ColorPicker, {
28436
28545
  value: this.props.color,
28437
28546
  onChange: this.change("color")
28438
28547
  })), /*#__PURE__*/React__namespace.createElement("div", {
28439
28548
  className: "perseus-widget-row"
28440
- }, /*#__PURE__*/React__namespace.createElement(perseus.DashPicker, {
28549
+ }, /*#__PURE__*/React__namespace.createElement(DashPicker, {
28441
28550
  value: this.props.strokeDasharray,
28442
28551
  onChange: this.change("strokeDasharray")
28443
28552
  })), /*#__PURE__*/React__namespace.createElement("div", {
@@ -28503,13 +28612,42 @@ class LabelEditor extends React__namespace.Component {
28503
28612
  onChange: this.change("coordY")
28504
28613
  }), /*#__PURE__*/React__namespace.createElement(TeX, null, "\\Large)")), /*#__PURE__*/React__namespace.createElement("div", {
28505
28614
  className: "perseus-widget-row"
28506
- }, /*#__PURE__*/React__namespace.createElement(perseus.ColorPicker, {
28615
+ }, /*#__PURE__*/React__namespace.createElement(ColorPicker, {
28507
28616
  value: this.props.color,
28508
28617
  onChange: this.change("color")
28509
28618
  })));
28510
28619
  }
28511
28620
  }
28512
28621
 
28622
+ const {
28623
+ ButtonGroup: ButtonGroup$4
28624
+ } = perseus.components;
28625
+ class ArrowPicker extends React__namespace.Component {
28626
+ static defaultProps = {
28627
+ value: ""
28628
+ };
28629
+ render() {
28630
+ return /*#__PURE__*/React__namespace.createElement(ButtonGroup$4, {
28631
+ value: this.props.value,
28632
+ allowEmpty: false,
28633
+ buttons: [{
28634
+ value: "",
28635
+ content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2014")
28636
+ }, {
28637
+ value: "->",
28638
+ content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2192")
28639
+ }
28640
+ /*
28641
+ TODO(eater): fix khan-exercises so these are supported
28642
+ {value: "<-", content: <span>&#x2190;</span>},
28643
+ {value: "<->", content: <span>&#x2194;</span>}
28644
+ */],
28645
+
28646
+ onChange: this.props.onChange
28647
+ });
28648
+ }
28649
+ }
28650
+
28513
28651
  const {
28514
28652
  NumberInput: NumberInput$c
28515
28653
  } = perseus.components;
@@ -28564,15 +28702,15 @@ class LineEditor extends React__namespace.Component {
28564
28702
  onChange: this.change("endY")
28565
28703
  }), /*#__PURE__*/React__namespace.createElement(TeX, null, "\\Large)")), /*#__PURE__*/React__namespace.createElement("div", {
28566
28704
  className: "perseus-widget-row"
28567
- }, /*#__PURE__*/React__namespace.createElement(perseus.ColorPicker, {
28705
+ }, /*#__PURE__*/React__namespace.createElement(ColorPicker, {
28568
28706
  value: this.props.color,
28569
28707
  onChange: this.change("color")
28570
28708
  })), /*#__PURE__*/React__namespace.createElement("div", {
28571
28709
  className: "perseus-widget-row"
28572
- }, /*#__PURE__*/React__namespace.createElement(perseus.DashPicker, {
28710
+ }, /*#__PURE__*/React__namespace.createElement(DashPicker, {
28573
28711
  value: this.props.strokeDasharray,
28574
28712
  onChange: this.change("strokeDasharray")
28575
- }), "\xA0 \xA0", /*#__PURE__*/React__namespace.createElement(perseus.ArrowPicker, {
28713
+ }), "\xA0 \xA0", /*#__PURE__*/React__namespace.createElement(ArrowPicker, {
28576
28714
  value: this.props.arrows,
28577
28715
  onChange: this.change("arrows")
28578
28716
  })), /*#__PURE__*/React__namespace.createElement("div", {
@@ -28858,12 +28996,12 @@ class ParametricEditor extends React__namespace.Component {
28858
28996
  onChange: this.change("rangeMax")
28859
28997
  }), /*#__PURE__*/React__namespace.createElement(TeX, null, "\\Large)")), /*#__PURE__*/React__namespace.createElement("div", {
28860
28998
  className: "perseus-widget-row"
28861
- }, /*#__PURE__*/React__namespace.createElement(perseus.ColorPicker, {
28999
+ }, /*#__PURE__*/React__namespace.createElement(ColorPicker, {
28862
29000
  value: this.props.color,
28863
29001
  onChange: this.change("color")
28864
29002
  })), /*#__PURE__*/React__namespace.createElement("div", {
28865
29003
  className: "perseus-widget-row"
28866
- }, /*#__PURE__*/React__namespace.createElement(perseus.DashPicker, {
29004
+ }, /*#__PURE__*/React__namespace.createElement(DashPicker, {
28867
29005
  value: this.props.strokeDasharray,
28868
29006
  onChange: this.change("strokeDasharray")
28869
29007
  })), /*#__PURE__*/React__namespace.createElement("div", {
@@ -28916,7 +29054,7 @@ class PointEditor extends React__namespace.Component {
28916
29054
  onChange: this.change("coordY")
28917
29055
  }), /*#__PURE__*/React__namespace.createElement(TeX, null, "\\Large)")), /*#__PURE__*/React__namespace.createElement("div", {
28918
29056
  className: "perseus-widget-row"
28919
- }, /*#__PURE__*/React__namespace.createElement(perseus.ColorPicker, {
29057
+ }, /*#__PURE__*/React__namespace.createElement(ColorPicker, {
28920
29058
  value: this.props.color,
28921
29059
  onChange: this.change("color")
28922
29060
  })));
@@ -28973,7 +29111,7 @@ class RectangleEditor extends React__namespace.Component {
28973
29111
  onChange: this.change("height")
28974
29112
  })), /*#__PURE__*/React__namespace.createElement("div", {
28975
29113
  className: "perseus-widget-row"
28976
- }, /*#__PURE__*/React__namespace.createElement(perseus.ColorPicker, {
29114
+ }, /*#__PURE__*/React__namespace.createElement(ColorPicker, {
28977
29115
  value: this.props.color,
28978
29116
  lightColors: true,
28979
29117
  onChange: this.change("color")
@@ -29116,7 +29254,7 @@ class InteractionEditor extends React__namespace.Component {
29116
29254
  } = getDependencies();
29117
29255
  return /*#__PURE__*/React__namespace.createElement("div", {
29118
29256
  className: "perseus-widget-interaction-editor"
29119
- }, /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29257
+ }, /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29120
29258
  title: "Grid settings"
29121
29259
  }, /*#__PURE__*/React__namespace.createElement(GraphSettings, {
29122
29260
  editableSettings: ["canvas", "graph"],
@@ -29129,7 +29267,7 @@ class InteractionEditor extends React__namespace.Component {
29129
29267
  onChange: this._updateGraphProps
29130
29268
  }), /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, this.props.graph.valid !== true && /*#__PURE__*/React__namespace.createElement("div", null, this.props.graph.valid))), ___default["default"].map(this.props.elements, function (element, n) {
29131
29269
  if (element.type === "movable-point") {
29132
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29270
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29133
29271
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Movable point", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, "(x_{" + element.options.varSubscript + "}, y_{" + element.options.varSubscript + "})"))
29134
29272
  // eslint-disable-next-line react/jsx-no-bind
29135
29273
  ,
@@ -29164,7 +29302,7 @@ class InteractionEditor extends React__namespace.Component {
29164
29302
  })));
29165
29303
  }
29166
29304
  if (element.type === "movable-line") {
29167
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29305
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29168
29306
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Movable line", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, "(x_{" + element.options.startSubscript + "}, y_{" + element.options.startSubscript + "})"), " ", "to", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, "(x_{" + element.options.endSubscript + "}, y_{" + element.options.endSubscript + "})"))
29169
29307
  // eslint-disable-next-line react/jsx-no-bind
29170
29308
  ,
@@ -29199,7 +29337,7 @@ class InteractionEditor extends React__namespace.Component {
29199
29337
  })));
29200
29338
  }
29201
29339
  if (element.type === "point") {
29202
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29340
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29203
29341
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Point", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, "(" + element.options.coordX + ", " + element.options.coordY + ")"))
29204
29342
  // eslint-disable-next-line react/jsx-no-bind
29205
29343
  ,
@@ -29234,7 +29372,7 @@ class InteractionEditor extends React__namespace.Component {
29234
29372
  })));
29235
29373
  }
29236
29374
  if (element.type === "line") {
29237
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29375
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29238
29376
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Line", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, "(" + element.options.startX + ", " + element.options.startY + ")"), " ", "to", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, "(" + element.options.endX + ", " + element.options.endY + ")"))
29239
29377
  // eslint-disable-next-line react/jsx-no-bind
29240
29378
  ,
@@ -29269,7 +29407,7 @@ class InteractionEditor extends React__namespace.Component {
29269
29407
  })));
29270
29408
  }
29271
29409
  if (element.type === "function") {
29272
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29410
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29273
29411
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Function", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, element.options.funcName + "(x) = " + element.options.value))
29274
29412
  // eslint-disable-next-line react/jsx-no-bind
29275
29413
  ,
@@ -29303,7 +29441,7 @@ class InteractionEditor extends React__namespace.Component {
29303
29441
  })));
29304
29442
  }
29305
29443
  if (element.type === "parametric") {
29306
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29444
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29307
29445
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Parametric")
29308
29446
  // eslint-disable-next-line react/jsx-no-bind
29309
29447
  ,
@@ -29337,7 +29475,7 @@ class InteractionEditor extends React__namespace.Component {
29337
29475
  })));
29338
29476
  }
29339
29477
  if (element.type === "label") {
29340
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29478
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29341
29479
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Label", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, unescapeMathMode(element.options.label)), " ")
29342
29480
  // eslint-disable-next-line react/jsx-no-bind
29343
29481
  ,
@@ -29371,7 +29509,7 @@ class InteractionEditor extends React__namespace.Component {
29371
29509
  })));
29372
29510
  }
29373
29511
  if (element.type === "rectangle") {
29374
- return /*#__PURE__*/React__namespace.createElement(perseus.ElementContainer, {
29512
+ return /*#__PURE__*/React__namespace.createElement(ElementContainer, {
29375
29513
  title: /*#__PURE__*/React__namespace.createElement("span", null, "Rectangle", " ", /*#__PURE__*/React__namespace.createElement(TeX, null, "(" + element.options.coordX + ", " + element.options.coordY + ")"), "\xA0\u2014\xA0", /*#__PURE__*/React__namespace.createElement(TeX, null, element.options.width + " \\times " + element.options.height))
29376
29514
  // eslint-disable-next-line react/jsx-no-bind
29377
29515
  ,
@@ -29433,6 +29571,20 @@ class InteractionEditor extends React__namespace.Component {
29433
29571
  }
29434
29572
  }
29435
29573
 
29574
+ var isProduction = process.env.NODE_ENV === 'production';
29575
+ var prefix = 'Invariant failed';
29576
+ function invariant(condition, message) {
29577
+ if (condition) {
29578
+ return;
29579
+ }
29580
+ if (isProduction) {
29581
+ throw new Error(prefix);
29582
+ }
29583
+ var provided = typeof message === 'function' ? message() : message;
29584
+ var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
29585
+ throw new Error(value);
29586
+ }
29587
+
29436
29588
  // Renders the given children in a View laid out horizontally.
29437
29589
  const LabeledRow = props => {
29438
29590
  const {
@@ -29442,16 +29594,16 @@ const LabeledRow = props => {
29442
29594
  style
29443
29595
  } = props;
29444
29596
  return /*#__PURE__*/React__namespace.createElement("label", {
29445
- className: aphrodite.css(styles$I.label)
29597
+ className: aphrodite.css(styles$J.label)
29446
29598
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29447
- style: [styles$I.row, style]
29599
+ style: [styles$J.row, style]
29448
29600
  }, labelSide === "start" || /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
29449
- style: styles$I.spaceEnd
29601
+ style: styles$J.spaceEnd
29450
29602
  }, label), children, labelSide === "end" && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
29451
- style: styles$I.spaceStart
29603
+ style: styles$J.spaceStart
29452
29604
  }, label)));
29453
29605
  };
29454
- const styles$I = aphrodite.StyleSheet.create({
29606
+ const styles$J = aphrodite.StyleSheet.create({
29455
29607
  label: {
29456
29608
  width: "fit-content"
29457
29609
  },
@@ -29477,11 +29629,11 @@ function Heading(_ref) {
29477
29629
  onToggle
29478
29630
  } = _ref;
29479
29631
  return /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
29480
- style: [styles$H.container, !isCollapsible && styles$H.notClickable],
29632
+ style: [styles$I.container, !isCollapsible && styles$I.notClickable],
29481
29633
  disabled: !isCollapsible,
29482
29634
  onClick: () => isCollapsible && onToggle?.(!isOpen)
29483
29635
  }, () => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29484
- style: styles$H.heading
29636
+ style: styles$I.heading
29485
29637
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
29486
29638
  style: {
29487
29639
  fontSize: 14,
@@ -29491,7 +29643,7 @@ function Heading(_ref) {
29491
29643
  isExpanded: isOpen
29492
29644
  })));
29493
29645
  }
29494
- const styles$H = aphrodite.StyleSheet.create({
29646
+ const styles$I = aphrodite.StyleSheet.create({
29495
29647
  container: {
29496
29648
  marginTop: wonderBlocksTokens.spacing.small_12,
29497
29649
  // NOTE(jeremy): This is the inverse of the @editorPadding CSS
@@ -29728,34 +29880,20 @@ const getAngleEquation = startCoords => {
29728
29880
  const roundedAngle = angle.toFixed(0);
29729
29881
  return `${roundedAngle}\u00B0 angle at (${vertex[0]}, ${vertex[1]})`;
29730
29882
  };
29731
- const shouldShowStartCoordsUI = (flags, graph) => {
29732
- // TODO(LEMS-2228): Remove flags once this is fully released
29733
- const startCoordsUiPhase1Types = ["linear", "linear-system", "ray", "segment", "circle"];
29734
- const startCoordsUiPhase2Types = ["sinusoid", "quadratic"];
29735
- const startCoordsPhase1 = flags?.mafs?.["start-coords-ui-phase-1"];
29736
- const startCoordsPhase2 = flags?.mafs?.["start-coords-ui-phase-2"];
29737
- const startCoordsPoint = flags?.mafs?.["start-coords-ui-point"];
29738
- const startCoordsPolygon = flags?.mafs?.["start-coords-ui-polygon"];
29739
- const startCoordsAngle = flags?.mafs?.["start-coords-ui-angle"];
29740
- if (startCoordsPhase1 && startCoordsUiPhase1Types.includes(graph.type)) {
29741
- return true;
29742
- }
29743
- if (startCoordsPhase2 && startCoordsUiPhase2Types.includes(graph.type)) {
29744
- return true;
29745
- }
29746
- if (startCoordsAngle && graph.type === "angle") {
29747
- return true;
29883
+ const shouldShowStartCoordsUI = (graph, isStatic) => {
29884
+ // We don't show the start coords UI for static graphs, since
29885
+ // the coords shown for this are determined by the coords on the
29886
+ // "correct" graph. The start coords would not be used here.
29887
+ if (isStatic) {
29888
+ return false;
29748
29889
  }
29749
- if (startCoordsPoint && graph.type === "point" && graph.numPoints !== "unlimited") {
29750
- return true;
29890
+ if (graph.type === "point" && graph.numPoints === "unlimited") {
29891
+ return false;
29751
29892
  }
29752
- if (startCoordsPolygon && graph.type === "polygon" && graph.numSides !== "unlimited" && (
29753
- // Pre-initialized graph with undefined snapTo value
29754
- // initializes to snapTo="grid"
29755
- graph.snapTo === "grid" || graph.snapTo === undefined)) {
29756
- return true;
29893
+ if (graph.type === "polygon" && (graph.numSides === "unlimited" || graph.snapTo === "angles" || graph.snapTo === "sides")) {
29894
+ return false;
29757
29895
  }
29758
- return false;
29896
+ return true;
29759
29897
  };
29760
29898
 
29761
29899
  /**
@@ -29770,25 +29908,22 @@ const LockedFigureSelect = props => {
29770
29908
  id,
29771
29909
  onChange
29772
29910
  } = props;
29773
- const figureTypes = ["point", "line", "vector", "ellipse", "polygon"];
29774
- if (props.showM2bFeatures) {
29775
- figureTypes.push("function");
29776
- }
29911
+ const figureTypes = ["point", "line", "vector", "ellipse", "polygon", "function"];
29777
29912
  if (props.showLabelsFlag) {
29778
29913
  figureTypes.push("label");
29779
29914
  }
29780
29915
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29781
- style: styles$G.container
29916
+ style: styles$H.container
29782
29917
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionMenu, {
29783
29918
  menuText: "Add locked figure",
29784
- style: styles$G.addElementSelect
29919
+ style: styles$H.addElementSelect
29785
29920
  }, figureTypes.map(figureType => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionItem, {
29786
29921
  key: `${id}-${figureType}`,
29787
29922
  label: figureType,
29788
29923
  onClick: () => onChange(figureType)
29789
29924
  }))));
29790
29925
  };
29791
- const styles$G = aphrodite.StyleSheet.create({
29926
+ const styles$H = aphrodite.StyleSheet.create({
29792
29927
  container: {
29793
29928
  marginTop: wonderBlocksTokens.spacing.xSmall_8
29794
29929
  },
@@ -29858,18 +29993,18 @@ const AngleInput = props => {
29858
29993
  }
29859
29994
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
29860
29995
  tag: "label",
29861
- style: styles$F.row
29996
+ style: styles$G.row
29862
29997
  }, "angle (degrees)", /*#__PURE__*/React__namespace.createElement(Strut, {
29863
29998
  size: wonderBlocksTokens.spacing.xxSmall_6
29864
29999
  }), /*#__PURE__*/React__namespace.createElement(ScrolllessNumberTextField, {
29865
30000
  value: angleInput,
29866
30001
  onChange: handleAngleChange,
29867
- style: styles$F.textField
30002
+ style: styles$G.textField
29868
30003
  }), /*#__PURE__*/React__namespace.createElement(Strut, {
29869
30004
  size: wonderBlocksTokens.spacing.xxSmall_6
29870
30005
  }));
29871
30006
  };
29872
- const styles$F = aphrodite.StyleSheet.create({
30007
+ const styles$G = aphrodite.StyleSheet.create({
29873
30008
  row: {
29874
30009
  display: "flex",
29875
30010
  flexDirection: "row",
@@ -29918,30 +30053,30 @@ const CoordinatePairInput = props => {
29918
30053
  onChange(newCoords);
29919
30054
  }
29920
30055
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29921
- style: [styles$E.row, style]
30056
+ style: [styles$F.row, style]
29922
30057
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
29923
30058
  tag: "label",
29924
- style: styles$E.row
30059
+ style: styles$F.row
29925
30060
  }, labels ? labels[0] : "x coord", /*#__PURE__*/React__namespace.createElement(Strut, {
29926
30061
  size: wonderBlocksTokens.spacing.xxSmall_6
29927
30062
  }), /*#__PURE__*/React__namespace.createElement(ScrolllessNumberTextField, {
29928
30063
  value: coordState[0],
29929
30064
  onChange: newValue => handleCoordChange(newValue, 0),
29930
- style: [styles$E.textField, error ? styles$E.errorField : undefined]
30065
+ style: [styles$F.textField, error ? styles$F.errorField : undefined]
29931
30066
  })), /*#__PURE__*/React__namespace.createElement(Strut, {
29932
30067
  size: wonderBlocksTokens.spacing.medium_16
29933
30068
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
29934
30069
  tag: "label",
29935
- style: styles$E.row
30070
+ style: styles$F.row
29936
30071
  }, labels ? labels[1] : "y coord", /*#__PURE__*/React__namespace.createElement(Strut, {
29937
30072
  size: wonderBlocksTokens.spacing.xxSmall_6
29938
30073
  }), /*#__PURE__*/React__namespace.createElement(ScrolllessNumberTextField, {
29939
30074
  value: coordState[1],
29940
30075
  onChange: newValue => handleCoordChange(newValue, 1),
29941
- style: [styles$E.textField, error ? styles$E.errorField : undefined]
30076
+ style: [styles$F.textField, error ? styles$F.errorField : undefined]
29942
30077
  })));
29943
30078
  };
29944
- const styles$E = aphrodite.StyleSheet.create({
30079
+ const styles$F = aphrodite.StyleSheet.create({
29945
30080
  row: {
29946
30081
  display: "flex",
29947
30082
  flexDirection: "row",
@@ -29974,14 +30109,14 @@ const PerseusEditorAccordion = props => {
29974
30109
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksAccordion.AccordionSection, {
29975
30110
  expanded: expanded,
29976
30111
  onToggle: onToggle,
29977
- style: [styles$D.container, containerStyle],
29978
- headerStyle: styles$D.accordionHeader,
30112
+ style: [styles$E.container, containerStyle],
30113
+ headerStyle: styles$E.accordionHeader,
29979
30114
  header: header
29980
30115
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29981
- style: [styles$D.accordionPanel, panelStyle]
30116
+ style: [styles$E.accordionPanel, panelStyle]
29982
30117
  }, children)));
29983
30118
  };
29984
- const styles$D = aphrodite.StyleSheet.create({
30119
+ const styles$E = aphrodite.StyleSheet.create({
29985
30120
  container: {
29986
30121
  backgroundColor: wonderBlocksTokens.color.fadedBlue8,
29987
30122
  marginTop: wonderBlocksTokens.spacing.xSmall_8
@@ -30012,13 +30147,13 @@ const ColorSwatch = props => {
30012
30147
  "aria-label":
30013
30148
  // Don't include an aria label for decorative circles.
30014
30149
  !decorative ? `${color}, ${filled ? "filled" : "open"}` : undefined,
30015
- style: [styles$C.colorSwatch, {
30150
+ style: [styles$D.colorSwatch, {
30016
30151
  border: `4px solid ${perseus.lockedFigureColors[color]}`,
30017
30152
  backgroundColor: filled ? perseus.lockedFigureColors[color] : wonderBlocksTokens.color.white
30018
30153
  }]
30019
30154
  });
30020
30155
  };
30021
- const styles$C = aphrodite.StyleSheet.create({
30156
+ const styles$D = aphrodite.StyleSheet.create({
30022
30157
  colorSwatch: {
30023
30158
  // Add a white outline so that the color swatch is visible when
30024
30159
  // the dropdown option is highlighted with its blue background.
@@ -30037,10 +30172,10 @@ const ColorSelect = props => {
30037
30172
  onChange
30038
30173
  } = props;
30039
30174
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30040
- style: [styles$B.row, style]
30175
+ style: [styles$C.row, style]
30041
30176
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30042
30177
  tag: "label",
30043
- style: styles$B.row
30178
+ style: styles$C.row
30044
30179
  }, "color", /*#__PURE__*/React__namespace.createElement(Strut, {
30045
30180
  size: wonderBlocksTokens.spacing.xxSmall_6
30046
30181
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
@@ -30059,7 +30194,7 @@ const ColorSelect = props => {
30059
30194
  })
30060
30195
  })))));
30061
30196
  };
30062
- const styles$B = aphrodite.StyleSheet.create({
30197
+ const styles$C = aphrodite.StyleSheet.create({
30063
30198
  row: {
30064
30199
  display: "flex",
30065
30200
  flexDirection: "row",
@@ -30078,17 +30213,17 @@ const EllipseSwatch = props => {
30078
30213
  } = props;
30079
30214
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30080
30215
  "aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
30081
- style: [styles$A.container, {
30216
+ style: [styles$B.container, {
30082
30217
  border: `4px ${strokeStyle} ${perseus.lockedFigureColors[color]}`
30083
30218
  }]
30084
30219
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30085
- style: [styles$A.innerCircle, {
30220
+ style: [styles$B.innerCircle, {
30086
30221
  backgroundColor: perseus.lockedFigureColors[color],
30087
30222
  opacity: fillStyle === "white" ? 0 : perseus.lockedFigureFillStyles[fillStyle]
30088
30223
  }]
30089
30224
  }));
30090
30225
  };
30091
- const styles$A = aphrodite.StyleSheet.create({
30226
+ const styles$B = aphrodite.StyleSheet.create({
30092
30227
  container: {
30093
30228
  // Add a white outline so that the color swatch is visible when
30094
30229
  // the dropdown option is highlighted with its blue background.
@@ -30114,7 +30249,7 @@ const LineStrokeSelect = props => {
30114
30249
  } = props;
30115
30250
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30116
30251
  tag: "label",
30117
- style: styles$z.lineStrokeSelect
30252
+ style: styles$A.lineStrokeSelect
30118
30253
  }, "stroke", /*#__PURE__*/React__namespace.createElement(Strut, {
30119
30254
  size: wonderBlocksTokens.spacing.xxxSmall_4
30120
30255
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
@@ -30131,7 +30266,7 @@ const LineStrokeSelect = props => {
30131
30266
  label: "dashed"
30132
30267
  })));
30133
30268
  };
30134
- const styles$z = aphrodite.StyleSheet.create({
30269
+ const styles$A = aphrodite.StyleSheet.create({
30135
30270
  lineStrokeSelect: {
30136
30271
  display: "flex",
30137
30272
  flexDirection: "row",
@@ -30153,40 +30288,40 @@ const LockedFigureSettingsActions = props => {
30153
30288
  onRemove
30154
30289
  } = props;
30155
30290
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30156
- style: styles$y.container
30291
+ style: styles$z.container
30157
30292
  }, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
30158
30293
  startIcon: trashIcon__default["default"],
30159
30294
  "aria-label": `Delete locked ${figureType}`,
30160
30295
  onClick: onRemove,
30161
30296
  kind: "tertiary",
30162
- style: styles$y.deleteButton
30297
+ style: styles$z.deleteButton
30163
30298
  }, "Delete"), /*#__PURE__*/React__namespace.createElement(Spring, null), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
30164
30299
  icon: caretDoubleUpIcon__default["default"],
30165
30300
  size: "small",
30166
30301
  "aria-label": `Move locked ${figureType} to the back`,
30167
30302
  onClick: () => onMove("back"),
30168
- style: styles$y.iconButton
30303
+ style: styles$z.iconButton
30169
30304
  }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
30170
30305
  icon: caretUpIcon__default["default"],
30171
30306
  size: "small",
30172
30307
  "aria-label": `Move locked ${figureType} backward`,
30173
30308
  onClick: () => onMove("backward"),
30174
- style: styles$y.iconButton
30309
+ style: styles$z.iconButton
30175
30310
  }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
30176
30311
  icon: caretDownIcon__default["default"],
30177
30312
  size: "small",
30178
30313
  "aria-label": `Move locked ${figureType} forward`,
30179
30314
  onClick: () => onMove("forward"),
30180
- style: styles$y.iconButton
30315
+ style: styles$z.iconButton
30181
30316
  }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
30182
30317
  icon: caretDoubleDownIcon__default["default"],
30183
30318
  size: "small",
30184
30319
  "aria-label": `Move locked ${figureType} to the front`,
30185
30320
  onClick: () => onMove("front"),
30186
- style: styles$y.iconButton
30321
+ style: styles$z.iconButton
30187
30322
  }));
30188
30323
  };
30189
- const styles$y = aphrodite.StyleSheet.create({
30324
+ const styles$z = aphrodite.StyleSheet.create({
30190
30325
  container: {
30191
30326
  width: "100%",
30192
30327
  flexDirection: "row",
@@ -30233,7 +30368,7 @@ const LockedEllipseSettings = props => {
30233
30368
  /*#__PURE__*/
30234
30369
  // Summary: Ellipse, center, radius, color (opacity, dashed)
30235
30370
  React__namespace.createElement(wonderBlocksCore.View, {
30236
- style: styles$x.row
30371
+ style: styles$y.row
30237
30372
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React__namespace.createElement(Strut, {
30238
30373
  size: wonderBlocksTokens.spacing.xSmall_8
30239
30374
  }), /*#__PURE__*/React__namespace.createElement(EllipseSwatch, {
@@ -30242,19 +30377,19 @@ const LockedEllipseSettings = props => {
30242
30377
  strokeStyle: strokeStyle
30243
30378
  }))
30244
30379
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30245
- style: styles$x.row
30380
+ style: styles$y.row
30246
30381
  }, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
30247
30382
  coord: center,
30248
- style: styles$x.spaceUnder,
30383
+ style: styles$y.spaceUnder,
30249
30384
  onChange: newCoords => onChangeProps({
30250
30385
  center: newCoords
30251
30386
  })
30252
30387
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30253
- style: styles$x.spaceUnder
30388
+ style: styles$y.spaceUnder
30254
30389
  }, /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
30255
30390
  coord: radius,
30256
30391
  labels: ["x radius", "y radius"],
30257
- style: styles$x.spaceUnder,
30392
+ style: styles$y.spaceUnder,
30258
30393
  onChange: newCoords => onChangeProps({
30259
30394
  radius: newCoords
30260
30395
  })
@@ -30266,7 +30401,7 @@ const LockedEllipseSettings = props => {
30266
30401
  }), /*#__PURE__*/React__namespace.createElement(Strut, {
30267
30402
  size: wonderBlocksTokens.spacing.xSmall_8
30268
30403
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30269
- style: [styles$x.row, styles$x.spaceUnder]
30404
+ style: [styles$y.row, styles$y.spaceUnder]
30270
30405
  }, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
30271
30406
  selectedValue: color,
30272
30407
  onChange: handleColorChange
@@ -30274,7 +30409,7 @@ const LockedEllipseSettings = props => {
30274
30409
  size: wonderBlocksTokens.spacing.medium_16
30275
30410
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30276
30411
  tag: "label",
30277
- style: [styles$x.row, styles$x.truncatedWidth]
30412
+ style: [styles$y.row, styles$y.truncatedWidth]
30278
30413
  }, "fill", /*#__PURE__*/React__namespace.createElement(Strut, {
30279
30414
  size: wonderBlocksTokens.spacing.xxSmall_6
30280
30415
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
@@ -30300,7 +30435,7 @@ const LockedEllipseSettings = props => {
30300
30435
  onRemove: onRemove
30301
30436
  }));
30302
30437
  };
30303
- const styles$x = aphrodite.StyleSheet.create({
30438
+ const styles$y = aphrodite.StyleSheet.create({
30304
30439
  row: {
30305
30440
  display: "flex",
30306
30441
  flexDirection: "row",
@@ -30321,15 +30456,15 @@ const LineSwatch = props => {
30321
30456
  lineStyle
30322
30457
  } = props;
30323
30458
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30324
- style: styles$w.container
30459
+ style: styles$x.container
30325
30460
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30326
30461
  "aria-label": `${color}, ${lineStyle}`,
30327
- style: [styles$w.lineSwatch, {
30462
+ style: [styles$x.lineSwatch, {
30328
30463
  border: `5px ${lineStyle} ${perseus.lockedFigureColors[color]}`
30329
30464
  }]
30330
30465
  }));
30331
30466
  };
30332
- const styles$w = aphrodite.StyleSheet.create({
30467
+ const styles$x = aphrodite.StyleSheet.create({
30333
30468
  container: {
30334
30469
  backgroundColor: wonderBlocksTokens.color.white,
30335
30470
  justifyContent: "center",
@@ -30341,6 +30476,12 @@ const styles$w = aphrodite.StyleSheet.create({
30341
30476
  }
30342
30477
  });
30343
30478
 
30479
+ const examples = {
30480
+ linear: ["x + 5", "1/2x - 2"],
30481
+ polynomial: ["1/2x^2 + 3x - 4", "(1/3)x^3 - 2x^2 + 3x - 4"],
30482
+ trigonometric: ["sin(x) * 3", "arctan(2x) + 4"]
30483
+ };
30484
+
30344
30485
  /**
30345
30486
  * LockedFunctionSettings is a component that allows the user to edit the
30346
30487
  * settings of specifically a locked function on the graph.
@@ -30359,18 +30500,20 @@ const LockedFunctionSettings = props => {
30359
30500
  onRemove
30360
30501
  } = props;
30361
30502
  const equationPrefix = directionalAxis === "x" ? "y=" : "x=";
30503
+ const domainRangeText = directionalAxis === "x" ? "domain" : "range";
30362
30504
  const lineLabel = `Function (${equationPrefix}${equation})`;
30363
30505
 
30364
- // Tracking the string value of domain constraints to handle interim state of
30506
+ // Tracking the string value of domain/range constraints to handle interim state of
30365
30507
  // entering a negative value, as well as representing Infinity as an empty string.
30366
30508
  // This variable is used when specifying the values of the input fields.
30367
30509
  const [domainEntries, setDomainEntries] = React.useState([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
30510
+ const [exampleCategory, setExampleCategory] = React.useState("");
30368
30511
  React.useEffect(() => {
30369
- // "useEffect" used to maintain parity between domain constraints and their string representation.
30512
+ // "useEffect" used to maintain parity between domain/range constraints and their string representation.
30370
30513
  setDomainEntries([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
30371
30514
  }, [domain]);
30372
30515
 
30373
- // Generic function for handling property changes (except for 'domain')
30516
+ // Generic function for handling property changes (except for 'domain/range')
30374
30517
  function handlePropChange(property, newValue) {
30375
30518
  const updatedProps = {};
30376
30519
  updatedProps[property] = newValue;
@@ -30378,8 +30521,8 @@ const LockedFunctionSettings = props => {
30378
30521
  }
30379
30522
 
30380
30523
  /*
30381
- Reason for having a separate 'propChange' function for 'domain':
30382
- Domain entries are optional. Their default value is +/- Infinity.
30524
+ Reason for having a separate 'propChange' function for 'domain/range':
30525
+ Domain/Range entries are optional. Their default value is +/- Infinity.
30383
30526
  Since input fields that are empty evaluate to zero, there needs to be
30384
30527
  dedicated code to convert empty to Infinity.
30385
30528
  */
@@ -30399,13 +30542,16 @@ const LockedFunctionSettings = props => {
30399
30542
  domain: newDomain
30400
30543
  });
30401
30544
  }
30545
+ const exampleCategories = Object.keys(examples);
30546
+ const exampleCategorySelected = exampleCategory !== "";
30547
+ const exampleContent = exampleCategorySelected ? examples[exampleCategory] : ["Select category to see example equations"];
30402
30548
  return /*#__PURE__*/React__namespace.createElement(PerseusEditorAccordion, {
30403
30549
  expanded: props.expanded,
30404
30550
  onToggle: props.onToggle,
30405
30551
  header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30406
- style: styles$v.row
30552
+ style: styles$w.row
30407
30553
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
30408
- style: styles$v.accordionHeader
30554
+ style: styles$w.accordionHeader
30409
30555
  }, lineLabel), /*#__PURE__*/React__namespace.createElement(Strut, {
30410
30556
  size: wonderBlocksTokens.spacing.xSmall_8
30411
30557
  }), /*#__PURE__*/React__namespace.createElement(LineSwatch, {
@@ -30413,7 +30559,7 @@ const LockedFunctionSettings = props => {
30413
30559
  lineStyle: strokeStyle
30414
30560
  }))
30415
30561
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30416
- style: [styles$v.row, styles$v.spaceUnder]
30562
+ style: [styles$w.row, styles$w.spaceUnder]
30417
30563
  }, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
30418
30564
  selectedValue: lineColor,
30419
30565
  onChange: newValue => {
@@ -30427,14 +30573,14 @@ const LockedFunctionSettings = props => {
30427
30573
  handlePropChange("strokeStyle", newValue);
30428
30574
  }
30429
30575
  })), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30430
- style: [styles$v.row, styles$v.rowSpace]
30576
+ style: [styles$w.row, styles$w.rowSpace]
30431
30577
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
30432
30578
  selectedValue: directionalAxis,
30433
30579
  onChange: newValue => {
30434
30580
  handlePropChange("directionalAxis", newValue);
30435
30581
  },
30436
30582
  "aria-label": "equation prefix",
30437
- style: styles$v.equationPrefix
30583
+ style: [styles$w.dropdownLabel, styles$w.axisMenu]
30438
30584
  // Placeholder is required, but never gets used.
30439
30585
  ,
30440
30586
  placeholder: ""
@@ -30453,17 +30599,17 @@ const LockedFunctionSettings = props => {
30453
30599
  onChange: newValue => {
30454
30600
  handlePropChange("equation", newValue);
30455
30601
  },
30456
- style: [styles$v.textField]
30602
+ style: [styles$w.textField]
30457
30603
  })), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30458
- style: [styles$v.row, styles$v.rowSpace]
30604
+ style: [styles$w.row, styles$w.rowSpace]
30459
30605
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30460
30606
  tag: "label",
30461
- style: styles$v.domainMin
30462
- }, "domain min", /*#__PURE__*/React__namespace.createElement(Strut, {
30607
+ style: [styles$w.dropdownLabel, styles$w.domainMin]
30608
+ }, `${domainRangeText} min`, /*#__PURE__*/React__namespace.createElement(Strut, {
30463
30609
  size: wonderBlocksTokens.spacing.xxSmall_6
30464
30610
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
30465
30611
  type: "number",
30466
- style: styles$v.domainMinField,
30612
+ style: styles$w.domainMinField,
30467
30613
  value: domainEntries[0],
30468
30614
  onChange: newValue => {
30469
30615
  handleDomainChange(0, newValue);
@@ -30472,24 +30618,83 @@ const LockedFunctionSettings = props => {
30472
30618
  size: wonderBlocksTokens.spacing.medium_16
30473
30619
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30474
30620
  tag: "label",
30475
- "aria-label": "domain max",
30476
- style: styles$v.domainMax
30621
+ "aria-label": `${domainRangeText} max`,
30622
+ style: [styles$w.dropdownLabel, styles$w.domainMax]
30477
30623
  }, "max", /*#__PURE__*/React__namespace.createElement(Strut, {
30478
30624
  size: wonderBlocksTokens.spacing.xxSmall_6
30479
30625
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
30480
30626
  type: "number",
30481
- style: styles$v.domainMaxField,
30627
+ style: styles$w.domainMaxField,
30482
30628
  value: domainEntries[1],
30483
30629
  onChange: newValue => {
30484
30630
  handleDomainChange(1, newValue);
30485
30631
  }
30486
- }))), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
30632
+ }))), /*#__PURE__*/React__namespace.createElement(PerseusEditorAccordion, {
30633
+ header: /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, "Example Functions"),
30634
+ expanded: false,
30635
+ containerStyle: styles$w.exampleWorkspace,
30636
+ panelStyle: styles$w.exampleAccordionPanel
30637
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30638
+ tag: "label",
30639
+ style: styles$w.dropdownLabel
30640
+ }, "Choose a category", /*#__PURE__*/React__namespace.createElement(Strut, {
30641
+ size: wonderBlocksTokens.spacing.xxSmall_6
30642
+ }), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
30643
+ selectedValue: exampleCategory,
30644
+ onChange: setExampleCategory,
30645
+ placeholder: "examples"
30646
+ }, exampleCategories.map(category => {
30647
+ return /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
30648
+ key: category,
30649
+ value: category,
30650
+ label: category
30651
+ });
30652
+ }))), exampleCategorySelected && /*#__PURE__*/React__namespace.createElement("ul", {
30653
+ className: aphrodite.css(styles$w.exampleContainer)
30654
+ }, exampleContent.map((example, index) => /*#__PURE__*/React__namespace.createElement(ExampleItem, {
30655
+ category: exampleCategory,
30656
+ example: example,
30657
+ index: index,
30658
+ pasteEquationFn: handlePropChange
30659
+ })))), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
30487
30660
  figureType: props.type,
30488
30661
  onMove: onMove,
30489
30662
  onRemove: onRemove
30490
30663
  }));
30491
30664
  };
30492
- const styles$v = aphrodite.StyleSheet.create({
30665
+ const ExampleItem = props => {
30666
+ const {
30667
+ category,
30668
+ example,
30669
+ index,
30670
+ pasteEquationFn
30671
+ } = props;
30672
+ const exampleId = React.useId();
30673
+ return /*#__PURE__*/React__namespace.createElement("li", {
30674
+ key: `${category}-${index}`,
30675
+ className: aphrodite.css(styles$w.exampleRow)
30676
+ }, /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
30677
+ icon: autoPasteIcon__default["default"],
30678
+ "aria-label": "paste example",
30679
+ "aria-describedby": exampleId,
30680
+ onClick: () => pasteEquationFn("equation", example),
30681
+ size: "medium",
30682
+ style: styles$w.copyPasteButton
30683
+ }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
30684
+ icon: copyIcon__default["default"],
30685
+ "aria-label": "copy example",
30686
+ "aria-describedby": exampleId,
30687
+ onClick: () => navigator.clipboard.writeText(example),
30688
+ size: "medium",
30689
+ style: styles$w.copyPasteButton
30690
+ }), /*#__PURE__*/React__namespace.createElement(Strut, {
30691
+ size: wonderBlocksTokens.spacing.xxxSmall_4
30692
+ }), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30693
+ style: styles$w.exampleContent,
30694
+ id: exampleId
30695
+ }, example));
30696
+ };
30697
+ const styles$w = aphrodite.StyleSheet.create({
30493
30698
  accordionHeader: {
30494
30699
  textOverflow: "ellipsis",
30495
30700
  // A maximum width needs to be specified in order for the ellipsis to work.
@@ -30499,17 +30704,20 @@ const styles$v = aphrodite.StyleSheet.create({
30499
30704
  overflow: "hidden",
30500
30705
  whiteSpace: "nowrap"
30501
30706
  },
30502
- equationPrefix: {
30707
+ axisMenu: {
30503
30708
  minWidth: "auto"
30504
30709
  },
30710
+ copyPasteButton: {
30711
+ flexShrink: "0",
30712
+ margin: "0 2px"
30713
+ },
30505
30714
  domainMin: {
30506
- alignItems: "center",
30507
- display: "flex",
30715
+ justifyContent: "space-between",
30508
30716
  // The 'width' property is applied to the label, which wraps the text and the input field.
30509
30717
  // The width of the input fields (min/max) should be the same (to have a consistent look),
30510
30718
  // so the following calculation distributes the space accordingly.
30511
- // For the "domain min" block, the text is 82.7px, and the strut is 6px (88.7px total).
30512
- // The "domain max" block is 30.23px, and the strut is 6px (36.23px total).
30719
+ // For the "domain/range min" block, the text is 82.7px, and the strut is 6px (88.7px total).
30720
+ // The "domain/range max" block is 30.23px, and the strut is 6px (36.23px total).
30513
30721
  // The calculation takes the remain space after the text & struts (141px total) are removed,
30514
30722
  // and divides it between the two input fields equally.
30515
30723
  // The calculation reads: "Take 1/2 of the non-text space, and add the required space for this label's text"
@@ -30522,8 +30730,6 @@ const styles$v = aphrodite.StyleSheet.create({
30522
30730
  },
30523
30731
 
30524
30732
  domainMax: {
30525
- alignItems: "center",
30526
- display: "flex",
30527
30733
  // See explanation for "domainMin" for the calculation below.
30528
30734
  width: "calc(((100% - 141px) / 2) + 36.2px)"
30529
30735
  },
@@ -30531,6 +30737,44 @@ const styles$v = aphrodite.StyleSheet.create({
30531
30737
  width: "calc(100% - 36.2px)" // make room for the label
30532
30738
  },
30533
30739
 
30740
+ dropdownLabel: {
30741
+ alignItems: "center",
30742
+ display: "flex"
30743
+ },
30744
+ exampleAccordionPanel: {
30745
+ alignItems: "start",
30746
+ paddingBottom: "12px",
30747
+ flexDirection: "row",
30748
+ flexWrap: "wrap"
30749
+ },
30750
+ exampleContainer: {
30751
+ background: "white",
30752
+ border: `1px solid ${wonderBlocksTokens.color.fadedOffBlack16}`,
30753
+ borderRadius: "4px",
30754
+ flexGrow: "1",
30755
+ listStyleType: "none",
30756
+ // Nothing special about the maxHeight value,
30757
+ // just a good height to partially show a 3rd example in the list
30758
+ // to hint at scrollable content.
30759
+ maxHeight: "88px",
30760
+ margin: "8px 0 0 0",
30761
+ overflowY: "scroll",
30762
+ padding: "4px 12px 4px 4px"
30763
+ },
30764
+ exampleContent: {
30765
+ fontFamily: `"Lato", sans-serif`,
30766
+ flexGrow: "1",
30767
+ color: wonderBlocksTokens.color.offBlack
30768
+ },
30769
+ exampleRow: {
30770
+ alignItems: "center",
30771
+ display: "flex",
30772
+ flexDirection: "row",
30773
+ minHeight: "44px"
30774
+ },
30775
+ exampleWorkspace: {
30776
+ background: wonderBlocksTokens.color.white50
30777
+ },
30534
30778
  rowSpace: {
30535
30779
  marginTop: wonderBlocksTokens.spacing.xSmall_8
30536
30780
  },
@@ -30568,14 +30812,14 @@ function LockedLabelSettings(props) {
30568
30812
  expanded: expanded,
30569
30813
  onToggle: onToggle,
30570
30814
  header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30571
- style: [styles$u.row, styles$u.accordionHeaderContainer]
30815
+ style: [styles$v.row, styles$v.accordionHeaderContainer]
30572
30816
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, "Label (", coord[0], ", ", coord[1], ")"), /*#__PURE__*/React__namespace.createElement(Strut, {
30573
30817
  size: wonderBlocksTokens.spacing.xSmall_8
30574
30818
  }), text !== "" && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
30575
30819
  style: [{
30576
30820
  backgroundColor: wonderBlocksTokens.color.white,
30577
30821
  color: perseus.lockedFigureColors[color]
30578
- }, styles$u.accordionHeader]
30822
+ }, styles$v.accordionHeader]
30579
30823
  }, text))
30580
30824
  }, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
30581
30825
  coord: coord,
@@ -30584,10 +30828,10 @@ function LockedLabelSettings(props) {
30584
30828
  coord: newCoords
30585
30829
  });
30586
30830
  },
30587
- style: styles$u.spaceUnder
30831
+ style: styles$v.spaceUnder
30588
30832
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30589
30833
  tag: "label",
30590
- style: [styles$u.row, styles$u.spaceUnder]
30834
+ style: [styles$v.row, styles$v.spaceUnder]
30591
30835
  }, "TeX", /*#__PURE__*/React__namespace.createElement(Strut, {
30592
30836
  size: wonderBlocksTokens.spacing.xSmall_8
30593
30837
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
@@ -30597,7 +30841,7 @@ function LockedLabelSettings(props) {
30597
30841
  text: newValue
30598
30842
  })
30599
30843
  })), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30600
- style: styles$u.row
30844
+ style: styles$v.row
30601
30845
  }, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
30602
30846
  selectedValue: color,
30603
30847
  onChange: newColor => {
@@ -30605,12 +30849,12 @@ function LockedLabelSettings(props) {
30605
30849
  color: newColor
30606
30850
  });
30607
30851
  },
30608
- style: styles$u.spaceUnder
30852
+ style: styles$v.spaceUnder
30609
30853
  }), /*#__PURE__*/React__namespace.createElement(Strut, {
30610
30854
  size: wonderBlocksTokens.spacing.medium_16
30611
30855
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30612
30856
  tag: "label",
30613
- style: styles$u.row
30857
+ style: styles$v.row
30614
30858
  }, "size", /*#__PURE__*/React__namespace.createElement(Strut, {
30615
30859
  size: wonderBlocksTokens.spacing.xSmall_8
30616
30860
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
@@ -30637,7 +30881,7 @@ function LockedLabelSettings(props) {
30637
30881
  onRemove: onRemove
30638
30882
  }));
30639
30883
  }
30640
- const styles$u = aphrodite.StyleSheet.create({
30884
+ const styles$v = aphrodite.StyleSheet.create({
30641
30885
  accordionHeaderContainer: {
30642
30886
  // Stop the label summary from wrapping.
30643
30887
  whiteSpace: "nowrap"
@@ -30671,7 +30915,7 @@ const LabeledSwitch = props => {
30671
30915
  const ids = wonderBlocksCore.useUniqueIdWithMock();
30672
30916
  const switchId = ids.get("switch");
30673
30917
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30674
- style: [styles$t.row, style]
30918
+ style: [styles$u.row, style]
30675
30919
  }, /*#__PURE__*/React__namespace.createElement(Switch__default["default"], {
30676
30920
  id: switchId,
30677
30921
  checked: checked,
@@ -30683,7 +30927,7 @@ const LabeledSwitch = props => {
30683
30927
  htmlFor: switchId
30684
30928
  }, label));
30685
30929
  };
30686
- const styles$t = aphrodite.StyleSheet.create({
30930
+ const styles$u = aphrodite.StyleSheet.create({
30687
30931
  row: {
30688
30932
  flexDirection: "row",
30689
30933
  alignItems: "center"
@@ -30717,13 +30961,13 @@ const DefiningPointSettings = props => {
30717
30961
  return /*#__PURE__*/React__namespace.createElement(PerseusEditorAccordion, {
30718
30962
  expanded: expanded,
30719
30963
  onToggle: onToggle,
30720
- containerStyle: styles$s.container,
30721
- panelStyle: styles$s.accordionPanel,
30964
+ containerStyle: styles$t.container,
30965
+ panelStyle: styles$t.accordionPanel,
30722
30966
  header:
30723
30967
  /*#__PURE__*/
30724
30968
  // Summary: Point, coords, color (filled/open)
30725
30969
  React__namespace.createElement(wonderBlocksCore.View, {
30726
- style: styles$s.row
30970
+ style: styles$t.row
30727
30971
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `${label || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React__namespace.createElement(Strut, {
30728
30972
  size: wonderBlocksTokens.spacing.xSmall_8
30729
30973
  }), showPoint && /*#__PURE__*/React__namespace.createElement(ColorSwatch, {
@@ -30733,7 +30977,7 @@ const DefiningPointSettings = props => {
30733
30977
  }, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
30734
30978
  coord: coord,
30735
30979
  error: !!error,
30736
- style: styles$s.spaceUnder,
30980
+ style: styles$t.spaceUnder,
30737
30981
  onChange: newCoords => {
30738
30982
  onChangeProps({
30739
30983
  coord: newCoords
@@ -30742,12 +30986,12 @@ const DefiningPointSettings = props => {
30742
30986
  }), onTogglePoint && /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
30743
30987
  label: "show point on graph",
30744
30988
  checked: !!showPoint,
30745
- style: showPoint && styles$s.spaceUnder,
30989
+ style: showPoint && styles$t.spaceUnder,
30746
30990
  onChange: onTogglePoint
30747
30991
  }), showPoint && /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
30748
30992
  selectedValue: pointColor,
30749
30993
  onChange: handleColorChange,
30750
- style: styles$s.spaceUnder
30994
+ style: styles$t.spaceUnder
30751
30995
  }), /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
30752
30996
  label: "open point",
30753
30997
  checked: !filled,
@@ -30758,7 +31002,7 @@ const DefiningPointSettings = props => {
30758
31002
  }
30759
31003
  })));
30760
31004
  };
30761
- const styles$s = aphrodite.StyleSheet.create({
31005
+ const styles$t = aphrodite.StyleSheet.create({
30762
31006
  container: {
30763
31007
  marginTop: wonderBlocksTokens.spacing.xSmall_8,
30764
31008
  marginBottom: 0,
@@ -30826,7 +31070,7 @@ const LockedLineSettings = props => {
30826
31070
  expanded: props.expanded,
30827
31071
  onToggle: props.onToggle,
30828
31072
  header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30829
- style: styles$r.row
31073
+ style: styles$s.row
30830
31074
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, lineLabel), /*#__PURE__*/React__namespace.createElement(Strut, {
30831
31075
  size: wonderBlocksTokens.spacing.xSmall_8
30832
31076
  }), /*#__PURE__*/React__namespace.createElement(LineSwatch, {
@@ -30835,7 +31079,7 @@ const LockedLineSettings = props => {
30835
31079
  }))
30836
31080
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30837
31081
  tag: "label",
30838
- style: [styles$r.row, styles$r.spaceUnder]
31082
+ style: [styles$s.row, styles$s.spaceUnder]
30839
31083
  }, "kind", /*#__PURE__*/React__namespace.createElement(Strut, {
30840
31084
  size: wonderBlocksTokens.spacing.xxxSmall_4
30841
31085
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
@@ -30856,7 +31100,7 @@ const LockedLineSettings = props => {
30856
31100
  value: "segment",
30857
31101
  label: "segment"
30858
31102
  }))), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30859
- style: styles$r.row
31103
+ style: styles$s.row
30860
31104
  }, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
30861
31105
  selectedValue: lineColor,
30862
31106
  onChange: handleColorChange
@@ -30868,7 +31112,7 @@ const LockedLineSettings = props => {
30868
31112
  lineStyle: value
30869
31113
  })
30870
31114
  })), isInvalid && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30871
- style: styles$r.errorText
31115
+ style: styles$s.errorText
30872
31116
  }, lengthZeroStr), /*#__PURE__*/React__namespace.createElement(DefiningPointSettings, _extends({
30873
31117
  label: "Point 1",
30874
31118
  showPoint: showPoint1,
@@ -30893,7 +31137,7 @@ const LockedLineSettings = props => {
30893
31137
  onRemove: onRemove
30894
31138
  }));
30895
31139
  };
30896
- const styles$r = aphrodite.StyleSheet.create({
31140
+ const styles$s = aphrodite.StyleSheet.create({
30897
31141
  row: {
30898
31142
  display: "flex",
30899
31143
  flexDirection: "row",
@@ -30934,7 +31178,7 @@ const LockedPointSettings = props => {
30934
31178
  /*#__PURE__*/
30935
31179
  // Summary: Point, coords, color (filled/open)
30936
31180
  React__namespace.createElement(wonderBlocksCore.View, {
30937
- style: styles$q.row
31181
+ style: styles$r.row
30938
31182
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Point (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React__namespace.createElement(Strut, {
30939
31183
  size: wonderBlocksTokens.spacing.xSmall_8
30940
31184
  }), /*#__PURE__*/React__namespace.createElement(ColorSwatch, {
@@ -30943,7 +31187,7 @@ const LockedPointSettings = props => {
30943
31187
  }))
30944
31188
  }, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
30945
31189
  coord: coord,
30946
- style: styles$q.spaceUnder,
31190
+ style: styles$r.spaceUnder,
30947
31191
  onChange: newCoord => {
30948
31192
  onChangeProps({
30949
31193
  coord: newCoord
@@ -30952,7 +31196,7 @@ const LockedPointSettings = props => {
30952
31196
  }), /*#__PURE__*/React__namespace.createElement(ColorSelect, {
30953
31197
  selectedValue: pointColor,
30954
31198
  onChange: handleColorChange,
30955
- style: styles$q.spaceUnder
31199
+ style: styles$r.spaceUnder
30956
31200
  }), /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
30957
31201
  label: "open point",
30958
31202
  checked: !filled,
@@ -30967,7 +31211,7 @@ const LockedPointSettings = props => {
30967
31211
  onRemove: onRemove
30968
31212
  }));
30969
31213
  };
30970
- const styles$q = aphrodite.StyleSheet.create({
31214
+ const styles$r = aphrodite.StyleSheet.create({
30971
31215
  row: {
30972
31216
  flexDirection: "row",
30973
31217
  alignItems: "center"
@@ -30985,17 +31229,17 @@ const PolygonSwatch = props => {
30985
31229
  } = props;
30986
31230
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30987
31231
  "aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
30988
- style: [styles$p.container, {
31232
+ style: [styles$q.container, {
30989
31233
  border: `4px ${strokeStyle} ${perseus.lockedFigureColors[color]}`
30990
31234
  }]
30991
31235
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30992
- style: [styles$p.innerSquare, {
31236
+ style: [styles$q.innerSquare, {
30993
31237
  backgroundColor: perseus.lockedFigureColors[color],
30994
31238
  opacity: fillStyle === "white" ? 0 : perseus.lockedFigureFillStyles[fillStyle]
30995
31239
  }]
30996
31240
  }));
30997
31241
  };
30998
- const styles$p = aphrodite.StyleSheet.create({
31242
+ const styles$q = aphrodite.StyleSheet.create({
30999
31243
  container: {
31000
31244
  // Add a white outline so that the color swatch is visible when
31001
31245
  // the dropdown option is highlighted with its blue background.
@@ -31073,7 +31317,7 @@ const LockedPolygonSettings = props => {
31073
31317
  /*#__PURE__*/
31074
31318
  // Summary: Polygon, number of sides, style swatch
31075
31319
  React__namespace.createElement(wonderBlocksCore.View, {
31076
- style: styles$o.row
31320
+ style: styles$p.row
31077
31321
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Polygon, ${points.length} sides`), /*#__PURE__*/React__namespace.createElement(Strut, {
31078
31322
  size: wonderBlocksTokens.spacing.xSmall_8
31079
31323
  }), /*#__PURE__*/React__namespace.createElement(PolygonSwatch, {
@@ -31082,7 +31326,7 @@ const LockedPolygonSettings = props => {
31082
31326
  strokeStyle: strokeStyle
31083
31327
  }))
31084
31328
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31085
- style: [styles$o.row, styles$o.spaceUnder]
31329
+ style: [styles$p.row, styles$p.spaceUnder]
31086
31330
  }, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
31087
31331
  selectedValue: color,
31088
31332
  onChange: handleColorChange
@@ -31090,7 +31334,7 @@ const LockedPolygonSettings = props => {
31090
31334
  size: wonderBlocksTokens.spacing.medium_16
31091
31335
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
31092
31336
  tag: "label",
31093
- style: [styles$o.row, styles$o.truncatedWidth]
31337
+ style: [styles$p.row, styles$p.truncatedWidth]
31094
31338
  }, "fill", /*#__PURE__*/React__namespace.createElement(Strut, {
31095
31339
  size: wonderBlocksTokens.spacing.xxSmall_6
31096
31340
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
@@ -31116,17 +31360,17 @@ const LockedPolygonSettings = props => {
31116
31360
  onChange: newValue => onChangeProps({
31117
31361
  showVertices: newValue
31118
31362
  }),
31119
- style: styles$o.spaceUnder
31363
+ style: styles$p.spaceUnder
31120
31364
  }), /*#__PURE__*/React__namespace.createElement(PerseusEditorAccordion, {
31121
31365
  header: /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, "Points"),
31122
31366
  expanded: true,
31123
- containerStyle: styles$o.pointAccordionContainer,
31124
- panelStyle: styles$o.pointAccordionPanel
31367
+ containerStyle: styles$p.pointAccordionContainer,
31368
+ panelStyle: styles$p.pointAccordionPanel
31125
31369
  }, points.map((point, index) => {
31126
31370
  const pointLabel = String.fromCharCode(65 + index);
31127
31371
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31128
31372
  key: `locked-polygon-point-index-${index}`,
31129
- style: [styles$o.row, styles$o.spaceUnder]
31373
+ style: [styles$p.row, styles$p.spaceUnder]
31130
31374
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `${pointLabel}:`), /*#__PURE__*/React__namespace.createElement(Strut, {
31131
31375
  size: wonderBlocksTokens.spacing.medium_16
31132
31376
  }), /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
@@ -31154,10 +31398,10 @@ const LockedPolygonSettings = props => {
31154
31398
  points: newPoints
31155
31399
  });
31156
31400
  },
31157
- style: styles$o.icon
31401
+ style: styles$p.icon
31158
31402
  }));
31159
31403
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31160
- style: [styles$o.row, styles$o.polygonActionsContainer]
31404
+ style: [styles$p.row, styles$p.polygonActionsContainer]
31161
31405
  }, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
31162
31406
  kind: "tertiary",
31163
31407
  startIcon: plusCircle__default["default"],
@@ -31167,30 +31411,30 @@ const LockedPolygonSettings = props => {
31167
31411
  });
31168
31412
  }
31169
31413
  }, "Add point"), /*#__PURE__*/React__namespace.createElement(Spring, null), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31170
- style: styles$o.movementButtonsContainer
31414
+ style: styles$p.movementButtonsContainer
31171
31415
  }, /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
31172
31416
  "aria-label": "Move polygon up",
31173
- style: styles$o.iconButton,
31417
+ style: styles$p.iconButton,
31174
31418
  size: "small",
31175
31419
  icon: arrowFatUp__default["default"],
31176
31420
  onClick: () => handlePolygonMove("up")
31177
31421
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31178
- style: styles$o.row
31422
+ style: styles$p.row
31179
31423
  }, /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
31180
31424
  "aria-label": "Move polygon left",
31181
- style: styles$o.iconButton,
31425
+ style: styles$p.iconButton,
31182
31426
  size: "small",
31183
31427
  icon: arrowFatLeft__default["default"],
31184
31428
  onClick: () => handlePolygonMove("left")
31185
31429
  }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
31186
31430
  "aria-label": "Move polygon down",
31187
- style: styles$o.iconButton,
31431
+ style: styles$p.iconButton,
31188
31432
  size: "small",
31189
31433
  icon: arrowFatDown__default["default"],
31190
31434
  onClick: () => handlePolygonMove("down")
31191
31435
  }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
31192
31436
  "aria-label": "Move polygon right",
31193
- style: styles$o.iconButton,
31437
+ style: styles$p.iconButton,
31194
31438
  size: "small",
31195
31439
  icon: arrowFatRight__default["default"],
31196
31440
  onClick: () => handlePolygonMove("right")
@@ -31200,7 +31444,7 @@ const LockedPolygonSettings = props => {
31200
31444
  onRemove: onRemove
31201
31445
  }));
31202
31446
  };
31203
- const styles$o = aphrodite.StyleSheet.create({
31447
+ const styles$p = aphrodite.StyleSheet.create({
31204
31448
  row: {
31205
31449
  display: "flex",
31206
31450
  flexDirection: "row",
@@ -31274,7 +31518,7 @@ const LockedVectorSettings = props => {
31274
31518
  expanded: props.expanded,
31275
31519
  onToggle: props.onToggle,
31276
31520
  header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31277
- style: styles$n.row
31521
+ style: styles$o.row
31278
31522
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, lineLabel), /*#__PURE__*/React__namespace.createElement(Strut, {
31279
31523
  size: wonderBlocksTokens.spacing.xSmall_8
31280
31524
  }), /*#__PURE__*/React__namespace.createElement(LineSwatch, {
@@ -31282,19 +31526,19 @@ const LockedVectorSettings = props => {
31282
31526
  lineStyle: "solid"
31283
31527
  }))
31284
31528
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31285
- style: [styles$n.row, styles$n.spaceUnder]
31529
+ style: [styles$o.row, styles$o.spaceUnder]
31286
31530
  }, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
31287
31531
  selectedValue: lineColor,
31288
31532
  onChange: handleColorChange
31289
31533
  })), isInvalid && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
31290
- style: styles$n.errorText
31534
+ style: styles$o.errorText
31291
31535
  }, lengthErrorMessage), /*#__PURE__*/React__namespace.createElement(PerseusEditorAccordion, {
31292
31536
  expanded: true // Initial state is expanded
31293
31537
  ,
31294
- containerStyle: styles$n.container,
31295
- panelStyle: styles$n.accordionPanel,
31538
+ containerStyle: styles$o.container,
31539
+ panelStyle: styles$o.accordionPanel,
31296
31540
  header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31297
- style: styles$n.row
31541
+ style: styles$o.row
31298
31542
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
31299
31543
  }, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
31300
31544
  coord: tail,
@@ -31305,10 +31549,10 @@ const LockedVectorSettings = props => {
31305
31549
  })), /*#__PURE__*/React__namespace.createElement(PerseusEditorAccordion, {
31306
31550
  expanded: true // Initial state is expanded
31307
31551
  ,
31308
- containerStyle: styles$n.container,
31309
- panelStyle: styles$n.accordionPanel,
31552
+ containerStyle: styles$o.container,
31553
+ panelStyle: styles$o.accordionPanel,
31310
31554
  header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31311
- style: styles$n.row
31555
+ style: styles$o.row
31312
31556
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Tip (${tip[0]}, ${tip[1]})`))
31313
31557
  }, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
31314
31558
  coord: tip,
@@ -31322,7 +31566,7 @@ const LockedVectorSettings = props => {
31322
31566
  onRemove: onRemove
31323
31567
  }));
31324
31568
  };
31325
- const styles$n = aphrodite.StyleSheet.create({
31569
+ const styles$o = aphrodite.StyleSheet.create({
31326
31570
  accordionPanel: {
31327
31571
  paddingBottom: wonderBlocksTokens.spacing.medium_16
31328
31572
  },
@@ -31365,10 +31609,7 @@ const LockedFigureSettings = props => {
31365
31609
  case "polygon":
31366
31610
  return /*#__PURE__*/React__namespace.createElement(LockedPolygonSettings, props);
31367
31611
  case "function":
31368
- if (props.showM2bFeatures) {
31369
- return /*#__PURE__*/React__namespace.createElement(LockedFunctionSettings, props);
31370
- }
31371
- break;
31612
+ return /*#__PURE__*/React__namespace.createElement(LockedFunctionSettings, props);
31372
31613
  case "label":
31373
31614
  if (props.showLabelsFlag) {
31374
31615
  return /*#__PURE__*/React__namespace.createElement(LockedLabelSettings, props);
@@ -31481,7 +31722,6 @@ const LockedFiguresSection = props => {
31481
31722
  }), isExpanded && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, figures?.map((figure, index) => {
31482
31723
  return /*#__PURE__*/React__namespace.createElement(LockedFigureSettings, _extends({
31483
31724
  key: `${uniqueId}-locked-${figure}-${index}`,
31484
- showM2bFeatures: props.showM2bFeatures,
31485
31725
  showLabelsFlag: props.showLabelsFlag,
31486
31726
  expanded: expandedStates[index],
31487
31727
  onToggle: newValue => {
@@ -31495,9 +31735,8 @@ const LockedFiguresSection = props => {
31495
31735
  onRemove: () => removeLockedFigure(index)
31496
31736
  }));
31497
31737
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31498
- style: styles$m.buttonContainer
31738
+ style: styles$n.buttonContainer
31499
31739
  }, /*#__PURE__*/React__namespace.createElement(LockedFigureSelect, {
31500
- showM2bFeatures: props.showM2bFeatures,
31501
31740
  showLabelsFlag: props.showLabelsFlag,
31502
31741
  id: `${uniqueId}-select`,
31503
31742
  onChange: addLockedFigure
@@ -31506,10 +31745,10 @@ const LockedFiguresSection = props => {
31506
31745
  }), showExpandButton && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
31507
31746
  kind: "secondary",
31508
31747
  onClick: () => toggleExpanded(allCollapsed),
31509
- style: styles$m.button
31748
+ style: styles$n.button
31510
31749
  }, buttonLabel))));
31511
31750
  };
31512
- const styles$m = aphrodite.StyleSheet.create({
31751
+ const styles$n = aphrodite.StyleSheet.create({
31513
31752
  buttonContainer: {
31514
31753
  flexDirection: "row",
31515
31754
  alignItems: "center"
@@ -31545,7 +31784,7 @@ const GraphPointsCountSelector = _ref => {
31545
31784
  // Never uses placeholder, always has value
31546
31785
  ,
31547
31786
  placeholder: "",
31548
- style: styles$l.singleSelectShort
31787
+ style: styles$m.singleSelectShort
31549
31788
  }, [...[...Array(7).keys()].map(n => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
31550
31789
  key: n,
31551
31790
  value: `${n}`,
@@ -31556,7 +31795,7 @@ const GraphPointsCountSelector = _ref => {
31556
31795
  label: "unlimited"
31557
31796
  })]);
31558
31797
  };
31559
- const styles$l = aphrodite.StyleSheet.create({
31798
+ const styles$m = aphrodite.StyleSheet.create({
31560
31799
  singleSelectShort: {
31561
31800
  // Non-standard spacing, but it's the smallest we can go
31562
31801
  // without running into styling issues with the dropdown.
@@ -31569,7 +31808,7 @@ const GraphTypeSelector = props => {
31569
31808
  selectedValue: props.graphType,
31570
31809
  onChange: props.onChange,
31571
31810
  placeholder: "Select a graph type",
31572
- style: styles$k.singleSelectShort
31811
+ style: styles$l.singleSelectShort
31573
31812
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
31574
31813
  value: "linear",
31575
31814
  label: "Linear function"
@@ -31602,7 +31841,7 @@ const GraphTypeSelector = props => {
31602
31841
  label: "Angle"
31603
31842
  }));
31604
31843
  };
31605
- const styles$k = aphrodite.StyleSheet.create({
31844
+ const styles$l = aphrodite.StyleSheet.create({
31606
31845
  singleSelectShort: {
31607
31846
  // Non-standard spacing, but it's the smallest we can go
31608
31847
  // without running into styling issues with the dropdown.
@@ -31633,6 +31872,53 @@ function InteractiveGraphCorrectAnswer(props) {
31633
31872
  }, props.equationString)), props.children));
31634
31873
  }
31635
31874
 
31875
+ function InteractiveGraphDescription(props) {
31876
+ const {
31877
+ ariaLabelValue,
31878
+ ariaDescriptionValue,
31879
+ onChange
31880
+ } = props;
31881
+ const [isOpen, setIsOpen] = React__namespace.useState(true);
31882
+ return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Heading, {
31883
+ title: "Description",
31884
+ isCollapsible: true,
31885
+ isOpen: isOpen,
31886
+ onToggle: setIsOpen
31887
+ }), isOpen && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelXSmall, {
31888
+ style: styles$k.caption
31889
+ }, "Use these fields to describe the graph as a whole. These are used by screen readers to describe content to users who are visually impaired."), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
31890
+ tag: "label"
31891
+ }, "Title", /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
31892
+ value: ariaLabelValue,
31893
+ onChange: newValue => onChange({
31894
+ fullGraphAriaLabel: newValue
31895
+ }),
31896
+ style: styles$k.spaceAbove
31897
+ })), /*#__PURE__*/React__namespace.createElement(Strut, {
31898
+ size: wonderBlocksTokens.spacing.small_12
31899
+ }), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
31900
+ tag: "label"
31901
+ }, "Description", /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextArea, {
31902
+ rows: 8,
31903
+ resizeType: "vertical",
31904
+ value: ariaDescriptionValue,
31905
+ onChange: newValue => onChange({
31906
+ fullGraphAriaDescription: newValue
31907
+ }),
31908
+ style: styles$k.spaceAbove
31909
+ }))));
31910
+ }
31911
+ const styles$k = aphrodite.StyleSheet.create({
31912
+ caption: {
31913
+ color: wonderBlocksTokens.color.offBlack64,
31914
+ paddingTop: wonderBlocksTokens.spacing.xxSmall_6,
31915
+ paddingBottom: wonderBlocksTokens.spacing.xxSmall_6
31916
+ },
31917
+ spaceAbove: {
31918
+ marginTop: wonderBlocksTokens.spacing.xxxSmall_4
31919
+ }
31920
+ });
31921
+
31636
31922
  /* eslint-disable react/forbid-prop-types, react/no-unsafe */
31637
31923
  const {
31638
31924
  ButtonGroup: ButtonGroup$2,
@@ -32608,15 +32894,6 @@ class InteractiveGraphEditor extends React__namespace.Component {
32608
32894
  coords: null
32609
32895
  }
32610
32896
  };
32611
- changeMatchType = newValue => {
32612
- const correct = {
32613
- ...this.props.correct,
32614
- match: newValue
32615
- };
32616
- this.props.onChange({
32617
- correct: correct
32618
- });
32619
- };
32620
32897
  changeStartCoords = coords => {
32621
32898
  if (!this.props.graph?.type) {
32622
32899
  return;
@@ -32635,7 +32912,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
32635
32912
  // is copied from the question editor and pasted into the hint editor
32636
32913
  // (double brackets in the markdown).
32637
32914
  serialize() {
32638
- const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showTooltips", "range", "gridStep", "snapStep", "lockedFigures");
32915
+ const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showTooltips", "range", "gridStep", "snapStep", "lockedFigures", "fullGraphAriaLabel", "fullGraphAriaDescription");
32639
32916
 
32640
32917
  // eslint-disable-next-line react/no-string-refs
32641
32918
  const graph = this.refs.graph;
@@ -32694,18 +32971,22 @@ class InteractiveGraphEditor extends React__namespace.Component {
32694
32971
  showProtractor: this.props.showProtractor,
32695
32972
  showTooltips: this.props.showTooltips,
32696
32973
  lockedFigures: this.props.lockedFigures,
32974
+ fullGraphAriaLabel: this.props.fullGraphAriaLabel,
32975
+ fullGraphAriaDescription: this.props.fullGraphAriaDescription,
32697
32976
  trackInteraction: function () {},
32698
- onChange: newProps => {
32977
+ onChange: _ref => {
32978
+ let {
32979
+ graph: newGraph
32980
+ } = _ref;
32699
32981
  let correct = this.props.correct;
32700
- // @ts-expect-error - TS2532 - Object is possibly 'undefined'.
32701
- if (correct.type === newProps.graph.type) {
32702
- correct = {
32703
- ...correct,
32704
- ...newProps.graph
32705
- };
32982
+ // TODO(benchristel): can we improve the type of onChange
32983
+ // so this invariant isn't necessary?
32984
+ invariant(newGraph != null);
32985
+ if (correct.type === newGraph.type) {
32986
+ correct = mergeGraphs(correct, newGraph);
32706
32987
  } else {
32707
32988
  // Clear options from previous graph
32708
- correct = newProps.graph;
32989
+ correct = newGraph;
32709
32990
  }
32710
32991
  this.props.onChange({
32711
32992
  correct: correct,
@@ -32749,7 +33030,11 @@ class InteractiveGraphEditor extends React__namespace.Component {
32749
33030
  }
32750
33031
  });
32751
33032
  }
32752
- })), /*#__PURE__*/React__namespace.createElement(InteractiveGraphCorrectAnswer, {
33033
+ })), this.props.graph && this.props.apiOptions?.flags?.mafs?.[this.props.graph.type] && /*#__PURE__*/React__namespace.createElement(InteractiveGraphDescription, {
33034
+ ariaLabelValue: this.props.fullGraphAriaLabel ?? "",
33035
+ ariaDescriptionValue: this.props.fullGraphAriaDescription ?? "",
33036
+ onChange: this.props.onChange
33037
+ }), /*#__PURE__*/React__namespace.createElement(InteractiveGraphCorrectAnswer, {
32753
33038
  equationString: equationString
32754
33039
  }, graph), this.props.correct?.type === "point" && /*#__PURE__*/React__namespace.createElement(LabeledRow, {
32755
33040
  label: "Number of Points:"
@@ -32774,8 +33059,8 @@ class InteractiveGraphEditor extends React__namespace.Component {
32774
33059
  selectedValue: this.props.correct?.numSides ? `${this.props.correct.numSides}` : "3",
32775
33060
  placeholder: "",
32776
33061
  onChange: newValue => {
32777
- const graph = {
32778
- ...this.props.correct,
33062
+ invariant(this.props.graph?.type === "polygon");
33063
+ const updates = {
32779
33064
  numSides: parsePointCount(newValue),
32780
33065
  coords: null,
32781
33066
  // reset the snap for UNLIMITED, which
@@ -32784,8 +33069,14 @@ class InteractiveGraphEditor extends React__namespace.Component {
32784
33069
  snapTo: "grid"
32785
33070
  };
32786
33071
  this.props.onChange({
32787
- correct: graph,
32788
- graph: graph
33072
+ correct: {
33073
+ ...this.props.correct,
33074
+ ...updates
33075
+ },
33076
+ graph: {
33077
+ ...this.props.graph,
33078
+ ...updates
33079
+ }
32789
33080
  });
32790
33081
  },
32791
33082
  style: styles$a.singleSelectShort
@@ -32801,14 +33092,21 @@ class InteractiveGraphEditor extends React__namespace.Component {
32801
33092
  ,
32802
33093
  placeholder: "",
32803
33094
  onChange: newValue => {
32804
- const graph = {
32805
- ...this.props.correct,
33095
+ invariant(this.props.correct.type === "polygon", `Expected correct answer type to be polygon, but got ${this.props.correct.type}`);
33096
+ invariant(this.props.graph?.type === "polygon", `Expected graph type to be polygon, but got ${this.props.graph?.type}`);
33097
+ const updates = {
32806
33098
  snapTo: newValue,
32807
33099
  coords: null
32808
33100
  };
32809
33101
  this.props.onChange({
32810
- correct: graph,
32811
- graph: graph
33102
+ correct: {
33103
+ ...this.props.correct,
33104
+ ...updates
33105
+ },
33106
+ graph: {
33107
+ ...this.props.graph,
33108
+ ...updates
33109
+ }
32812
33110
  });
32813
33111
  },
32814
33112
  style: styles$a.singleSelectShort
@@ -32830,6 +33128,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
32830
33128
  !!this.props.correct?.showAngles,
32831
33129
  onChange: () => {
32832
33130
  if (this.props.graph?.type === "polygon") {
33131
+ invariant(this.props.correct.type === "polygon", `Expected graph type to be polygon, but got ${this.props.correct.type}`);
32833
33132
  this.props.onChange({
32834
33133
  correct: {
32835
33134
  ...this.props.correct,
@@ -32850,7 +33149,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
32850
33149
  // Don't show indeterminate checkbox state
32851
33150
  !!this.props.correct?.showSides,
32852
33151
  onChange: () => {
32853
- if (this.props.graph?.type === "polygon") {
33152
+ if (this.props.graph?.type === "polygon" && this.props.correct.type === "polygon") {
32854
33153
  this.props.onChange({
32855
33154
  correct: {
32856
33155
  ...this.props.correct,
@@ -32880,9 +33179,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
32880
33179
  }
32881
33180
  });
32882
33181
  }
32883
- })), this.props.graph?.type &&
32884
- // TODO(LEMS-2228): Remove flags once this is fully released
32885
- shouldShowStartCoordsUI(this.props.apiOptions.flags, this.props.graph) && /*#__PURE__*/React__namespace.createElement(StartCoordsSettings, _extends({}, this.props.graph, {
33182
+ })), this.props.graph?.type && shouldShowStartCoordsUI(this.props.graph, this.props.static) && /*#__PURE__*/React__namespace.createElement(StartCoordsSettings, _extends({}, this.props.graph, {
32886
33183
  range: this.props.range,
32887
33184
  step: this.props.step,
32888
33185
  onChange: this.changeStartCoords
@@ -32903,7 +33200,23 @@ class InteractiveGraphEditor extends React__namespace.Component {
32903
33200
  label: "Student answer must"
32904
33201
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
32905
33202
  selectedValue: this.props.correct.match || "exact",
32906
- onChange: this.changeMatchType
33203
+ onChange: newValue => {
33204
+ invariant(this.props.correct.type === "polygon", `Expected graph type to be polygon, but got ${this.props.correct.type}`);
33205
+ const correct = {
33206
+ ...this.props.correct,
33207
+ // TODO(benchristel): this cast is necessary
33208
+ // because "exact" is not actually a valid
33209
+ // value for `match`; a value of undefined
33210
+ // means exact matching. The code happens
33211
+ // to work because "exact" falls through
33212
+ // to the correct else branch in
33213
+ // InteractiveGraph.validate()
33214
+ match: newValue
33215
+ };
33216
+ this.props.onChange({
33217
+ correct
33218
+ });
33219
+ }
32907
33220
  // Never uses placeholder, always has value
32908
33221
  ,
32909
33222
  placeholder: "",
@@ -32924,7 +33237,21 @@ class InteractiveGraphEditor extends React__namespace.Component {
32924
33237
  label: "Student answer must"
32925
33238
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
32926
33239
  selectedValue: this.props.correct.match || "exact",
32927
- onChange: this.changeMatchType
33240
+ onChange: newValue => {
33241
+ this.props.onChange({
33242
+ correct: {
33243
+ ...this.props.correct,
33244
+ // TODO(benchristel): this cast is necessary
33245
+ // because "exact" is not actually a valid
33246
+ // value for `match`; a value of undefined
33247
+ // means exact matching. The code happens
33248
+ // to work because "exact" falls through
33249
+ // to the correct else branch in
33250
+ // InteractiveGraph.validate()
33251
+ match: newValue
33252
+ }
33253
+ });
33254
+ }
32928
33255
  // Never uses placeholder, always has value
32929
33256
  ,
32930
33257
  placeholder: "",
@@ -32939,13 +33266,85 @@ class InteractiveGraphEditor extends React__namespace.Component {
32939
33266
  // Only show the "Add locked figure" dropdown if the graph
32940
33267
  // is using Mafs.
32941
33268
  this.props.graph && this.props.apiOptions?.flags?.mafs?.[this.props.graph.type] && /*#__PURE__*/React__namespace.createElement(LockedFiguresSection, {
32942
- showM2bFeatures: this.props.apiOptions?.flags?.mafs?.["interactive-graph-locked-features-m2b"],
32943
33269
  showLabelsFlag: this.props.apiOptions?.flags?.mafs?.["interactive-graph-locked-features-labels"],
32944
33270
  figures: this.props.lockedFigures,
32945
33271
  onChange: this.props.onChange
32946
33272
  }));
32947
33273
  }
32948
33274
  }
33275
+
33276
+ // Merges two graphs that have the same `type`. Properties defined in `b`
33277
+ // overwrite properties of the same name in `a`. Throws an exception if the
33278
+ // types are different or not recognized.
33279
+ function mergeGraphs(a, b) {
33280
+ if (a.type !== b.type) {
33281
+ throw new Error(`Cannot merge graphs with different types (${a.type} and ${b.type})`);
33282
+ }
33283
+ switch (a.type) {
33284
+ case "angle":
33285
+ invariant(b.type === "angle");
33286
+ return {
33287
+ ...a,
33288
+ ...b
33289
+ };
33290
+ case "circle":
33291
+ invariant(b.type === "circle");
33292
+ return {
33293
+ ...a,
33294
+ ...b
33295
+ };
33296
+ case "linear":
33297
+ invariant(b.type === "linear");
33298
+ return {
33299
+ ...a,
33300
+ ...b
33301
+ };
33302
+ case "linear-system":
33303
+ invariant(b.type === "linear-system");
33304
+ return {
33305
+ ...a,
33306
+ ...b
33307
+ };
33308
+ case "point":
33309
+ invariant(b.type === "point");
33310
+ return {
33311
+ ...a,
33312
+ ...b
33313
+ };
33314
+ case "polygon":
33315
+ invariant(b.type === "polygon");
33316
+ return {
33317
+ ...a,
33318
+ ...b
33319
+ };
33320
+ case "quadratic":
33321
+ invariant(b.type === "quadratic");
33322
+ return {
33323
+ ...a,
33324
+ ...b
33325
+ };
33326
+ case "ray":
33327
+ invariant(b.type === "ray");
33328
+ return {
33329
+ ...a,
33330
+ ...b
33331
+ };
33332
+ case "segment":
33333
+ invariant(b.type === "segment");
33334
+ return {
33335
+ ...a,
33336
+ ...b
33337
+ };
33338
+ case "sinusoid":
33339
+ invariant(b.type === "sinusoid");
33340
+ return {
33341
+ ...a,
33342
+ ...b
33343
+ };
33344
+ default:
33345
+ throw new wonderStuffCore.UnreachableCaseError(a);
33346
+ }
33347
+ }
32949
33348
  const styles$a = aphrodite.StyleSheet.create({
32950
33349
  singleSelectShort: {
32951
33350
  // Non-standard spacing, but it's the smallest we can go