@khanacademy/perseus-editor 3.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-core';
2
- import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusError, Errors, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, ItemExtras, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, TransformerWidget, displaySigFigs, widgets } from '@khanacademy/perseus';
2
+ import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusError, Errors, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, ItemExtras, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, displaySigFigs, widgets } from '@khanacademy/perseus';
3
3
  import * as React from 'react';
4
4
  import { useRef, useEffect } from 'react';
5
5
  import _ from 'underscore';
@@ -14,7 +14,7 @@ import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
14
14
  import caretRight from '@phosphor-icons/core/bold/caret-right-bold.svg';
15
15
  import classNames from 'classnames';
16
16
  import ReactDOM from 'react-dom';
17
- import { point, number, line, ray, vector } from '@khanacademy/kmath';
17
+ import { point, number } from '@khanacademy/kmath';
18
18
  import * as KAS from '@khanacademy/kas';
19
19
  import { isTruthy } from '@khanacademy/wonder-stuff-core';
20
20
  import { createMathField } from '@khanacademy/math-input';
@@ -25,7 +25,7 @@ import * as i18n$1 from '@khanacademy/wonder-blocks-i18n';
25
25
 
26
26
  // This file is processed by a Rollup plugin (replace) to inject the production
27
27
  const libName = "@khanacademy/perseus-editor";
28
- const libVersion = "3.0.1";
28
+ const libVersion = "4.1.0";
29
29
  addLibraryVersionToPerseusDebug(libName, libVersion);
30
30
 
31
31
  function _extends() {
@@ -23452,7 +23452,7 @@ class StructuredItemDiff extends React.Component {
23452
23452
 
23453
23453
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
23454
23454
  const {
23455
- InfoTip: InfoTip$n,
23455
+ InfoTip: InfoTip$m,
23456
23456
  InlineIcon: InlineIcon$8
23457
23457
  } = components;
23458
23458
  const {
@@ -23524,7 +23524,7 @@ class HintEditor extends React.Component {
23524
23524
  type: "button",
23525
23525
  className: this.props.isFirst ? "hidden" : "",
23526
23526
  onClick: _.partial(this.props.onMove, -1)
23527
- }, /*#__PURE__*/React.createElement(InlineIcon$8, iconCircleArrowUp$1)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$n, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23527
+ }, /*#__PURE__*/React.createElement(InlineIcon$8, iconCircleArrowUp$1)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$m, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23528
23528
  type: "checkbox"
23529
23529
  // @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
23530
23530
  ,
@@ -23777,7 +23777,7 @@ CombinedHintsEditor.defaultProps = {
23777
23777
  };
23778
23778
 
23779
23779
  const {
23780
- InfoTip: InfoTip$m
23780
+ InfoTip: InfoTip$l
23781
23781
  } = components;
23782
23782
  class ItemExtrasEditor extends React.Component {
23783
23783
  constructor(...args) {
@@ -23935,7 +23935,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement("div", {
23935
23935
  type: "checkbox",
23936
23936
  checked: props.checked,
23937
23937
  onChange: props.onChange
23938
- })), /*#__PURE__*/React.createElement(InfoTip$m, null, props.infoTip));
23938
+ })), /*#__PURE__*/React.createElement(InfoTip$l, null, props.infoTip));
23939
23939
 
23940
23940
  const ITEM_DATA_VERSION = itemDataVersion;
23941
23941
  class ItemEditor extends React.Component {
@@ -24322,8 +24322,6 @@ function widgetCallback(widgetInfo, images) {
24322
24322
  images.push(widgetInfo.options.image.url);
24323
24323
  } else if (widgetInfo.type === "plotter") {
24324
24324
  images.push(widgetInfo.options.picUrl);
24325
- } else if (widgetInfo.type === "transformer") {
24326
- handleBackgroundImage(widgetInfo.options.graph, images);
24327
24325
  }
24328
24326
  }
24329
24327
  function findImagesInRenderers(renderers) {
@@ -25767,7 +25765,7 @@ const StatefulEditorPage = createReactClass({
25767
25765
  });
25768
25766
 
25769
25767
  const {
25770
- PropCheckBox: PropCheckBox$d,
25768
+ PropCheckBox: PropCheckBox$c,
25771
25769
  TextListEditor: TextListEditor$4
25772
25770
  } = components;
25773
25771
  const Categorizer = Categorizer$1.widget;
@@ -25784,7 +25782,7 @@ class CategorizerEditor extends React.Component {
25784
25782
  render() {
25785
25783
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
25786
25784
  className: "perseus-widget-row"
25787
- }, /*#__PURE__*/React.createElement(PropCheckBox$d, {
25785
+ }, /*#__PURE__*/React.createElement(PropCheckBox$c, {
25788
25786
  label: "Randomize item order",
25789
25787
  labelAlignment: "right",
25790
25788
  randomizeItems: this.props.randomizeItems,
@@ -25896,8 +25894,8 @@ class BlurInput extends React.Component {
25896
25894
  }
25897
25895
 
25898
25896
  const {
25899
- InfoTip: InfoTip$l,
25900
- PropCheckBox: PropCheckBox$c
25897
+ InfoTip: InfoTip$k,
25898
+ PropCheckBox: PropCheckBox$b
25901
25899
  } = components;
25902
25900
  const DEFAULT_WIDTH = 400;
25903
25901
  const DEFAULT_HEIGHT = 400;
@@ -26053,11 +26051,11 @@ class CSProgramEditor extends React.Component {
26053
26051
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Url or Program ID:", " ", /*#__PURE__*/React.createElement(BlurInput, {
26054
26052
  value: this.props.programID,
26055
26053
  onChange: this._handleProgramIDChange
26056
- })), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$c, {
26054
+ })), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
26057
26055
  label: "Show Editor",
26058
26056
  showEditor: this.props.showEditor,
26059
26057
  onChange: this.props.onChange
26060
- }), /*#__PURE__*/React.createElement(InfoTip$l, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$c, {
26058
+ }), /*#__PURE__*/React.createElement(InfoTip$k, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
26061
26059
  label: "Show Buttons",
26062
26060
  showButtons: this.props.showButtons,
26063
26061
  onChange: this.props.onChange
@@ -26065,7 +26063,7 @@ class CSProgramEditor extends React.Component {
26065
26063
  name: "settings",
26066
26064
  pairs: this.props.settings,
26067
26065
  onChange: this._handleSettingsChange
26068
- }), /*#__PURE__*/React.createElement(InfoTip$l, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
26066
+ }), /*#__PURE__*/React.createElement(InfoTip$k, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
26069
26067
  }
26070
26068
  }
26071
26069
  CSProgramEditor.propTypes = _extends({}, Changeable.propTypes);
@@ -26151,7 +26149,7 @@ DeprecatedStandinEditor.widgetName = "deprecated-standin";
26151
26149
 
26152
26150
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
26153
26151
  const {
26154
- InfoTip: InfoTip$k,
26152
+ InfoTip: InfoTip$j,
26155
26153
  InlineIcon: InlineIcon$6
26156
26154
  } = components;
26157
26155
  const {
@@ -26220,14 +26218,14 @@ class DropdownEditor extends React.Component {
26220
26218
  className: "perseus-widget-dropdown"
26221
26219
  }, /*#__PURE__*/React.createElement("div", {
26222
26220
  className: "dropdown-info"
26223
- }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26221
+ }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26224
26222
  className: "dropdown-placeholder"
26225
26223
  }, /*#__PURE__*/React.createElement("input", {
26226
26224
  type: "text",
26227
26225
  placeholder: "Placeholder value",
26228
26226
  value: this.props.placeholder,
26229
26227
  onChange: this.onPlaceholderChange
26230
- }), /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React.createElement("div", {
26228
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React.createElement("div", {
26231
26229
  className: "clearfix"
26232
26230
  }), /*#__PURE__*/React.createElement("ul", {
26233
26231
  className: "dropdown-choices"
@@ -26761,8 +26759,8 @@ const SortableItem = createReactClass({
26761
26759
  });
26762
26760
 
26763
26761
  const {
26764
- InfoTip: InfoTip$j,
26765
- PropCheckBox: PropCheckBox$b
26762
+ InfoTip: InfoTip$i,
26763
+ PropCheckBox: PropCheckBox$a
26766
26764
  } = components;
26767
26765
 
26768
26766
  // types for iterables
@@ -27009,16 +27007,16 @@ class ExpressionEditor extends React.Component {
27009
27007
  className: "perseus-widget-expression-editor"
27010
27008
  }, /*#__PURE__*/React.createElement("h3", {
27011
27009
  className: "expression-editor-h3"
27012
- }, "Global Options"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$b, {
27010
+ }, "Global Options"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27013
27011
  times: this.props.times,
27014
27012
  onChange: this.props.onChange,
27015
27013
  labelAlignment: "right",
27016
27014
  label: "Use \xD7 for rendering multiplication instead of a center dot."
27017
- }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.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.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Function variables: ", /*#__PURE__*/React.createElement("input", {
27015
+ }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.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.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Function variables: ", /*#__PURE__*/React.createElement("input", {
27018
27016
  type: "text",
27019
27017
  defaultValue: this.props.functions.join(" "),
27020
27018
  onChange: this.handleFunctions
27021
- })), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.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.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React.createElement("h3", {
27019
+ })), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.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.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React.createElement("h3", {
27022
27020
  className: "expression-editor-h3"
27023
27021
  }, "Answers"), /*#__PURE__*/React.createElement("p", {
27024
27022
  style: {
@@ -27108,19 +27106,19 @@ class AnswerOption extends React.Component {
27108
27106
  className: "answer-expression"
27109
27107
  }, /*#__PURE__*/React.createElement(Expression, this.props.expressionProps))), /*#__PURE__*/React.createElement("div", {
27110
27108
  className: "answer-option"
27111
- }, /*#__PURE__*/React.createElement(PropCheckBox$b, {
27109
+ }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27112
27110
  form: this.props.form,
27113
27111
  onChange: this.props.onChange,
27114
27112
  labelAlignment: "right",
27115
27113
  label: "Answer expression must have the same form."
27116
- }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
27114
+ }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
27117
27115
  className: "answer-option"
27118
- }, /*#__PURE__*/React.createElement(PropCheckBox$b, {
27116
+ }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27119
27117
  simplify: this.props.simplify,
27120
27118
  onChange: this.props.onChange,
27121
27119
  labelAlignment: "right",
27122
27120
  label: "Answer expression must be fully expanded and simplified."
27123
- }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.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.createElement("div", {
27121
+ }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.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.createElement("div", {
27124
27122
  className: "remove-container"
27125
27123
  }, removeButton)));
27126
27124
  }
@@ -27320,14 +27318,14 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
27320
27318
 
27321
27319
  const {
27322
27320
  ButtonGroup: ButtonGroup$3,
27323
- InfoTip: InfoTip$i,
27324
- PropCheckBox: PropCheckBox$a,
27321
+ InfoTip: InfoTip$h,
27322
+ PropCheckBox: PropCheckBox$9,
27325
27323
  RangeInput: RangeInput$5
27326
27324
  } = components;
27327
27325
  const {
27328
27326
  getDependencies: getDependencies$9
27329
27327
  } = Dependencies;
27330
- const defaultBackgroundImage$3 = {
27328
+ const defaultBackgroundImage$2 = {
27331
27329
  url: null,
27332
27330
  width: 0,
27333
27331
  height: 0
@@ -27364,7 +27362,7 @@ const GraphSettings = createReactClass({
27364
27362
  gridStep: [1, 1],
27365
27363
  snapStep: [1, 1],
27366
27364
  valid: true,
27367
- backgroundImage: defaultBackgroundImage$3,
27365
+ backgroundImage: defaultBackgroundImage$2,
27368
27366
  markings: "graph",
27369
27367
  showProtractor: false,
27370
27368
  showRuler: false,
@@ -27729,7 +27727,7 @@ const GraphSettings = createReactClass({
27729
27727
  onChange: this.change("markings")
27730
27728
  })), /*#__PURE__*/React.createElement("div", {
27731
27729
  className: "perseus-widget-left-col"
27732
- }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27730
+ }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27733
27731
  label: "Show tooltips",
27734
27732
  showTooltips: this.props.showTooltips,
27735
27733
  onChange: this.change
@@ -27751,19 +27749,19 @@ const GraphSettings = createReactClass({
27751
27749
  },
27752
27750
  onKeyPress: this.changeBackgroundUrl,
27753
27751
  onBlur: this.changeBackgroundUrl
27754
- }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27752
+ }), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27755
27753
  className: "misc-settings"
27756
27754
  }, /*#__PURE__*/React.createElement("div", {
27757
27755
  className: "perseus-widget-row"
27758
27756
  }, /*#__PURE__*/React.createElement("div", {
27759
27757
  className: "perseus-widget-left-col"
27760
- }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27758
+ }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27761
27759
  label: "Show ruler",
27762
27760
  showRuler: this.props.showRuler,
27763
27761
  onChange: this.change
27764
27762
  })), /*#__PURE__*/React.createElement("div", {
27765
27763
  className: "perseus-widget-right-col"
27766
- }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27764
+ }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27767
27765
  label: "Show protractor",
27768
27766
  showProtractor: this.props.showProtractor,
27769
27767
  onChange: this.change
@@ -27788,7 +27786,7 @@ const GraphSettings = createReactClass({
27788
27786
  });
27789
27787
 
27790
27788
  const {
27791
- InfoTip: InfoTip$h,
27789
+ InfoTip: InfoTip$g,
27792
27790
  MultiButtonGroup: MultiButtonGroup$1
27793
27791
  } = components;
27794
27792
  const {
@@ -27871,7 +27869,7 @@ class GrapherEditor extends React.Component {
27871
27869
  className: "perseus-error"
27872
27870
  }, this.props.graph.valid);
27873
27871
  }
27874
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27872
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$g, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27875
27873
  editableSettings: ["graph", "snap", "image"],
27876
27874
  box: getInteractiveBoxFromSizeClass$1(sizeClass),
27877
27875
  range: this.props.graph.range,
@@ -27966,7 +27964,7 @@ GroupEditor.defaultProps = {
27966
27964
  };
27967
27965
 
27968
27966
  const {
27969
- PropCheckBox: PropCheckBox$9
27967
+ PropCheckBox: PropCheckBox$8
27970
27968
  } = components;
27971
27969
  /**
27972
27970
  * This is used for editing a name/value pair.
@@ -28089,11 +28087,11 @@ class IframeEditor extends React.Component {
28089
28087
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
28090
28088
  ,
28091
28089
  onChange: this.change("height")
28092
- })), /*#__PURE__*/React.createElement(PropCheckBox$9, {
28090
+ })), /*#__PURE__*/React.createElement(PropCheckBox$8, {
28093
28091
  label: "Allow full screen",
28094
28092
  allowFullScreen: this.props.allowFullScreen,
28095
28093
  onChange: this.props.onChange
28096
- }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$9, {
28094
+ }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$8, {
28097
28095
  label: "Allow iframe content to redirect the page",
28098
28096
  allowTopNavigation: this.props.allowTopNavigation,
28099
28097
  onChange: this.props.onChange
@@ -28114,14 +28112,15 @@ IframeEditor.defaultProps = {
28114
28112
  allowTopNavigation: false
28115
28113
  };
28116
28114
 
28115
+ /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
28117
28116
  const {
28118
- InfoTip: InfoTip$g,
28117
+ InfoTip: InfoTip$f,
28119
28118
  InlineIcon: InlineIcon$4,
28120
28119
  RangeInput: RangeInput$4
28121
28120
  } = components;
28122
28121
  const defaultBoxSize = 400;
28123
28122
  const defaultRange = [0, 10];
28124
- const defaultBackgroundImage$2 = {
28123
+ const defaultBackgroundImage$1 = {
28125
28124
  url: null,
28126
28125
  width: 0,
28127
28126
  height: 0
@@ -28138,37 +28137,23 @@ const INTERNALLY_HOSTED_URL_RE = new RegExp("^(https?|web\\+graphie)://[^/]*" +
28138
28137
  * Alignment option for captions, relative to specified coordinates.
28139
28138
  */
28140
28139
  const captionAlignments = ["center", "above", "above right", "right", "below right", "below", "below left", "left", "above left"];
28141
- const ImageEditor = createReactClass({
28142
- displayName: "ImageEditor",
28143
- propTypes: _extends({}, Changeable.propTypes),
28144
- statics: {
28145
- widgetName: "image"
28146
- },
28147
- componentDidMount: function () {
28140
+ class ImageEditor extends React.Component {
28141
+ constructor(...args) {
28142
+ super(...args);
28143
+ this._isMounted = false;
28144
+ this.state = {
28145
+ backgroundImageError: ""
28146
+ };
28147
+ }
28148
+ componentDidMount() {
28148
28149
  // TODO(scottgrant): This is a hack to remove the deprecated call to
28149
28150
  // this.isMounted() but is still considered an anti-pattern.
28150
28151
  this._isMounted = true;
28151
- },
28152
- componentWillUnmount: function () {
28152
+ }
28153
+ componentWillUnmount() {
28153
28154
  this._isMounted = false;
28154
- },
28155
- getDefaultProps: function () {
28156
- return {
28157
- title: "",
28158
- range: [defaultRange, defaultRange],
28159
- box: [defaultBoxSize, defaultBoxSize],
28160
- backgroundImage: defaultBackgroundImage$2,
28161
- labels: [],
28162
- alt: "",
28163
- caption: ""
28164
- };
28165
- },
28166
- getInitialState: function () {
28167
- return {
28168
- backgroundImageError: ""
28169
- };
28170
- },
28171
- render: function () {
28155
+ }
28156
+ render() {
28172
28157
  const backgroundImage = this.props.backgroundImage;
28173
28158
  const imageSettings = /*#__PURE__*/React.createElement("div", {
28174
28159
  className: "image-settings"
@@ -28178,7 +28163,7 @@ const ImageEditor = createReactClass({
28178
28163
  style: {
28179
28164
  width: "100%"
28180
28165
  }
28181
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$g, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28166
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28182
28167
  apiOptions: this.props.apiOptions,
28183
28168
  content: this.props.alt,
28184
28169
  onChange: props => {
@@ -28202,15 +28187,15 @@ const ImageEditor = createReactClass({
28202
28187
  }, this.state.backgroundImageError);
28203
28188
  return /*#__PURE__*/React.createElement("div", {
28204
28189
  className: "perseus-image-editor"
28205
- }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$g, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28190
+ }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28206
28191
  value: backgroundImage.url || "",
28207
28192
  style: {
28208
28193
  width: 332
28209
28194
  },
28210
28195
  onChange: url => this.onUrlChange(url, false)
28211
28196
  })), backgroundImage.url && imageSettings);
28212
- },
28213
- _renderRowForLabel: function (label, i) {
28197
+ }
28198
+ _renderRowForLabel(label, i) {
28214
28199
  return /*#__PURE__*/React.createElement("tr", {
28215
28200
  key: i
28216
28201
  }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(RangeInput$4, {
@@ -28249,19 +28234,19 @@ const ImageEditor = createReactClass({
28249
28234
  ,
28250
28235
  onClick: this.removeLabel.bind(this, i)
28251
28236
  }, /*#__PURE__*/React.createElement(InlineIcon$4, icons.iconTrash))));
28252
- },
28237
+ }
28253
28238
  change(...args) {
28254
28239
  return Changeable.change.apply(this, args);
28255
- },
28256
- removeLabel: function (labelIndex, e) {
28240
+ }
28241
+ removeLabel(labelIndex, e) {
28257
28242
  e.preventDefault();
28258
- const labels = _(this.props.labels).clone();
28243
+ const labels = [...this.props.labels];
28259
28244
  labels.splice(labelIndex, 1);
28260
28245
  this.props.onChange({
28261
28246
  labels: labels
28262
28247
  });
28263
- },
28264
- onCoordinateChange: function (labelIndex, newCoordinates) {
28248
+ }
28249
+ onCoordinateChange(labelIndex, newCoordinates) {
28265
28250
  const labels = this.props.labels.slice();
28266
28251
  labels[labelIndex] = _.extend({}, labels[labelIndex], {
28267
28252
  coordinates: newCoordinates
@@ -28269,8 +28254,8 @@ const ImageEditor = createReactClass({
28269
28254
  this.props.onChange({
28270
28255
  labels: labels
28271
28256
  });
28272
- },
28273
- onContentChange: function (labelIndex, e) {
28257
+ }
28258
+ onContentChange(labelIndex, e) {
28274
28259
  const newContent = e.target.value;
28275
28260
  const labels = this.props.labels.slice();
28276
28261
  labels[labelIndex] = _.extend({}, labels[labelIndex], {
@@ -28279,8 +28264,8 @@ const ImageEditor = createReactClass({
28279
28264
  this.props.onChange({
28280
28265
  labels: labels
28281
28266
  });
28282
- },
28283
- onAlignmentChange: function (labelIndex, e) {
28267
+ }
28268
+ onAlignmentChange(labelIndex, e) {
28284
28269
  const newAlignment = e.target.value;
28285
28270
  const labels = this.props.labels.slice();
28286
28271
  labels[labelIndex] = _.extend({}, labels[labelIndex], {
@@ -28289,8 +28274,8 @@ const ImageEditor = createReactClass({
28289
28274
  this.props.onChange({
28290
28275
  labels: labels
28291
28276
  });
28292
- },
28293
- setUrl: function (url, width, height, silent) {
28277
+ }
28278
+ setUrl(url, width, height, silent) {
28294
28279
  // Because this calls into WidgetEditor._handleWidgetChange, which
28295
28280
  // checks for this widget's ref to serialize it.
28296
28281
  //
@@ -28308,11 +28293,12 @@ const ImageEditor = createReactClass({
28308
28293
  backgroundImage: image,
28309
28294
  box: box
28310
28295
  }, null, silent);
28311
- },
28296
+ }
28297
+
28312
28298
  // silently load the image when the component mounts
28313
28299
  // silently update url and sizes when the image loads
28314
28300
  // noisily load the image in response to the author changing it
28315
- onUrlChange: async function (url, silent) {
28301
+ async onUrlChange(url, silent) {
28316
28302
  // Check if we've been passed something that looks like a URL
28317
28303
  if (!url) {
28318
28304
  this.setUrl(url, 0, 0, silent);
@@ -28339,22 +28325,33 @@ const ImageEditor = createReactClass({
28339
28325
  backgroundImageError: `There was an error loading the image URL: ${JSON.stringify(error, null, 2)}`
28340
28326
  });
28341
28327
  }
28342
- },
28343
- onRangeChange: function (type, newRange) {
28328
+ }
28329
+ onRangeChange(type, newRange) {
28344
28330
  const range = this.props.range.slice();
28345
28331
  range[type] = newRange;
28346
28332
  this.props.onChange({
28347
28333
  range: range
28348
28334
  });
28349
- },
28335
+ }
28350
28336
  serialize() {
28351
28337
  return EditorJsonify.serialize.call(this);
28352
28338
  }
28353
- });
28339
+ }
28340
+ ImageEditor.displayName = "ImageEditor";
28341
+ ImageEditor.widgetName = "image";
28342
+ ImageEditor.defaultProps = {
28343
+ title: "",
28344
+ range: [defaultRange, defaultRange],
28345
+ box: [defaultBoxSize, defaultBoxSize],
28346
+ backgroundImage: defaultBackgroundImage$1,
28347
+ labels: [],
28348
+ alt: "",
28349
+ caption: ""
28350
+ };
28354
28351
 
28355
28352
  /* eslint-disable react/sort-comp */
28356
28353
  const {
28357
- InfoTip: InfoTip$f
28354
+ InfoTip: InfoTip$e
28358
28355
  } = components;
28359
28356
  const answerTypes = {
28360
28357
  number: {
@@ -28440,7 +28437,7 @@ class InputNumberEditor extends React.Component {
28440
28437
  value: "optional"
28441
28438
  }, "will be accepted"), /*#__PURE__*/React.createElement("option", {
28442
28439
  value: "enforced"
28443
- }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28440
+ }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28444
28441
  type: "checkbox",
28445
28442
  checked: this.props.inexact,
28446
28443
  onChange: e => {
@@ -28476,7 +28473,7 @@ class InputNumberEditor extends React.Component {
28476
28473
  });
28477
28474
  },
28478
28475
  "aria-label": "Answer type"
28479
- }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28476
+ }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28480
28477
  value: this.props.size,
28481
28478
  onChange: e => {
28482
28479
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"small" | "normal" | undefined'.
@@ -28488,7 +28485,7 @@ class InputNumberEditor extends React.Component {
28488
28485
  value: "normal"
28489
28486
  }, "Normal (80px)"), /*#__PURE__*/React.createElement("option", {
28490
28487
  value: "small"
28491
- }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28488
+ }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28492
28489
  type: "checkbox",
28493
28490
  checked: this.props.rightAlign,
28494
28491
  onChange: e => {
@@ -29669,7 +29666,7 @@ const SegmentCountSelector = ({
29669
29666
  }, `${n} segment${n > 1 ? "s" : ""}`)));
29670
29667
 
29671
29668
  const {
29672
- InfoTip: InfoTip$e
29669
+ InfoTip: InfoTip$d
29673
29670
  } = components;
29674
29671
  const {
29675
29672
  containerSizeClass,
@@ -29677,7 +29674,7 @@ const {
29677
29674
  } = SizingUtils;
29678
29675
  const DeprecationMixin = Util.DeprecationMixin;
29679
29676
  const InteractiveGraph = InteractiveGraphWidget.widget;
29680
- const defaultBackgroundImage$1 = {
29677
+ const defaultBackgroundImage = {
29681
29678
  url: null
29682
29679
  };
29683
29680
  const deprecatedProps = {
@@ -29843,7 +29840,7 @@ class InteractiveGraphEditor extends React.Component {
29843
29840
  value: "angles"
29844
29841
  }, "interior angles"), /*#__PURE__*/React.createElement("option", {
29845
29842
  value: "sides"
29846
- }, "side measures"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."), /*#__PURE__*/React.createElement("p", null, "The interior angle and side measure options guide the points to the nearest whole angle or side"), " ", "measure respectively.")), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(Typography.LabelSmall, {
29843
+ }, "side measures"))), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."), /*#__PURE__*/React.createElement("p", null, "The interior angle and side measure options guide the points to the nearest whole angle or side"), " ", "measure respectively.")), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(Typography.LabelSmall, {
29847
29844
  tag: "label"
29848
29845
  }, "Show angle measures:", " ", /*#__PURE__*/React.createElement("input", {
29849
29846
  type: "checkbox",
@@ -29855,7 +29852,7 @@ class InteractiveGraphEditor extends React.Component {
29855
29852
  })
29856
29853
  });
29857
29854
  }
29858
- })), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Displays the interior angle measures."))), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(Typography.LabelSmall, {
29855
+ })), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Displays the interior angle measures."))), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(Typography.LabelSmall, {
29859
29856
  tag: "label"
29860
29857
  }, "Show side measures:", " ", /*#__PURE__*/React.createElement("input", {
29861
29858
  type: "checkbox",
@@ -29867,7 +29864,7 @@ class InteractiveGraphEditor extends React.Component {
29867
29864
  })
29868
29865
  });
29869
29866
  }
29870
- })), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Displays the side lengths.")))), ((_this$props$correct9 = this.props.correct) == null ? void 0 : _this$props$correct9.type) === "segment" && /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Number of segments: "), /*#__PURE__*/React.createElement(SegmentCountSelector, {
29867
+ })), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Displays the side lengths.")))), ((_this$props$correct9 = this.props.correct) == null ? void 0 : _this$props$correct9.type) === "segment" && /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Number of segments: "), /*#__PURE__*/React.createElement(SegmentCountSelector, {
29871
29868
  numSegments: (_this$props$correct10 = this.props.correct) == null ? void 0 : _this$props$correct10.numSegments,
29872
29869
  onChange: sides => {
29873
29870
  this.props.onChange({
@@ -29887,7 +29884,7 @@ class InteractiveGraphEditor extends React.Component {
29887
29884
  borderStyle: "solid",
29888
29885
  borderWidth: 1
29889
29886
  }
29890
- }, equationString), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), /*#__PURE__*/React.createElement(GraphSettings, {
29887
+ }, equationString), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), /*#__PURE__*/React.createElement(GraphSettings, {
29891
29888
  box: getInteractiveBoxFromSizeClass(sizeClass),
29892
29889
  range: this.props.range,
29893
29890
  labels: this.props.labels,
@@ -29916,7 +29913,7 @@ class InteractiveGraphEditor extends React.Component {
29916
29913
  value: "approx"
29917
29914
  }, "be approximately congruent"), /*#__PURE__*/React.createElement("option", {
29918
29915
  value: "similar"
29919
- }, "be similar"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Match Exactly:"), " Match exactly in size, orientation, and location on the grid even if it is not shown in the background.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Congruent:"), " Be congruent in size and shape, but can be located anywhere on the grid.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Approximately Congruent:"), " Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid.", " ", /*#__PURE__*/React.createElement("em", null, "Use this with snapping to angle measure."))), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Similar:"), " Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."))))), this.props.correct.type === "angle" && /*#__PURE__*/React.createElement("div", {
29916
+ }, "be similar"))), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Match Exactly:"), " Match exactly in size, orientation, and location on the grid even if it is not shown in the background.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Congruent:"), " Be congruent in size and shape, but can be located anywhere on the grid.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Approximately Congruent:"), " Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid.", " ", /*#__PURE__*/React.createElement("em", null, "Use this with snapping to angle measure."))), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Similar:"), " Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."))))), this.props.correct.type === "angle" && /*#__PURE__*/React.createElement("div", {
29920
29917
  className: "type-settings"
29921
29918
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Student answer must", " ", /*#__PURE__*/React.createElement("select", {
29922
29919
  value: this.props.correct.match,
@@ -29925,7 +29922,7 @@ class InteractiveGraphEditor extends React.Component {
29925
29922
  value: "exact"
29926
29923
  }, "match exactly"), /*#__PURE__*/React.createElement("option", {
29927
29924
  value: "congruent"
29928
- }, "be congruent"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position.")))), graph);
29925
+ }, "be congruent"))), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position.")))), graph);
29929
29926
  }
29930
29927
  changeMatchType(e) {
29931
29928
  const correct = _.extend({}, this.props.correct, {
@@ -29963,7 +29960,7 @@ class InteractiveGraphEditor extends React.Component {
29963
29960
  InteractiveGraphEditor.widgetName = "interactive-graph";
29964
29961
  InteractiveGraphEditor.defaultProps = _extends({}, InteractiveGraph.defaultProps, {
29965
29962
  valid: true,
29966
- backgroundImage: defaultBackgroundImage$1,
29963
+ backgroundImage: defaultBackgroundImage,
29967
29964
  showTooltips: false,
29968
29965
  correct: {
29969
29966
  type: InteractiveGraph.defaultProps.graph.type,
@@ -31470,9 +31467,9 @@ const styles = StyleSheet.create({
31470
31467
  });
31471
31468
 
31472
31469
  const {
31473
- InfoTip: InfoTip$d,
31470
+ InfoTip: InfoTip$c,
31474
31471
  NumberInput: NumberInput$a,
31475
- PropCheckBox: PropCheckBox$8
31472
+ PropCheckBox: PropCheckBox$7
31476
31473
  } = components;
31477
31474
  const MAX_SIZE = 8;
31478
31475
 
@@ -31646,10 +31643,10 @@ class LightsPuzzleEditor extends React.Component {
31646
31643
  value: pattern,
31647
31644
  key: i
31648
31645
  }, pattern);
31649
- }))), /*#__PURE__*/React.createElement("div", null, "Grade incomplete puzzles as wrong:", " ", /*#__PURE__*/React.createElement(PropCheckBox$8, {
31646
+ }))), /*#__PURE__*/React.createElement("div", null, "Grade incomplete puzzles as wrong:", " ", /*#__PURE__*/React.createElement(PropCheckBox$7, {
31650
31647
  gradeIncompleteAsWrong: this.props.gradeIncompleteAsWrong,
31651
31648
  onChange: this.props.onChange
31652
- }), /*#__PURE__*/React.createElement(InfoTip$d, null, "By default, incomplete puzzles are graded as empty.")), /*#__PURE__*/React.createElement("div", null, "Starting configuration:"), /*#__PURE__*/React.createElement("div", {
31649
+ }), /*#__PURE__*/React.createElement(InfoTip$c, null, "By default, incomplete puzzles are graded as empty.")), /*#__PURE__*/React.createElement("div", null, "Starting configuration:"), /*#__PURE__*/React.createElement("div", {
31653
31650
  style: {
31654
31651
  overflowX: "auto"
31655
31652
  }
@@ -31674,8 +31671,8 @@ LightsPuzzleEditor.defaultProps = {
31674
31671
 
31675
31672
  /* eslint-disable react/forbid-prop-types, react/sort-comp */
31676
31673
  const {
31677
- InfoTip: InfoTip$c,
31678
- PropCheckBox: PropCheckBox$7,
31674
+ InfoTip: InfoTip$b,
31675
+ PropCheckBox: PropCheckBox$6,
31679
31676
  TextListEditor: TextListEditor$3
31680
31677
  } = components;
31681
31678
  class MatcherEditor extends React.Component {
@@ -31701,7 +31698,7 @@ class MatcherEditor extends React.Component {
31701
31698
  render() {
31702
31699
  return /*#__PURE__*/React.createElement("div", {
31703
31700
  className: "perseus-matcher-editor"
31704
- }, /*#__PURE__*/React.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "Enter the correct answers here. The preview on the right will show the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React.createElement("div", {
31701
+ }, /*#__PURE__*/React.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Enter the correct answers here. The preview on the right will show the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React.createElement("div", {
31705
31702
  className: "perseus-clearfix"
31706
31703
  }, /*#__PURE__*/React.createElement(TextListEditor$3, {
31707
31704
  options: this.props.left,
@@ -31719,7 +31716,7 @@ class MatcherEditor extends React.Component {
31719
31716
  }, cb);
31720
31717
  },
31721
31718
  layout: "vertical"
31722
- })), /*#__PURE__*/React.createElement("span", null, " ", "Labels:", " ", /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "These are entirely optional."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", {
31719
+ })), /*#__PURE__*/React.createElement("span", null, " ", "Labels:", " ", /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "These are entirely optional."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", {
31723
31720
  type: "text",
31724
31721
  defaultValue: this.props.labels[0]
31725
31722
  // eslint-disable-next-line react/jsx-no-bind
@@ -31731,15 +31728,15 @@ class MatcherEditor extends React.Component {
31731
31728
  // eslint-disable-next-line react/jsx-no-bind
31732
31729
  ,
31733
31730
  onChange: this.onLabelChange.bind(this, 1)
31734
- })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$7, {
31731
+ })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$6, {
31735
31732
  label: "Order of the matched pairs matters:",
31736
31733
  orderMatters: this.props.orderMatters,
31737
31734
  onChange: this.props.onChange
31738
- }), /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."), /*#__PURE__*/React.createElement("p", null, "If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$7, {
31735
+ }), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."), /*#__PURE__*/React.createElement("p", null, "If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$6, {
31739
31736
  label: "Padding:",
31740
31737
  padding: this.props.padding,
31741
31738
  onChange: this.props.onChange
31742
- }), /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "Padding is good for text, but not needed for images."))));
31739
+ }), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Padding is good for text, but not needed for images."))));
31743
31740
  }
31744
31741
  }
31745
31742
  MatcherEditor.propTypes = {
@@ -31882,9 +31879,9 @@ MatrixEditor.defaultProps = {
31882
31879
  };
31883
31880
 
31884
31881
  const {
31885
- InfoTip: InfoTip$b,
31882
+ InfoTip: InfoTip$a,
31886
31883
  NumberInput: NumberInput$9,
31887
- PropCheckBox: PropCheckBox$6,
31884
+ PropCheckBox: PropCheckBox$5,
31888
31885
  RangeInput: RangeInput$2
31889
31886
  } = components;
31890
31887
  const defaultImage = {
@@ -31939,7 +31936,7 @@ class MeasurerEditor extends React.Component {
31939
31936
  ref: "image-url",
31940
31937
  defaultValue: image.url,
31941
31938
  onChange: this._changeUrl
31942
- }), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), image.url && /*#__PURE__*/React.createElement("div", {
31939
+ }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), image.url && /*#__PURE__*/React.createElement("div", {
31943
31940
  className: "perseus-widget-row"
31944
31941
  }, /*#__PURE__*/React.createElement("label", {
31945
31942
  className: "perseus-widget-left-col"
@@ -31965,13 +31962,13 @@ class MeasurerEditor extends React.Component {
31965
31962
  className: "perseus-widget-row"
31966
31963
  }, /*#__PURE__*/React.createElement("div", {
31967
31964
  className: "perseus-widget-left-col"
31968
- }, /*#__PURE__*/React.createElement(PropCheckBox$6, {
31965
+ }, /*#__PURE__*/React.createElement(PropCheckBox$5, {
31969
31966
  label: "Show ruler",
31970
31967
  showRuler: this.props.showRuler,
31971
31968
  onChange: this.props.onChange
31972
31969
  })), /*#__PURE__*/React.createElement("div", {
31973
31970
  className: "perseus-widget-right-col"
31974
- }, /*#__PURE__*/React.createElement(PropCheckBox$6, {
31971
+ }, /*#__PURE__*/React.createElement(PropCheckBox$5, {
31975
31972
  label: "Show protractor",
31976
31973
  showProtractor: this.props.showProtractor,
31977
31974
  onChange: this.props.onChange
@@ -32084,9 +32081,9 @@ MoleculeWidgetEditor.widgetName = "molecule-renderer";
32084
32081
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
32085
32082
  const {
32086
32083
  ButtonGroup: ButtonGroup$1,
32087
- InfoTip: InfoTip$a,
32084
+ InfoTip: InfoTip$9,
32088
32085
  NumberInput: NumberInput$7,
32089
- PropCheckBox: PropCheckBox$5,
32086
+ PropCheckBox: PropCheckBox$4,
32090
32087
  RangeInput: RangeInput$1
32091
32088
  } = components;
32092
32089
  const bound = (x, gt, lt) => Math.min(Math.max(x, gt), lt);
@@ -32246,7 +32243,7 @@ class NumberLineEditor extends React.Component {
32246
32243
  placeholder: "answer",
32247
32244
  size: "normal",
32248
32245
  useArrowKeys: true
32249
- }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, <, >, \u2264, \u2265)."))), /*#__PURE__*/React.createElement("div", {
32246
+ }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, <, >, \u2264, \u2265)."))), /*#__PURE__*/React.createElement("div", {
32250
32247
  className: "perseus-widget-row"
32251
32248
  }, this.props.static ? /*#__PURE__*/React.createElement("label", null, "Range:") : /*#__PURE__*/React.createElement("label", null, "Position:", " ", /*#__PURE__*/React.createElement(NumberInput$7, {
32252
32249
  value: this.props.initialX,
@@ -32264,7 +32261,7 @@ class NumberLineEditor extends React.Component {
32264
32261
  onChange: this.onRangeChange,
32265
32262
  format: this.props.labelStyle,
32266
32263
  useArrowKeys: true
32267
- }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "This controls the initial position of the point along the number line and the", /*#__PURE__*/React.createElement("strong", null, "range"), ", the position of the endpoints of the number line. Setting the range constrains the position of the answer and the labels."), /*#__PURE__*/React.createElement("p", null, "In static mode, the initial position of the point is determined by Correct x instead of position."))), /*#__PURE__*/React.createElement("div", {
32264
+ }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "This controls the initial position of the point along the number line and the", /*#__PURE__*/React.createElement("strong", null, "range"), ", the position of the endpoints of the number line. Setting the range constrains the position of the answer and the labels."), /*#__PURE__*/React.createElement("p", null, "In static mode, the initial position of the point is determined by Correct x instead of position."))), /*#__PURE__*/React.createElement("div", {
32268
32265
  className: "perseus-widget-row"
32269
32266
  }, /*#__PURE__*/React.createElement("div", {
32270
32267
  className: "perseus-widget-left-col"
@@ -32286,30 +32283,30 @@ class NumberLineEditor extends React.Component {
32286
32283
  ,
32287
32284
  onChange: this.onLabelRangeChange.bind(this, 1),
32288
32285
  useArrowKeys: true
32289
- }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "This controls the position of the left / right labels. By default, the labels are set by the range ", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), " Ensure that the labels line up with the tick marks, or it may be confusing for users.")))), /*#__PURE__*/React.createElement("div", {
32286
+ }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "This controls the position of the left / right labels. By default, the labels are set by the range ", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), " Ensure that the labels line up with the tick marks, or it may be confusing for users.")))), /*#__PURE__*/React.createElement("div", {
32290
32287
  className: "perseus-widget-row"
32291
32288
  }, "Style:", " ", /*#__PURE__*/React.createElement(ButtonGroup$1, {
32292
32289
  allowEmpty: false,
32293
32290
  value: this.props.labelStyle,
32294
32291
  buttons: labelStyleEditorButtons,
32295
32292
  onChange: this.onLabelStyleChange
32296
- }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "This controls the styling of the labels for the two main labels as well as all the tick mark labels, if applicable. Your choices are decimal, improper fractions, mixed fractions, and non-reduced fractions."))), /*#__PURE__*/React.createElement("div", {
32293
+ }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "This controls the styling of the labels for the two main labels as well as all the tick mark labels, if applicable. Your choices are decimal, improper fractions, mixed fractions, and non-reduced fractions."))), /*#__PURE__*/React.createElement("div", {
32297
32294
  className: "perseus-widget-row"
32298
32295
  }, !this.props.static && /*#__PURE__*/React.createElement("div", {
32299
32296
  className: "perseus-widget-left-col"
32300
- }, /*#__PURE__*/React.createElement(PropCheckBox$5, {
32297
+ }, /*#__PURE__*/React.createElement(PropCheckBox$4, {
32301
32298
  label: "Show tick controller",
32302
32299
  isTickCtrl: this.props.isTickCtrl,
32303
32300
  onChange: this.props.onChange
32304
32301
  })), /*#__PURE__*/React.createElement("div", {
32305
32302
  className: "perseus-widget-right-col"
32306
- }, /*#__PURE__*/React.createElement(PropCheckBox$5, {
32303
+ }, /*#__PURE__*/React.createElement(PropCheckBox$4, {
32307
32304
  label: "Show label ticks",
32308
32305
  labelTicks: this.props.labelTicks,
32309
32306
  onChange: this.props.onChange
32310
32307
  }))), /*#__PURE__*/React.createElement("div", {
32311
32308
  className: "perseus-widget-row"
32312
- }, !this.props.static && /*#__PURE__*/React.createElement(PropCheckBox$5, {
32309
+ }, !this.props.static && /*#__PURE__*/React.createElement(PropCheckBox$4, {
32313
32310
  label: "Show tooltips",
32314
32311
  showTooltips: this.props.showTooltips,
32315
32312
  onChange: this.props.onChange
@@ -32324,7 +32321,7 @@ class NumberLineEditor extends React.Component {
32324
32321
  },
32325
32322
  placeholder: width / this.props.tickStep,
32326
32323
  useArrowKeys: true
32327
- })), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "This controls the number (and position) of the tick marks. The number of divisions is constrained to", " " + divisionRange[0] + EN_DASH + divisionRange[1], ".", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), " The user will be able to specify the number of divisions in a number input."))), !isTickCtrl && /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("label", null, "Num divisions:", " ", /*#__PURE__*/React.createElement(NumberInput$7, {
32324
+ })), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "This controls the number (and position) of the tick marks. The number of divisions is constrained to", " " + divisionRange[0] + EN_DASH + divisionRange[1], ".", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), " The user will be able to specify the number of divisions in a number input."))), !isTickCtrl && /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("label", null, "Num divisions:", " ", /*#__PURE__*/React.createElement(NumberInput$7, {
32328
32325
  value: this.props.numDivisions || null,
32329
32326
  format: "decimal",
32330
32327
  onChange: this.onNumDivisionsChange,
@@ -32342,7 +32339,7 @@ class NumberLineEditor extends React.Component {
32342
32339
  },
32343
32340
  placeholder: width / this.props.numDivisions,
32344
32341
  useArrowKeys: true
32345
- })), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "This controls the number (and position) of the tick marks; you can either set the number of divisions (2 divisions would split the entire range in two halves), or the tick step (the distance between ticks) and the other value will be updated accordingly.", " ", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), " There is no check to see if labels coordinate with the tick marks, which may be confusing for users if the blue labels and black ticks are off-step.")))), /*#__PURE__*/React.createElement("div", {
32342
+ })), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "This controls the number (and position) of the tick marks; you can either set the number of divisions (2 divisions would split the entire range in two halves), or the tick step (the distance between ticks) and the other value will be updated accordingly.", " ", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), " There is no check to see if labels coordinate with the tick marks, which may be confusing for users if the blue labels and black ticks are off-step.")))), /*#__PURE__*/React.createElement("div", {
32346
32343
  className: "perseus-widget-row"
32347
32344
  }, /*#__PURE__*/React.createElement("label", null, "Snap increments per tick:", " ", /*#__PURE__*/React.createElement(NumberInput$7, {
32348
32345
  value: snapDivisions,
@@ -32352,7 +32349,7 @@ class NumberLineEditor extends React.Component {
32352
32349
  ,
32353
32350
  onChange: this.onNumChange.bind(this, "snapDivisions"),
32354
32351
  useArrowKeys: true
32355
- })), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "This determines the number of different places the point will snap between two adjacent tick marks.", " ", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), "Ensure the required number of snap increments is provided to answer the question."))));
32352
+ })), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "This determines the number of different places the point will snap between two adjacent tick marks.", " ", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Note:"), "Ensure the required number of snap increments is provided to answer the question."))));
32356
32353
  }
32357
32354
  }
32358
32355
  NumberLineEditor.propTypes = {
@@ -32390,11 +32387,11 @@ NumberLineEditor.defaultProps = {
32390
32387
 
32391
32388
  const {
32392
32389
  ButtonGroup,
32393
- InfoTip: InfoTip$9,
32390
+ InfoTip: InfoTip$8,
32394
32391
  InlineIcon: InlineIcon$3,
32395
32392
  MultiButtonGroup,
32396
32393
  NumberInput: NumberInput$6,
32397
- PropCheckBox: PropCheckBox$4,
32394
+ PropCheckBox: PropCheckBox$3,
32398
32395
  TextInput: TextInput$3
32399
32396
  } = components;
32400
32397
  const {
@@ -32479,16 +32476,16 @@ const NumericInputEditor = createReactClass({
32479
32476
  content: "wrong"
32480
32477
  }],
32481
32478
  onChange: this.updateAnswer(i, "simplify")
32482
- }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"ungraded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and after)"), /*#__PURE__*/React.createElement("p", null, "Select \"accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"wrong\" ", /*#__PURE__*/React.createElement("em", null, "only"), " if we are specifically assessing the ability to simplify.")));
32479
+ }), /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"ungraded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and after)"), /*#__PURE__*/React.createElement("p", null, "Select \"accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"wrong\" ", /*#__PURE__*/React.createElement("em", null, "only"), " if we are specifically assessing the ability to simplify.")));
32483
32480
  const suggestedAnswerTypes = i => /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
32484
32481
  className: "perseus-widget-row"
32485
32482
  }, /*#__PURE__*/React.createElement("label", null, "Choose the suggested answer formats"), /*#__PURE__*/React.createElement(MultiButtonGroup, {
32486
32483
  buttons: answerFormButtons,
32487
32484
  values: answers[i]["answerForms"],
32488
32485
  onChange: this.updateAnswer(i, "answerForms")
32489
- }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "Formats will be autoselected for you based on the given answer; to show no suggested formats and accept all types, simply have a decimal/integer be the answer. Values with \u03C0 will have format \"pi\", and values that are fractions will have some subset (mixed will be \"mixed\" and \"proper\"; improper/proper will both be \"improper\" and \"proper\"). If you would like to specify that it is only a proper fraction (or only a mixed/improper fraction), deselect the other format. Except for specific cases, you should not need to change the autoselected formats."), /*#__PURE__*/React.createElement("p", null, "To restrict the answer to ", /*#__PURE__*/React.createElement("em", null, "only"), " an improper fraction (i.e. 7/4), select the improper fraction and toggle \"strict\" to true. This ", /*#__PURE__*/React.createElement("b", null, "will not"), " ", "accept 1.75 as an answer.", " "), /*#__PURE__*/React.createElement("p", null, "Unless you are testing that specific skill, please do not restrict the answer format."))), /*#__PURE__*/React.createElement("div", {
32486
+ }), /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Formats will be autoselected for you based on the given answer; to show no suggested formats and accept all types, simply have a decimal/integer be the answer. Values with \u03C0 will have format \"pi\", and values that are fractions will have some subset (mixed will be \"mixed\" and \"proper\"; improper/proper will both be \"improper\" and \"proper\"). If you would like to specify that it is only a proper fraction (or only a mixed/improper fraction), deselect the other format. Except for specific cases, you should not need to change the autoselected formats."), /*#__PURE__*/React.createElement("p", null, "To restrict the answer to ", /*#__PURE__*/React.createElement("em", null, "only"), " an improper fraction (i.e. 7/4), select the improper fraction and toggle \"strict\" to true. This ", /*#__PURE__*/React.createElement("b", null, "will not"), " ", "accept 1.75 as an answer.", " "), /*#__PURE__*/React.createElement("p", null, "Unless you are testing that specific skill, please do not restrict the answer format."))), /*#__PURE__*/React.createElement("div", {
32490
32487
  className: "perseus-widget-row"
32491
- }, /*#__PURE__*/React.createElement(PropCheckBox$4, {
32488
+ }, /*#__PURE__*/React.createElement(PropCheckBox$3, {
32492
32489
  label: "Strictly match only these formats",
32493
32490
  strict: answers[i]["strict"]
32494
32491
  // eslint-disable-next-line react/jsx-no-bind
@@ -32516,10 +32513,10 @@ const NumericInputEditor = createReactClass({
32516
32513
  content: "Small (40px)"
32517
32514
  }],
32518
32515
  onChange: this.change("size")
32519
- }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them.")));
32516
+ }), /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them.")));
32520
32517
  const rightAlign = /*#__PURE__*/React.createElement("div", {
32521
32518
  className: "perseus-widget-row"
32522
- }, /*#__PURE__*/React.createElement(PropCheckBox$4, {
32519
+ }, /*#__PURE__*/React.createElement(PropCheckBox$3, {
32523
32520
  label: "Right alignment",
32524
32521
  rightAlign: this.props.rightAlign,
32525
32522
  onChange: this.props.onChange
@@ -32529,14 +32526,14 @@ const NumericInputEditor = createReactClass({
32529
32526
  }, /*#__PURE__*/React.createElement("label", null, "Label text:", " ", /*#__PURE__*/React.createElement(TextInput$3, {
32530
32527
  value: this.props.labelText,
32531
32528
  onChange: this.change("labelText")
32532
- })), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "Text to describe this input. This will be shown to users using screenreaders.")));
32529
+ })), /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Text to describe this input. This will be shown to users using screenreaders.")));
32533
32530
  const coefficientCheck = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
32534
32531
  className: "perseus-widget-row"
32535
- }, /*#__PURE__*/React.createElement(PropCheckBox$4, {
32532
+ }, /*#__PURE__*/React.createElement(PropCheckBox$3, {
32536
32533
  label: "Coefficient",
32537
32534
  coefficient: this.props.coefficient,
32538
32535
  onChange: this.props.onChange
32539
- }), /*#__PURE__*/React.createElement(InfoTip$9, null, /*#__PURE__*/React.createElement("p", null, "A coefficient style number allows the student to use - for -1 and an empty string to mean 1."))));
32536
+ }), /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "A coefficient style number allows the student to use - for -1 and an empty string to mean 1."))));
32540
32537
  const addAnswerButton = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("a", {
32541
32538
  href: "javascript:void(0)",
32542
32539
  className: "simple-button orange",
@@ -32744,7 +32741,7 @@ const NumericInputEditor = createReactClass({
32744
32741
 
32745
32742
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
32746
32743
  const {
32747
- InfoTip: InfoTip$8,
32744
+ InfoTip: InfoTip$7,
32748
32745
  TextListEditor: TextListEditor$2
32749
32746
  } = components;
32750
32747
  const NORMAL = "normal",
@@ -32804,13 +32801,13 @@ class OrdererEditor extends React.Component {
32804
32801
  render() {
32805
32802
  return /*#__PURE__*/React.createElement("div", {
32806
32803
  className: "perseus-widget-orderer"
32807
- }, /*#__PURE__*/React.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Place the cards in the correct order. The same card can be used more than once in the answer but will only be displayed once at the top of a stack of identical cards."))), /*#__PURE__*/React.createElement(TextListEditor$2, {
32804
+ }, /*#__PURE__*/React.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "Place the cards in the correct order. The same card can be used more than once in the answer but will only be displayed once at the top of a stack of identical cards."))), /*#__PURE__*/React.createElement(TextListEditor$2, {
32808
32805
  options: _.pluck(this.props.correctOptions, "content")
32809
32806
  // eslint-disable-next-line react/jsx-no-bind
32810
32807
  ,
32811
32808
  onChange: this.onOptionsChange.bind(this, "correctOptions"),
32812
32809
  layout: this.props.layout
32813
- }), /*#__PURE__*/React.createElement("div", null, " ", "Other cards:", " ", /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Create cards that are not part of the answer."))), /*#__PURE__*/React.createElement(TextListEditor$2, {
32810
+ }), /*#__PURE__*/React.createElement("div", null, " ", "Other cards:", " ", /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "Create cards that are not part of the answer."))), /*#__PURE__*/React.createElement(TextListEditor$2, {
32814
32811
  options: _.pluck(this.props.otherOptions, "content")
32815
32812
  // eslint-disable-next-line react/jsx-no-bind
32816
32813
  ,
@@ -32825,7 +32822,7 @@ class OrdererEditor extends React.Component {
32825
32822
  value: HORIZONTAL$1
32826
32823
  }, "Horizontal"), /*#__PURE__*/React.createElement("option", {
32827
32824
  value: VERTICAL$1
32828
- }, "Vertical"))), /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text (e.g. proofs)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Height:", " ", /*#__PURE__*/React.createElement("select", {
32825
+ }, "Vertical"))), /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text (e.g. proofs)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Height:", " ", /*#__PURE__*/React.createElement("select", {
32829
32826
  value: this.props.height
32830
32827
  // @ts-expect-error - TS2322 - Type '(arg1: ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'ChangeEventHandler<HTMLSelectElement>'.
32831
32828
  ,
@@ -32834,7 +32831,7 @@ class OrdererEditor extends React.Component {
32834
32831
  value: NORMAL
32835
32832
  }, "Normal"), /*#__PURE__*/React.createElement("option", {
32836
32833
  value: AUTO
32837
- }, "Automatic"))), /*#__PURE__*/React.createElement(InfoTip$8, null, /*#__PURE__*/React.createElement("p", null, "Use \"Normal\" for text, \"Automatic\" for images."))));
32834
+ }, "Automatic"))), /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "Use \"Normal\" for text, \"Automatic\" for images."))));
32838
32835
  }
32839
32836
  }
32840
32837
  OrdererEditor.propTypes = {
@@ -32857,8 +32854,8 @@ OrdererEditor.defaultProps = {
32857
32854
  };
32858
32855
 
32859
32856
  const {
32860
- InfoTip: InfoTip$7,
32861
- PropCheckBox: PropCheckBox$3
32857
+ InfoTip: InfoTip$6,
32858
+ PropCheckBox: PropCheckBox$2
32862
32859
  } = components;
32863
32860
  class PassageEditor extends React.Component {
32864
32861
  constructor(..._args) {
@@ -32906,12 +32903,12 @@ class PassageEditor extends React.Component {
32906
32903
  className: "perseus-widget-passage-editor"
32907
32904
  }, /*#__PURE__*/React.createElement("div", {
32908
32905
  className: "perseus-widget-row"
32909
- }, /*#__PURE__*/React.createElement(PropCheckBox$3, {
32906
+ }, /*#__PURE__*/React.createElement(PropCheckBox$2, {
32910
32907
  label: "Show line numbers",
32911
32908
  labelAlignment: "right",
32912
32909
  showLineNumbers: this.props.showLineNumbers,
32913
32910
  onChange: this.props.onChange
32914
- })), /*#__PURE__*/React.createElement("div", null, "Passage title:", /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "An optional title that will appear directly above the passage in the same font style. (E.g. Passage 1)")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", {
32911
+ })), /*#__PURE__*/React.createElement("div", null, "Passage title:", /*#__PURE__*/React.createElement(InfoTip$6, null, /*#__PURE__*/React.createElement("p", null, "An optional title that will appear directly above the passage in the same font style. (E.g. Passage 1)")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", {
32915
32912
  type: "text",
32916
32913
  defaultValue: this.props.passageTitle,
32917
32914
  onChange: e => {
@@ -32920,7 +32917,7 @@ class PassageEditor extends React.Component {
32920
32917
  passageTitle: e.target.value
32921
32918
  });
32922
32919
  }
32923
- }))), /*#__PURE__*/React.createElement("div", null, "Passage Text:", passageEditor), /*#__PURE__*/React.createElement("div", null, "Footnotes:", /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "To add footnotes, add ^ characters where they belong in the passage. Then, add ^ in the footnotes area to reference the footnotes in the passage.")), footnotesEditor));
32920
+ }))), /*#__PURE__*/React.createElement("div", null, "Passage Text:", passageEditor), /*#__PURE__*/React.createElement("div", null, "Footnotes:", /*#__PURE__*/React.createElement(InfoTip$6, null, /*#__PURE__*/React.createElement("p", null, "To add footnotes, add ^ characters where they belong in the passage. Then, add ^ in the footnotes area to reference the footnotes in the passage.")), footnotesEditor));
32924
32921
  }
32925
32922
  }
32926
32923
  PassageEditor.propTypes = _extends({}, Changeable.propTypes, {
@@ -32938,7 +32935,7 @@ PassageEditor.defaultProps = {
32938
32935
  };
32939
32936
 
32940
32937
  const {
32941
- InfoTip: InfoTip$6,
32938
+ InfoTip: InfoTip$5,
32942
32939
  NumberInput: NumberInput$5,
32943
32940
  TextInput: TextInput$2
32944
32941
  } = components;
@@ -32968,7 +32965,7 @@ class PassageRefEditor extends React.Component {
32968
32965
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
32969
32966
  ,
32970
32967
  onChange: this.change("summaryText")
32971
- }), /*#__PURE__*/React.createElement(InfoTip$6, null, /*#__PURE__*/React.createElement("p", null, "Short summary of the referenced section. This will be included in parentheses and quotes automatically."), /*#__PURE__*/React.createElement("p", null, "Ex: The start ... the end")))));
32968
+ }), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "Short summary of the referenced section. This will be included in parentheses and quotes automatically."), /*#__PURE__*/React.createElement("p", null, "Ex: The start ... the end")))));
32972
32969
  }
32973
32970
  }
32974
32971
  PassageRefEditor.propTypes = _extends({}, Changeable.propTypes, {
@@ -33016,7 +33013,7 @@ PassageRefTargetEditor.defaultProps = {
33016
33013
  };
33017
33014
 
33018
33015
  const {
33019
- InfoTip: InfoTip$5,
33016
+ InfoTip: InfoTip$4,
33020
33017
  NumberInput: NumberInput$4,
33021
33018
  RangeInput,
33022
33019
  TextListEditor: TextListEditor$1
@@ -33251,7 +33248,7 @@ class PlotterEditor extends React.Component {
33251
33248
  useArrowKeys: true,
33252
33249
  value: this.state.tickStep,
33253
33250
  onChange: this.handleChangeTickStep
33254
- })), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "The difference between adjacent ticks."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Range:", " ", /*#__PURE__*/React.createElement(RangeInput, {
33251
+ })), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "The difference between adjacent ticks."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Range:", " ", /*#__PURE__*/React.createElement(RangeInput, {
33255
33252
  placeholder: [0, 10],
33256
33253
  useArrowKeys: true,
33257
33254
  value: [this.state.minX, this.state.maxX],
@@ -33262,11 +33259,11 @@ class PlotterEditor extends React.Component {
33262
33259
  useArrowKeys: true,
33263
33260
  value: this.props.labelInterval,
33264
33261
  onChange: this.changeLabelInterval
33265
- })), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "Which ticks to display the labels for. For instance, setting this to \"4\" will only show every 4th label (plus the last one)"))), this.props.type === "pic" && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Picture:", " ", /*#__PURE__*/React.createElement(BlurInput, {
33262
+ })), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "Which ticks to display the labels for. For instance, setting this to \"4\" will only show every 4th label (plus the last one)"))), this.props.type === "pic" && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Picture:", " ", /*#__PURE__*/React.createElement(BlurInput, {
33266
33263
  className: "pic-url",
33267
33264
  value: this.props.picUrl,
33268
33265
  onChange: this.changePicUrl
33269
- }), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "Use the default picture of Earth, or insert the URL for a different picture using the \"Add image\" function."))), this.state.pic && this.state.pic.width !== this.state.pic.height && /*#__PURE__*/React.createElement("p", {
33266
+ }), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "Use the default picture of Earth, or insert the URL for a different picture using the \"Add image\" function."))), this.state.pic && this.state.pic.width !== this.state.pic.height && /*#__PURE__*/React.createElement("p", {
33270
33267
  className: "warning"
33271
33268
  }, /*#__PURE__*/React.createElement("b", null, "Warning"), ": You are using a picture which is not square. This means the image will get distorted. You should probably crop it to be square.")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Categories:", " ", /*#__PURE__*/React.createElement(TextListEditor$1
33272
33269
  // eslint-disable-next-line react/no-string-refs
@@ -33290,14 +33287,14 @@ class PlotterEditor extends React.Component {
33290
33287
  type: "text",
33291
33288
  onChange: this.changeSnaps,
33292
33289
  defaultValue: this.props.snapsPerLine
33293
- })), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."))), /*#__PURE__*/React.createElement("div", null, "Editing values:", " ", editingStates.map(editing => /*#__PURE__*/React.createElement("label", {
33290
+ })), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."))), /*#__PURE__*/React.createElement("div", null, "Editing values:", " ", editingStates.map(editing => /*#__PURE__*/React.createElement("label", {
33294
33291
  key: editing
33295
33292
  }, /*#__PURE__*/React.createElement("input", {
33296
33293
  type: "radio",
33297
33294
  disabled: editing === CORRECT && this.props.static,
33298
33295
  checked: this.props.static ? editing === STARTING : this.state.editing === editing,
33299
33296
  onChange: e => this.changeEditing(editing)
33300
- }), editing)), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."), /*#__PURE__*/React.createElement("p", null, "In static mode, the starting values are rendered out to the displayed widget."))), /*#__PURE__*/React.createElement(Plotter, _extends({}, props, {
33297
+ }), editing)), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."), /*#__PURE__*/React.createElement("p", null, "In static mode, the starting values are rendered out to the displayed widget."))), /*#__PURE__*/React.createElement(Plotter, _extends({}, props, {
33301
33298
  starting: this.props[this.state.editing],
33302
33299
  onChange: this.handlePlotterChange
33303
33300
  })));
@@ -33326,7 +33323,7 @@ PlotterEditor.defaultProps = _extends({}, editorDefaults, {
33326
33323
 
33327
33324
  const {
33328
33325
  InlineIcon: InlineIcon$2,
33329
- PropCheckBox: PropCheckBox$2
33326
+ PropCheckBox: PropCheckBox$1
33330
33327
  } = components;
33331
33328
  const {
33332
33329
  iconPlus: iconPlus$1,
@@ -33517,21 +33514,21 @@ class RadioEditor extends React.Component {
33517
33514
  target: "_blank"
33518
33515
  }, "Multiple choice style guide"), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("div", {
33519
33516
  className: "perseus-widget-left-col"
33520
- }, /*#__PURE__*/React.createElement(PropCheckBox$2, {
33517
+ }, /*#__PURE__*/React.createElement(PropCheckBox$1, {
33521
33518
  label: "Multiple selections",
33522
33519
  labelAlignment: "right",
33523
33520
  multipleSelect: this.props.multipleSelect,
33524
33521
  onChange: this.onMultipleSelectChange
33525
33522
  })), /*#__PURE__*/React.createElement("div", {
33526
33523
  className: "perseus-widget-right-col"
33527
- }, /*#__PURE__*/React.createElement(PropCheckBox$2, {
33524
+ }, /*#__PURE__*/React.createElement(PropCheckBox$1, {
33528
33525
  label: "Randomize order",
33529
33526
  labelAlignment: "right",
33530
33527
  randomize: this.props.randomize,
33531
33528
  onChange: this.props.onChange
33532
33529
  })), this.props.multipleSelect && /*#__PURE__*/React.createElement("div", {
33533
33530
  className: "perseus-widget-left-col"
33534
- }, /*#__PURE__*/React.createElement(PropCheckBox$2, {
33531
+ }, /*#__PURE__*/React.createElement(PropCheckBox$1, {
33535
33532
  label: "Specify number correct",
33536
33533
  labelAlignment: "right",
33537
33534
  countChoices: this.props.countChoices,
@@ -33914,7 +33911,7 @@ SimpleMarkdownTesterEditor.defaultProps = {
33914
33911
  };
33915
33912
 
33916
33913
  const {
33917
- InfoTip: InfoTip$4,
33914
+ InfoTip: InfoTip$3,
33918
33915
  NumberInput: NumberInput$2
33919
33916
  } = components;
33920
33917
  const maxTrials = 5000;
@@ -33950,7 +33947,7 @@ class SimulatorEditor extends React.Component {
33950
33947
  className: "graph-settings-axis-label",
33951
33948
  value: this.props.proportionLabel,
33952
33949
  onChange: _.partial(this.handleTargetValueChange, "proportionLabel")
33953
- }), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "This text will be displayed next to the box in which the user enters the sample proportion for their simulation. For example, if your question is about surveying for approval ratings, you might want this to say \"Sample approval rating\"."))), /*#__PURE__*/React.createElement("div", null, i18n$1._("Proportion or Percentage"), ":", /*#__PURE__*/React.createElement("select", {
33950
+ }), /*#__PURE__*/React.createElement(InfoTip$3, null, /*#__PURE__*/React.createElement("p", null, "This text will be displayed next to the box in which the user enters the sample proportion for their simulation. For example, if your question is about surveying for approval ratings, you might want this to say \"Sample approval rating\"."))), /*#__PURE__*/React.createElement("div", null, i18n$1._("Proportion or Percentage"), ":", /*#__PURE__*/React.createElement("select", {
33954
33951
  className: "perseus-widget-dropdown",
33955
33952
  value: this.props.proportionOrPercentage,
33956
33953
  onChange: _.partial(this.handleTargetValueChange, "proportionOrPercentage")
@@ -33960,13 +33957,13 @@ class SimulatorEditor extends React.Component {
33960
33957
  }, "Proportion"), /*#__PURE__*/React.createElement("option", {
33961
33958
  key: "percentage",
33962
33959
  value: "percentage"
33963
- }, "Percentage")), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "Do you want the user to describe their simulation in terms of a proportion or a percentage?"))), /*#__PURE__*/React.createElement("div", null, i18n$1._("Number of trials"), ":", /*#__PURE__*/React.createElement(NumberInput$2, {
33960
+ }, "Percentage")), /*#__PURE__*/React.createElement(InfoTip$3, null, /*#__PURE__*/React.createElement("p", null, "Do you want the user to describe their simulation in terms of a proportion or a percentage?"))), /*#__PURE__*/React.createElement("div", null, i18n$1._("Number of trials"), ":", /*#__PURE__*/React.createElement(NumberInput$2, {
33964
33961
  value: this.props.numTrials,
33965
33962
  checkValidity: val => {
33966
33963
  return val >= 0 && val <= maxTrials;
33967
33964
  },
33968
33965
  onChange: this.change("numTrials")
33969
- }), /*#__PURE__*/React.createElement(InfoTip$4, null, /*#__PURE__*/React.createElement("p", null, "This controls the number of trials used in the simulation. For example, if you set this to 50, then the survey will be conducted 50 times. Warning: setting this too high (i.e., greater than 5000 or so) will freeze the page."))));
33966
+ }), /*#__PURE__*/React.createElement(InfoTip$3, null, /*#__PURE__*/React.createElement("p", null, "This controls the number of trials used in the simulation. For example, if you set this to 50, then the survey will be conducted 50 times. Warning: setting this too high (i.e., greater than 5000 or so) will freeze the page."))));
33970
33967
  }
33971
33968
  }
33972
33969
  SimulatorEditor.propTypes = _extends({}, Changeable.propTypes, {
@@ -33987,8 +33984,8 @@ SimulatorEditor.defaultProps = {
33987
33984
 
33988
33985
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
33989
33986
  const {
33990
- InfoTip: InfoTip$3,
33991
- PropCheckBox: PropCheckBox$1,
33987
+ InfoTip: InfoTip$2,
33988
+ PropCheckBox,
33992
33989
  TextListEditor
33993
33990
  } = components;
33994
33991
  const HORIZONTAL = "horizontal";
@@ -34007,7 +34004,7 @@ class SorterEditor extends React.Component {
34007
34004
  }
34008
34005
  render() {
34009
34006
  const editor = this;
34010
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React.createElement(InfoTip$3, null, /*#__PURE__*/React.createElement("p", null, "Enter the correct answer (in the correct order) here. The preview on the right will have the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React.createElement(TextListEditor, {
34007
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React.createElement(InfoTip$2, null, /*#__PURE__*/React.createElement("p", null, "Enter the correct answer (in the correct order) here. The preview on the right will have the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React.createElement(TextListEditor, {
34011
34008
  options: this.props.correct
34012
34009
  // eslint-disable-next-line react/jsx-no-bind
34013
34010
  ,
@@ -34026,11 +34023,11 @@ class SorterEditor extends React.Component {
34026
34023
  value: HORIZONTAL
34027
34024
  }, "Horizontal"), /*#__PURE__*/React.createElement("option", {
34028
34025
  value: VERTICAL
34029
- }, "Vertical"))), /*#__PURE__*/React.createElement(InfoTip$3, null, /*#__PURE__*/React.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text and larger images."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$1, {
34026
+ }, "Vertical"))), /*#__PURE__*/React.createElement(InfoTip$2, null, /*#__PURE__*/React.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text and larger images."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox, {
34030
34027
  label: "Padding:",
34031
34028
  padding: this.props.padding,
34032
34029
  onChange: this.props.onChange
34033
- }), /*#__PURE__*/React.createElement(InfoTip$3, null, /*#__PURE__*/React.createElement("p", null, "Padding is good for text, but not needed for images."))));
34030
+ }), /*#__PURE__*/React.createElement(InfoTip$2, null, /*#__PURE__*/React.createElement("p", null, "Padding is good for text, but not needed for images."))));
34034
34031
  }
34035
34032
  }
34036
34033
  SorterEditor.propTypes = {
@@ -34047,7 +34044,7 @@ SorterEditor.defaultProps = {
34047
34044
 
34048
34045
  /* eslint-disable react/sort-comp */
34049
34046
  const {
34050
- InfoTip: InfoTip$2,
34047
+ InfoTip: InfoTip$1,
34051
34048
  NumberInput: NumberInput$1
34052
34049
  } = components;
34053
34050
  const Table = TableWidget.widget;
@@ -34135,7 +34132,7 @@ class TableEditor extends React.Component {
34135
34132
  }
34136
34133
  },
34137
34134
  useArrowKeys: true
34138
- }))), /*#__PURE__*/React.createElement("div", null, " ", "Table of answers:", " ", /*#__PURE__*/React.createElement(InfoTip$2, null, /*#__PURE__*/React.createElement("p", null, "The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Table, tableProps)));
34135
+ }))), /*#__PURE__*/React.createElement("div", null, " ", "Table of answers:", " ", /*#__PURE__*/React.createElement(InfoTip$1, null, /*#__PURE__*/React.createElement("p", null, "The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Table, tableProps)));
34139
34136
  }
34140
34137
  }
34141
34138
  TableEditor.propTypes = {
@@ -34159,776 +34156,6 @@ TableEditor.defaultProps = function () {
34159
34156
  };
34160
34157
  }();
34161
34158
 
34162
- const {
34163
- Graph,
34164
- InfoTip: InfoTip$1,
34165
- PropCheckBox
34166
- } = components;
34167
- const Transformer = TransformerWidget.widget;
34168
- const {
34169
- deepEq,
34170
- getGridStep
34171
- } = Util;
34172
- function arraySum(array) {
34173
- return _.reduce(array, function (memo, arg) {
34174
- return memo + arg;
34175
- }, 0);
34176
- }
34177
- const defaultBackgroundImage = {
34178
- url: null
34179
- };
34180
-
34181
- /* Scales a distance from the default range of
34182
- * [-10, 10] to a given props.range pair
34183
- *
34184
- * Used for sizing various transformation tools
34185
- * (rotation handle, dilation circle)
34186
- */
34187
- function scaleToRange(dist, range) {
34188
- const spreadX = range[0][1] - range[0][0];
34189
- const spreadY = range[1][1] - range[1][0];
34190
- return dist * Math.max(spreadX, spreadY) / 20;
34191
- }
34192
- function orderInsensitiveCoordsEqual(coords1, coords2) {
34193
- coords1 = _.clone(coords1).sort(point.compare);
34194
- coords2 = _.clone(coords2).sort(point.compare);
34195
- return _.all(_.map(coords1, function (coord1, i) {
34196
- const coord2 = coords2[i];
34197
- return point.equal(coord1, coord2);
34198
- }));
34199
- }
34200
- const defaultGraphProps = function defaultGraphProps(setProps, boxSize) {
34201
- setProps = setProps || {};
34202
- const labels = setProps.labels || ["x", "y"];
34203
- const range = setProps.range || [[-10, 10], [-10, 10]];
34204
- const step = setProps.step || [1, 1];
34205
- const gridStep = setProps.gridStep || getGridStep(range, step, boxSize);
34206
- return {
34207
- box: [boxSize, boxSize],
34208
- labels: labels,
34209
- range: range,
34210
- step: step,
34211
- gridStep: gridStep,
34212
- valid: true,
34213
- backgroundImage: defaultBackgroundImage,
34214
- markings: "grid",
34215
- showProtractor: false
34216
- };
34217
- };
34218
- const defaultTransformerProps = {
34219
- apiOptions: ApiOptions.defaults,
34220
- gradeEmpty: false,
34221
- graphMode: "interactive",
34222
- listMode: "dynamic",
34223
- graph: {},
34224
- tools: {
34225
- translation: {
34226
- enabled: true,
34227
- required: false,
34228
- constraints: {}
34229
- },
34230
- rotation: {
34231
- enabled: true,
34232
- required: false,
34233
- constraints: {
34234
- fixed: false
34235
- },
34236
- coord: [1, 6]
34237
- },
34238
- reflection: {
34239
- enabled: true,
34240
- required: false,
34241
- constraints: {
34242
- fixed: false
34243
- },
34244
- coords: [[2, -4], [2, 2]]
34245
- },
34246
- dilation: {
34247
- enabled: true,
34248
- required: false,
34249
- constraints: {
34250
- fixed: false
34251
- },
34252
- coord: [6, 6]
34253
- }
34254
- },
34255
- drawSolutionShape: true,
34256
- starting: {
34257
- shape: {
34258
- type: "polygon-3",
34259
- coords: [[2, 2], [2, 6], [7, 2]]
34260
- },
34261
- transformations: []
34262
- },
34263
- correct: {
34264
- shape: {
34265
- type: "polygon-3",
34266
- coords: [[2, 2], [2, 6], [7, 2]]
34267
- },
34268
- transformations: []
34269
- }
34270
- };
34271
- class ToolSettings extends React.Component {
34272
- constructor(...args) {
34273
- super(...args);
34274
- this.changeConstraints = changed => {
34275
- const newConstraints = _.extend({}, this.props.constraints, changed);
34276
- this.props.onChange({
34277
- constraints: newConstraints
34278
- });
34279
- };
34280
- }
34281
- render() {
34282
- return /*#__PURE__*/React.createElement("div", null, this.props.name, ":", " ", /*#__PURE__*/React.createElement(PropCheckBox, {
34283
- label: "enabled:",
34284
- enabled: this.props.settings.enabled,
34285
- onChange: this.props.onChange
34286
- }), " ", this.props.settings.enabled && /*#__PURE__*/React.createElement(PropCheckBox, {
34287
- label: "required:",
34288
- required: this.props.settings.required,
34289
- onChange: this.props.onChange
34290
- }), this.props.settings.enabled && /*#__PURE__*/React.createElement(InfoTip$1, null, "'Required' will only grade the answer as correct if the student has used at least one such transformation."), " ", this.props.allowFixed && this.props.settings.enabled && /*#__PURE__*/React.createElement(PropCheckBox, {
34291
- label: "fixed:",
34292
- fixed: this.props.settings.constraints.fixed,
34293
- onChange: this.changeConstraints
34294
- }), this.props.allowFixed && this.props.settings.enabled && /*#__PURE__*/React.createElement(InfoTip$1, null, "Enable 'fixed' to prevent the student from repositioning the tool. The tool will appear in the position at which it is placed in the editor below."));
34295
- }
34296
- }
34297
- ToolSettings.defaultProps = {
34298
- allowFixed: true
34299
- };
34300
- class TransformationExplorerSettings extends React.Component {
34301
- constructor(...args) {
34302
- super(...args);
34303
- this.getMode = () => {
34304
- return this.props.graphMode + "," + this.props.listMode;
34305
- };
34306
- this.changeMode = e => {
34307
- const selected = e.target.value;
34308
- const modes = selected.split(",");
34309
- this.props.onChange({
34310
- graphMode: modes[0],
34311
- listMode: modes[1]
34312
- });
34313
- };
34314
- this.changeHandlerFor = toolName => {
34315
- return change => {
34316
- const newTools = _.clone(this.props.tools);
34317
- newTools[toolName] = _.extend({}, this.props.tools[toolName], change);
34318
- this.props.onChange({
34319
- tools: newTools
34320
- });
34321
- };
34322
- };
34323
- }
34324
- render() {
34325
- return /*#__PURE__*/React.createElement("div", {
34326
- className: "transformer-settings"
34327
- }, /*#__PURE__*/React.createElement("div", null, " ", "Mode:", " ", /*#__PURE__*/React.createElement("select", {
34328
- value: this.getMode(),
34329
- onChange: this.changeMode
34330
- }, /*#__PURE__*/React.createElement("option", {
34331
- value: "interactive,dynamic"
34332
- }, " ", "Exploration with text", " "), /*#__PURE__*/React.createElement("option", {
34333
- value: "interactive,static"
34334
- }, " ", "Exploration without text", " "), /*#__PURE__*/React.createElement("option", {
34335
- value: "dynamic,interactive"
34336
- }, " ", "Formal with movement", " "), /*#__PURE__*/React.createElement("option", {
34337
- value: "static,interactive"
34338
- }, " ", "Formal without movement", " ")), /*#__PURE__*/React.createElement(InfoTip$1, null, /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("b", null, "Exploration:"), " Students create transformations with tools on the graph.", " "), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("b", null, "Formal with movement:"), " Students specify transformations mathematically in the transformation list. Graph shows the results of these transformations.", " "), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("b", null, "Formal without movement:"), " Students specify transformations mathematically in the transformation list. Graph does not update.", " ")))), /*#__PURE__*/React.createElement(ToolSettings, {
34339
- name: "Translations",
34340
- settings: this.props.tools.translation,
34341
- allowFixed: false,
34342
- onChange: this.changeHandlerFor("translation")
34343
- }), /*#__PURE__*/React.createElement(ToolSettings, {
34344
- name: "Rotations",
34345
- settings: this.props.tools.rotation,
34346
- onChange: this.changeHandlerFor("rotation")
34347
- }), /*#__PURE__*/React.createElement(ToolSettings, {
34348
- name: "Reflections",
34349
- settings: this.props.tools.reflection,
34350
- onChange: this.changeHandlerFor("reflection")
34351
- }), /*#__PURE__*/React.createElement(ToolSettings, {
34352
- name: "Dilations",
34353
- settings: this.props.tools.dilation,
34354
- onChange: this.changeHandlerFor("dilation")
34355
- }), /*#__PURE__*/React.createElement(PropCheckBox, {
34356
- label: "Draw Solution:",
34357
- drawSolutionShape: this.props.drawSolutionShape,
34358
- onChange: this.props.onChange
34359
- }));
34360
- }
34361
- }
34362
- const ShapeTypes = {
34363
- getPointCountForType: function (type) {
34364
- const splitType = type.split("-");
34365
- if (splitType[0] === "polygon") {
34366
- return splitType[1] || 3;
34367
- }
34368
- if (splitType[0] === "line" || splitType[0] === "lineSegment") {
34369
- return 2;
34370
- }
34371
- if (splitType[0] === "angle") {
34372
- return 3;
34373
- }
34374
- if (splitType[0] === "circle") {
34375
- return 2;
34376
- }
34377
- if (splitType[0] === "point") {
34378
- return 1;
34379
- }
34380
- },
34381
- addMovableShape: function (graphie, options) {
34382
- if (options.editable && options.translatable) {
34383
- throw new PerseusError("It doesn't make sense to have a movable shape " + "where you can stretch the points and translate them " + "simultaneously.", Errors.InvalidInput, {
34384
- metadata: {
34385
- options
34386
- }
34387
- });
34388
- }
34389
- const points = _.map(options.shape.coords, function (coord) {
34390
- let isMoving = false;
34391
- let previousCoord = coord;
34392
- const onMove = function onMove(x, y) {
34393
- if (!isMoving) {
34394
- previousCoord = currentPoint.coord;
34395
- isMoving = true;
34396
- }
34397
- let moveVector = vector.subtract([x, y], currentPoint.coord);
34398
-
34399
- // Translate from (x, y) semantics to (dX, dY) semantics
34400
- // This is more useful for translations on multiple points,
34401
- // where we care about how the points moved, not where any
34402
- // individual point ended up
34403
- if (options.onMove) {
34404
- moveVector = options.onMove(moveVector[0], moveVector[1]);
34405
- }
34406
-
34407
- // Perform a translation on all points in this shape when
34408
- // any point moves
34409
- if (options.translatable) {
34410
- _.each(points, function (point) {
34411
- // The point itself will be updated by the
34412
- // movablePoint class, so only translate the other
34413
- // points
34414
- if (point !== currentPoint) {
34415
- point.setCoord(vector.add(point.coord, moveVector));
34416
- }
34417
- });
34418
- }
34419
-
34420
- // Update our shape and our currentPoint
34421
- // Without this, some shapes (circles, angles) appear
34422
- // "bouncy" as they are updated with currentPoint at the
34423
- // current mouse coordinate (oldCoord), rather than newCoord
34424
- const oldCoord = currentPoint.coord;
34425
- const newCoord = vector.add(currentPoint.coord, moveVector);
34426
- // Temporarily change our coordinate so that
34427
- // shape.update() sees the new coordinate
34428
- currentPoint.coord = newCoord;
34429
- shape.update();
34430
- // ...But don't break onMove, which assumes it
34431
- // is the only thing changing our coord
34432
- currentPoint.coord = oldCoord;
34433
- return newCoord;
34434
- };
34435
- const onMoveEnd = function onMoveEnd() {
34436
- // onMove isn't guaranteed to be called before onMoveEnd, so
34437
- // we have to take into account that we may not have moved and
34438
- // set previousCoord.
34439
- if (options.onMoveEnd && isMoving) {
34440
- isMoving = false;
34441
- // We don't use the supplied x and y parameters here
34442
- // because MovablePoint's onMoveEnd semantics suck.
34443
- // It returns the mouseX, mouseY without processing them
34444
- // through onMove, leaving us with weird fractional moves
34445
- const change = vector.subtract(currentPoint.coord, previousCoord);
34446
- options.onMoveEnd(change[0], change[1]);
34447
- }
34448
- shape.update();
34449
- };
34450
- const currentPoint = graphie.addMovablePoint({
34451
- coord: coord,
34452
- normalStyle: options.normalPointStyle,
34453
- highlightStyle: options.highlightPointStyle,
34454
- constraints: {
34455
- fixed: !options.translatable && !options.editable
34456
- },
34457
- visible: options.showPoints,
34458
- snapX: options.snap && options.snap[0] || 0,
34459
- snapY: options.snap && options.snap[1] || 0,
34460
- bounded: false,
34461
- // Don't bound it when placing it on the graph
34462
- onMove: onMove,
34463
- onMoveEnd: onMoveEnd
34464
- });
34465
-
34466
- // Bound it when moving
34467
- // We can't set this earlier, because doing so would mean any
34468
- // points outside of the graph would be moved into a moved into
34469
- // a position that doesn't preserve the shape
34470
- currentPoint.bounded = true;
34471
- return currentPoint;
34472
- });
34473
- const shape = ShapeTypes.addShape(graphie, options, points);
34474
- const removeShapeWithoutPoints = shape.remove;
34475
- shape.remove = function () {
34476
- removeShapeWithoutPoints.apply(shape);
34477
- _.invoke(points, "remove");
34478
- };
34479
- return shape;
34480
- },
34481
- addShape: function (graphie, options, points) {
34482
- points = points || options.shape.coords;
34483
- const types = ShapeTypes._typesOf(options.shape);
34484
- const typeOptions = options.shape.options || ShapeTypes.defaultOptions(types);
34485
- const shapes = ShapeTypes._mapTypes(types, points, function (type, points, i) {
34486
- const shapeOptions = _.extend({}, options, typeOptions[i]);
34487
- return ShapeTypes._addType(graphie, type, points, shapeOptions);
34488
- });
34489
- const updateFuncs = _.filter(_.pluck(shapes, "update"), _.identity);
34490
- const update = function update() {
34491
- _.invoke(updateFuncs, "call");
34492
- };
34493
- const removeFuncs = _.filter(_.pluck(shapes, "remove"), _.identity);
34494
- const remove = function remove() {
34495
- _.invoke(removeFuncs, "call");
34496
- };
34497
- const getOptions = function getOptions() {
34498
- return _.map(shapes, function (shape) {
34499
- if (shape.getOptions) {
34500
- return shape.getOptions();
34501
- }
34502
- return {};
34503
- });
34504
- };
34505
- const toJSON = function toJSON() {
34506
- const coords = _.map(points, function (pt) {
34507
- if (_.isArray(pt)) {
34508
- return pt;
34509
- }
34510
- return pt.coord;
34511
- });
34512
- return {
34513
- type: types,
34514
- coords: coords,
34515
- options: getOptions()
34516
- };
34517
- };
34518
- return {
34519
- type: types,
34520
- points: points,
34521
- update: update,
34522
- remove: remove,
34523
- toJSON: toJSON,
34524
- getOptions: getOptions
34525
- };
34526
- },
34527
- equal: function (shape1, shape2) {
34528
- const types1 = ShapeTypes._typesOf(shape1);
34529
- const types2 = ShapeTypes._typesOf(shape2);
34530
- if (types1.length !== types2.length) {
34531
- return false;
34532
- }
34533
- const shapes1 = ShapeTypes._mapTypes(types1, shape1.coords, ShapeTypes._combine);
34534
- const shapes2 = ShapeTypes._mapTypes(types2, shape2.coords, ShapeTypes._combine);
34535
- return _.all(_.map(shapes1, function (partialShape1, i) {
34536
- const partialShape2 = shapes2[i];
34537
- if (partialShape1.type !== partialShape2.type) {
34538
- return false;
34539
- }
34540
- return ShapeTypes._forType(partialShape1.type).equal(partialShape1.coords, partialShape2.coords);
34541
- }));
34542
- },
34543
- _typesOf: function (shape) {
34544
- let types = shape.type;
34545
- if (!_.isArray(types)) {
34546
- types = [types];
34547
- }
34548
- return _.map(types, function (type) {
34549
- if (type === "polygon") {
34550
- return "polygon-3";
34551
- }
34552
- return type;
34553
- });
34554
- },
34555
- defaultOptions: function (types) {
34556
- return _.map(types, function (type) {
34557
- const typeDefaultOptions = ShapeTypes._forType(type).defaultOptions;
34558
- return _.extend({}, typeDefaultOptions);
34559
- });
34560
- },
34561
- _forType: function (type) {
34562
- const baseType = type.split("-")[0];
34563
- return ShapeTypes[baseType];
34564
- },
34565
- _mapTypes: function (types, points, func, context) {
34566
- return _.map(types, function (type, i) {
34567
- const pointCount = ShapeTypes.getPointCountForType(type);
34568
- const currentPoints = _.first(points, pointCount);
34569
- points = _.rest(points, pointCount);
34570
- return func.call(context, type, currentPoints, i);
34571
- });
34572
- },
34573
- _addType: function (graphie, type, points, options) {
34574
- const lineCoords = _.isArray(points[0]) ? {
34575
- coordA: points[0],
34576
- coordZ: points[1]
34577
- } : {
34578
- pointA: points[0],
34579
- pointZ: points[1]
34580
- };
34581
- type = type.split("-")[0];
34582
- if (type === "polygon") {
34583
- const polygon = graphie.addMovablePolygon(_.extend({}, options, {
34584
- fixed: !options.editable,
34585
- snapX: options.snap && options.snap[0] || 0,
34586
- snapY: options.snap && options.snap[1] || 0,
34587
- points: points,
34588
- constrainToGraph: false
34589
- }));
34590
- return {
34591
- update: polygon.transform.bind(polygon),
34592
- remove: polygon.remove.bind(polygon)
34593
- };
34594
- }
34595
- if (type === "line" || type === "lineSegment") {
34596
- const line = graphie.addMovableLineSegment(_.extend({}, options, lineCoords, {
34597
- movePointsWithLine: true,
34598
- fixed: true,
34599
- constraints: {
34600
- fixed: true
34601
- },
34602
- extendLine: type === "line"
34603
- }));
34604
-
34605
- // TODO(jack): Hide points on uneditable lines when translation
34606
- // is a vector.
34607
- // We can't just remove the points yet, because they are the
34608
- // translation handle for the line.
34609
- return {
34610
- update: line.transform.bind(line, true),
34611
- remove: line.remove.bind(line)
34612
- };
34613
- }
34614
- if (type === "angle") {
34615
- // If this angle is editable, we want to be able to make angles
34616
- // both larger and smaller than 180 degrees.
34617
- // If this angle is not editable, it should always maintain
34618
- // it's angle measure, even if it is reflected (causing the
34619
- // clockwise-ness of the points to change)
34620
- const shouldChangeReflexivity = options.editable ? null : false;
34621
- const angle = graphie.addMovableAngle({
34622
- angleLabel: "$deg0",
34623
- fixed: true,
34624
- points: points,
34625
- normalStyle: options.normalStyle,
34626
- reflex: options.reflex
34627
- });
34628
-
34629
- // Hide non-vertex points on uneditable angles
34630
- if (!_.isArray(points[0]) && !options.editable) {
34631
- points[0].remove();
34632
- points[2].remove();
34633
- }
34634
- return {
34635
- update: angle.update.bind(angle, shouldChangeReflexivity),
34636
- remove: angle.remove.bind(angle),
34637
- getOptions: function () {
34638
- return {
34639
- reflex: angle.isReflex()
34640
- };
34641
- }
34642
- };
34643
- }
34644
- if (type === "circle") {
34645
- let perimeter = {
34646
- // temporary object for the first removal
34647
- remove: _.identity
34648
- };
34649
- const redrawPerim = function redrawPerim() {
34650
- const coord0 = points[0].coord || points[0];
34651
- const coord1 = points[1].coord || points[1];
34652
- const radius = point.distanceToPoint(coord0, coord1);
34653
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
34654
- perimeter.remove();
34655
- perimeter = graphie.circle(coord0, radius, _.extend({
34656
- stroke: KhanColors.DYNAMIC,
34657
- "stroke-width": 2
34658
- }, options.normalStyle));
34659
- };
34660
- redrawPerim();
34661
- if (points[1].remove && !options.editable) {
34662
- points[1].remove();
34663
- }
34664
- return {
34665
- update: redrawPerim,
34666
- remove: function () {
34667
- // Not _.bind because the remove function changes
34668
- // when the perimeter is redrawn
34669
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
34670
- perimeter.remove();
34671
- }
34672
- };
34673
- }
34674
- if (type === "point") {
34675
- // do nothing
34676
- return {
34677
- update: null,
34678
- remove: null
34679
- };
34680
- }
34681
- throw new PerseusError("Invalid shape type " + type, Errors.InvalidInput);
34682
- },
34683
- _combine: function (type, coords) {
34684
- return {
34685
- type: type,
34686
- coords: coords
34687
- };
34688
- },
34689
- polygon: {
34690
- equal: orderInsensitiveCoordsEqual
34691
- },
34692
- line: {
34693
- equal: line.equal
34694
- },
34695
- lineSegment: {
34696
- equal: orderInsensitiveCoordsEqual
34697
- },
34698
- angle: {
34699
- equal: function (points1, points2) {
34700
- if (!point.equal(points1[1], points2[1])) {
34701
- return false;
34702
- }
34703
- const line1_0 = [points1[1], points1[0]];
34704
- const line1_2 = [points1[1], points1[2]];
34705
- const line2_0 = [points2[1], points2[0]];
34706
- const line2_2 = [points2[1], points2[2]];
34707
- const equalUnflipped =
34708
- // @ts-expect-error - TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'. | TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'.
34709
- ray.equal(line1_0, line2_0) && ray.equal(line1_2, line2_2);
34710
- const equalFlipped =
34711
- // @ts-expect-error - TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'. | TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'.
34712
- ray.equal(line1_0, line2_2) && ray.equal(line1_2, line2_0);
34713
- return equalUnflipped || equalFlipped;
34714
- },
34715
- defaultOptions: {
34716
- reflex: false
34717
- }
34718
- },
34719
- circle: {
34720
- equal: function (points1, points2) {
34721
- const radius1 = point.distanceToPoint(points1[0], points1[1]);
34722
- const radius2 = point.distanceToPoint(points2[0], points2[1]);
34723
- return point.equal(points1[0], points2[0]) && number.equal(radius1, radius2);
34724
- }
34725
- },
34726
- point: {
34727
- equal: point.equal
34728
- }
34729
- };
34730
- class TransformationsShapeEditor extends React.Component {
34731
- constructor(...args) {
34732
- super(...args);
34733
- /* Return the option string for a given type */
34734
- this.getTypeString = type => {
34735
- if (_.isArray(type)) {
34736
- return _.map(type, this.getTypeString).join(",");
34737
- }
34738
- if (type === "polygon") {
34739
- return "polygon-" + this.props.shape.coords.length;
34740
- }
34741
- return type;
34742
- };
34743
- /* Change the type on the window event e
34744
- *
34745
- * e.target.value is the new type string
34746
- */
34747
- this.changeType = e => {
34748
- const types = String(e.target.value).split(",");
34749
- const pointCount = arraySum(_.map(types, ShapeTypes.getPointCountForType));
34750
-
34751
- // eslint-disable-next-line react/no-string-refs
34752
- // @ts-expect-error - TS2339 - Property 'props' does not exist on type 'ReactInstance'.
34753
- const radius = scaleToRange(4, this.refs.graph.props.range);
34754
- const offset = (1 / 2 - 1 / pointCount) * 180;
34755
- const coords = _.times(pointCount, function (i) {
34756
- return point.rotateDeg([radius, 0], 360 * i / pointCount + offset);
34757
- });
34758
- this.props.onChange({
34759
- shape: {
34760
- type: types,
34761
- coords: coords,
34762
- options: ShapeTypes.defaultOptions(types)
34763
- }
34764
- });
34765
- };
34766
- this.updateCoords = () => {
34767
- this.props.onChange({
34768
- // @ts-expect-error - TS2339 - Property 'shape' does not exist on type 'TransformationsShapeEditor'.
34769
- shape: this.shape.toJSON()
34770
- });
34771
- };
34772
- this.setupGraphie = graphie => {
34773
- // @ts-expect-error - TS2339 - Property 'shape' does not exist on type 'TransformationsShapeEditor'.
34774
- this.shape = ShapeTypes.addMovableShape(graphie, {
34775
- editable: true,
34776
- snap: graphie.snap,
34777
- shape: this.props.shape,
34778
- onMoveEnd: this.updateCoords
34779
- });
34780
- };
34781
- }
34782
- render() {
34783
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Graph
34784
- // eslint-disable-next-line react/no-string-refs
34785
- , {
34786
- ref: "graph",
34787
- box: this.props.graph.box,
34788
- range: this.props.graph.range,
34789
- labels: this.props.graph.labels,
34790
- step: this.props.graph.step,
34791
- gridStep: this.props.graph.gridStep,
34792
- markings: this.props.graph.markings,
34793
- backgroundImage: this.props.graph.backgroundImage,
34794
- onGraphieUpdated: this.setupGraphie
34795
- }), /*#__PURE__*/React.createElement("select", {
34796
- key: "type-select",
34797
- value: this.getTypeString(this.props.shape.type),
34798
- onChange: this.changeType
34799
- }, /*#__PURE__*/React.createElement("option", {
34800
- value: "polygon-3"
34801
- }, "Triangle"), /*#__PURE__*/React.createElement("option", {
34802
- value: "polygon-4"
34803
- }, "Quadrilateral"), /*#__PURE__*/React.createElement("option", {
34804
- value: "polygon-5"
34805
- }, "Pentagon"), /*#__PURE__*/React.createElement("option", {
34806
- value: "polygon-6"
34807
- }, "Hexagon"), /*#__PURE__*/React.createElement("option", {
34808
- value: "line"
34809
- }, "Line"), /*#__PURE__*/React.createElement("option", {
34810
- value: "line,line"
34811
- }, "2 lines"), /*#__PURE__*/React.createElement("option", {
34812
- value: "lineSegment"
34813
- }, "Line segment"), /*#__PURE__*/React.createElement("option", {
34814
- value: "lineSegment,lineSegment"
34815
- }, " ", "2 line segments", " "), /*#__PURE__*/React.createElement("option", {
34816
- value: "angle"
34817
- }, "Angle"), /*#__PURE__*/React.createElement("option", {
34818
- value: "circle"
34819
- }, "Circle")));
34820
- }
34821
- componentDidMount() {
34822
- // eslint-disable-next-line react/no-string-refs
34823
- // @ts-expect-error - TS2339 - Property 'graphie' does not exist on type 'ReactInstance'.
34824
- this.setupGraphie(this.refs.graph.graphie());
34825
- }
34826
- componentDidUpdate(prevProps) {
34827
- if (!deepEq(prevProps.shape, this.props.shape)) {
34828
- // eslint-disable-next-line react/no-string-refs
34829
- // @ts-expect-error - TS2339 - Property 'reset' does not exist on type 'ReactInstance'.
34830
- this.refs.graph.reset();
34831
- }
34832
- }
34833
- }
34834
- class TransformerEditor extends React.Component {
34835
- constructor(...args) {
34836
- super(...args);
34837
- // propagate a props change on our graph settings to
34838
- // this.props.graph
34839
- this.changeGraph = (graphChanges, callback) => {
34840
- const newGraph = _.extend({}, this.props.graph, graphChanges);
34841
- this.props.onChange({
34842
- graph: newGraph
34843
- }, callback);
34844
- };
34845
- // propagate a props change on our starting graph to
34846
- // this.props.starting
34847
- this.changeStarting = startingChanges => {
34848
- const newStarting = _.extend({}, this.props.starting, startingChanges);
34849
- this.props.onChange({
34850
- starting: newStarting
34851
- });
34852
- };
34853
- // propagate a transformations change onto correct.transformations
34854
- this.changeTransformer = (changes, callback) => {
34855
- if (changes.transformations) {
34856
- changes.correct = _extends({}, this.props.correct, {
34857
- transformations: changes.transformations
34858
- });
34859
- delete changes.transformations;
34860
- }
34861
- this.props.onChange(changes, callback);
34862
- };
34863
- this.serialize = () => {
34864
- // eslint-disable-next-line react/no-string-refs
34865
- // @ts-expect-error - TS2339 - Property 'getEditorJSON' does not exist on type 'ReactInstance'.
34866
- const json = this.refs.explorer.getEditorJSON();
34867
- json.correct = json.answer;
34868
- delete json.answer;
34869
- return json;
34870
- };
34871
- }
34872
- render() {
34873
- // Fill in any missing value in this.props.graph
34874
- // this can happen because the graph json doesn't include
34875
- // box, for example
34876
- const graph = _.extend(defaultGraphProps(this.props.graph, 340), this.props.graph);
34877
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox, {
34878
- label: "Grade empty answers as wrong:",
34879
- gradeEmpty: this.props.gradeEmpty,
34880
- onChange: this.props.onChange
34881
- }), /*#__PURE__*/React.createElement(InfoTip$1, null, /*#__PURE__*/React.createElement("p", null, "We generally do not grade empty answers. This usually works well, but sometimes can result in giving away part of an answer in a multi-part question."), /*#__PURE__*/React.createElement("p", null, "If this is a multi-part question (there is another widget), you probably want to enable this option. Otherwise, you should leave it disabled."), /*#__PURE__*/React.createElement("p", null, "Confused? Talk to Elizabeth."))), /*#__PURE__*/React.createElement("div", null, "Graph settings:"), /*#__PURE__*/React.createElement(GraphSettings, {
34882
- box: graph.box,
34883
- labels: graph.labels,
34884
- range: graph.range,
34885
- step: graph.step,
34886
- gridStep: graph.gridStep,
34887
- valid: graph.valid,
34888
- backgroundImage: graph.backgroundImage,
34889
- markings: graph.markings,
34890
- showProtractor: graph.showProtractor,
34891
- onChange: this.changeGraph
34892
- }), /*#__PURE__*/React.createElement("div", null, "Transformation settings:"), /*#__PURE__*/React.createElement(TransformationExplorerSettings
34893
- // eslint-disable-next-line react/no-string-refs
34894
- , {
34895
- ref: "transformationSettings",
34896
- graphMode: this.props.graphMode,
34897
- listMode: this.props.listMode,
34898
- tools: this.props.tools,
34899
- drawSolutionShape: this.props.drawSolutionShape,
34900
- onChange: this.props.onChange
34901
- }), /*#__PURE__*/React.createElement("div", null, "Starting location:"), /*#__PURE__*/React.createElement(TransformationsShapeEditor
34902
- // eslint-disable-next-line react/no-string-refs
34903
- , {
34904
- ref: "shapeEditor",
34905
- graph: graph,
34906
- shape: this.props.starting.shape,
34907
- onChange: this.changeStarting,
34908
- setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
34909
- }), /*#__PURE__*/React.createElement("div", null, "Solution transformations:"), /*#__PURE__*/React.createElement(Transformer
34910
- // eslint-disable-next-line react/no-string-refs
34911
- , {
34912
- ref: "explorer",
34913
- graph: graph,
34914
- graphMode: this.props.graphMode,
34915
- listMode: this.props.listMode,
34916
- gradeEmpty: this.props.gradeEmpty,
34917
- tools: this.props.tools,
34918
- drawSolutionShape: this.props.drawSolutionShape,
34919
- starting: this.props.starting,
34920
- correct: this.props.starting,
34921
- transformations: this.props.correct.transformations,
34922
- onChange: this.changeTransformer,
34923
- trackInteraction: () => {}
34924
- }));
34925
- }
34926
- }
34927
- // TODO (jack): These should be refactored into a nice object at the top
34928
- // so that we don't have all this duplication
34929
- TransformerEditor.defaultProps = defaultTransformerProps;
34930
- TransformerEditor.widgetName = "transformer";
34931
-
34932
34159
  const {
34933
34160
  InlineIcon,
34934
34161
  NumberInput
@@ -35210,7 +34437,7 @@ VideoEditor.defaultProps = {
35210
34437
  location: ""
35211
34438
  };
35212
34439
 
35213
- var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExampleGraphieWidgetEditor, ExampleWidgetEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, GradedGroupSetEditor, GrapherEditor, GroupEditor, IframeEditor, ImageEditor, InputNumberEditor, InteractionEditor, InteractiveGraphEditor, LabelImageEditor, LightsPuzzleEditor, MatcherEditor, MatrixEditor, MeasurerEditor, MoleculeWidgetEditor, NumberLineEditor, NumericInputEditor, OrdererEditor, PassageEditor, PassageRefEditor, PassageRefTargetEditor, PlotterEditor, ReactionDiagramWidgetEditor, SequenceEditor, SimpleMarkdownTesterEditor, SimulatorEditor, SorterEditor, TableEditor, TransformerEditor, UnitInputEditor, VideoEditor, RadioEditor, DeprecatedStandinEditor];
34440
+ var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExampleGraphieWidgetEditor, ExampleWidgetEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, GradedGroupSetEditor, GrapherEditor, GroupEditor, IframeEditor, ImageEditor, InputNumberEditor, InteractionEditor, InteractiveGraphEditor, LabelImageEditor, LightsPuzzleEditor, MatcherEditor, MatrixEditor, MeasurerEditor, MoleculeWidgetEditor, NumberLineEditor, NumericInputEditor, OrdererEditor, PassageEditor, PassageRefEditor, PassageRefTargetEditor, PlotterEditor, ReactionDiagramWidgetEditor, SequenceEditor, SimpleMarkdownTesterEditor, SimulatorEditor, SorterEditor, TableEditor, UnitInputEditor, VideoEditor, RadioEditor, DeprecatedStandinEditor];
35214
34441
 
35215
34442
  class TextInput extends React.Component {
35216
34443
  constructor(...args) {
@@ -35426,6 +34653,8 @@ var AllWidgets = [...widgets, ...testingWidgets];
35426
34653
 
35427
34654
  Widgets.registerEditors(AllEditors);
35428
34655
  Widgets.registerWidgets(AllWidgets);
34656
+ Widgets.replaceEditor("transformer", "deprecated-standin");
34657
+ Widgets.replaceWidget("transformer", "deprecatd-standin");
35429
34658
 
35430
34659
  export { AllEditors, AllWidgets, ArticleDiff, ArticleEditor, DeviceFramer, Editor, EditorPage, IframeContentRenderer, ItemDiff, MultiRendererEditor, StatefulArticleEditor, StatefulEditorPage, StructuredItemDiff, ViewportResizer, i18n, libVersion };
35431
34660
  //# sourceMappingURL=index.js.map