@khanacademy/perseus 19.7.3 → 19.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -84,7 +84,7 @@ export type { ServerItemRenderer as ServerItemRendererComponent } from "./server
84
84
  export type { Alignment, APIOptions, APIOptionsWithDefaults, ChangeHandler, DeviceType, DomInsertCheckFn, EditorMode, FocusPath, Hint, ImageDict, ImageUploader, JiptLabelStore, JiptRenderer, PerseusDependencies, PerseusScore, Version, VideoData, VideoKind, WidgetDict, WidgetExports, } from "./types";
85
85
  export type { ParsedValue } from "./util";
86
86
  export type { PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
87
- PerseusImageBackground, PerseusInputNumberWidgetOptions, PerseusInteractiveGraphWidgetOptions, PerseusItem, PerseusPlotterWidgetOptions, PerseusPythonProgramWidgetOptions, PerseusRadioWidgetOptions, PerseusRenderer, PerseusWidget, } from "./perseus-types";
87
+ PerseusImageBackground, PerseusInputNumberWidgetOptions, PerseusInteractiveGraphWidgetOptions, PerseusItem, PerseusPlotterWidgetOptions, PerseusPythonProgramWidgetOptions, PerseusRadioWidgetOptions, PerseusExampleWidgetOptions, PerseusExampleGraphieWidgetOptions, PerseusSimpleMarkdownTesterWidgetOptions, PerseusRenderer, PerseusWidget, PerseusWidgetsMap, } from "./perseus-types";
88
88
  export type { Coord } from "./interactive2/types";
89
89
  export type { MarkerType } from "./widgets/label-image/types";
90
90
  /**
package/dist/index.js CHANGED
@@ -18971,7 +18971,7 @@ const getRendererPropsForWidgetInfo = (widgetInfo, problemNum) => {
18971
18971
  // It shouldn't matter what we return here, but for consistency
18972
18972
  // we return the untransformed options, as if the widget did
18973
18973
  // not have a transform defined.
18974
- return widgetInfo.options;
18974
+ return widgetInfo;
18975
18975
  }
18976
18976
  let transform;
18977
18977
  if (widgetInfo.static) {
@@ -19614,11 +19614,8 @@ class Renderer extends React__namespace.Component {
19614
19614
 
19615
19615
  // The widget needs access to its "rubric" at all times when in review
19616
19616
  // mode (which is really just part of its widget info).
19617
- let reviewModeRubric = null;
19618
19617
  const widgetInfo = this.state.widgetInfo[id];
19619
- if (this.props.reviewMode && widgetInfo) {
19620
- reviewModeRubric = widgetInfo.options;
19621
- }
19618
+ const reviewModeRubric = this.props.reviewMode && widgetInfo ? widgetInfo.options : null;
19622
19619
  if (!this._interactionTrackers) {
19623
19620
  this._interactionTrackers = {};
19624
19621
  }
@@ -28326,38 +28323,174 @@ class Graph extends React__namespace.Component {
28326
28323
  }
28327
28324
  }
28328
28325
 
28329
- const useInteractivePoint = (coords, snaps, range) => mafs.useMovablePoint(coords, {
28330
- constrain: coord => constrain(coord, snaps, range),
28331
- color: Color__default["default"].blue
28332
- });
28326
+ const MOVE_CONTROL_POINT = "move-control-point";
28327
+ function moveControlPoint(objectIndex, pointIndex, destination) {
28328
+ return {
28329
+ type: MOVE_CONTROL_POINT,
28330
+ objectIndex,
28331
+ pointIndex,
28332
+ destination
28333
+ };
28334
+ }
28335
+ const MOVE_SEGMENT = "move-segment";
28336
+ function moveSegment(segmentIndex, delta) {
28337
+ return {
28338
+ type: MOVE_SEGMENT,
28339
+ segmentIndex,
28340
+ delta
28341
+ };
28342
+ }
28333
28343
 
28334
- /**
28335
- * We do not want to call `onGraphChange` until the user
28336
- * has interacted with the graph. See the test,
28337
- * "should reject no interaction"
28338
- */
28339
- const useEffectAfterFirstRender = (fn, deps) => {
28340
- const firstRender = React.useRef(true);
28341
- React.useEffect(() => {
28342
- if (firstRender.current) {
28343
- firstRender.current = false;
28344
- return;
28345
- }
28346
- fn();
28347
- // eslint-disable-next-line react-hooks/exhaustive-deps
28348
- }, [fn, ...deps]);
28344
+ const SegmentGraph = props => {
28345
+ const {
28346
+ dispatch
28347
+ } = props;
28348
+ const {
28349
+ segments,
28350
+ snapStep,
28351
+ range
28352
+ } = props.graphState;
28353
+ return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, segments.map((segment, i) => /*#__PURE__*/React__namespace.createElement(SegmentView, {
28354
+ key: i,
28355
+ segment: segment,
28356
+ snaps: snapStep,
28357
+ range: range,
28358
+ onMoveSegment: delta => {
28359
+ dispatch(moveSegment(i, delta));
28360
+ },
28361
+ onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(i, endpointIndex, destination)),
28362
+ "data-testid": "segment" + i
28363
+ })));
28349
28364
  };
28350
- const snap = (val, step) => {
28351
- const inverse = 1 / step;
28352
- return Math.round(val * inverse) / inverse;
28365
+ const SegmentView = props => {
28366
+ const [pt1, pt2] = props.segment;
28367
+ const midpoint = mafs.vec.midpoint(pt1, pt2);
28368
+ return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Line.Segment, {
28369
+ point1: pt1,
28370
+ point2: pt2
28371
+ }), /*#__PURE__*/React__namespace.createElement(mafs.MovablePoint, {
28372
+ point: midpoint,
28373
+ color: Color__default["default"].blue,
28374
+ onMove: newPoint => {
28375
+ props.onMoveSegment(mafs.vec.sub(newPoint, midpoint));
28376
+ }
28377
+ }), /*#__PURE__*/React__namespace.createElement(mafs.MovablePoint, {
28378
+ point: pt1,
28379
+ color: Color__default["default"].blue,
28380
+ onMove: newPoint => {
28381
+ props.onMovePoint(0, newPoint);
28382
+ }
28383
+ }), /*#__PURE__*/React__namespace.createElement(mafs.MovablePoint, {
28384
+ point: pt2,
28385
+ color: Color__default["default"].blue,
28386
+ onMove: newPoint => {
28387
+ props.onMovePoint(1, newPoint);
28388
+ }
28389
+ }));
28353
28390
  };
28354
- const clamp = (n, min, max) => Math.max(min, Math.min(max, n));
28355
- const constrain = (coord, snapStep, range) => {
28356
- const [x, y] = coord;
28357
- const [xSnap, ySnap] = snapStep;
28358
- const [[xMin, xMax], [yMin, yMax]] = range;
28359
- return [clamp(snap(x, xSnap), xMin, xMax), clamp(snap(y, ySnap), yMin, yMax)];
28391
+
28392
+ const renderLineLabel = (n, _ref) => {
28393
+ let [min, max] = _ref;
28394
+ return n !== -1 && n !== min && n !== max;
28360
28395
  };
28396
+ const axisOptions = (props, index) => ({
28397
+ axis: props.markings === "graph",
28398
+ lines: props.step[index],
28399
+ subdivisions: props.step[index] / props.gridStep[index],
28400
+ labels: n => renderLineLabel(n, props.range[index]) ? n : ""
28401
+ });
28402
+ const Grid = props => props.markings === "none" ? null : /*#__PURE__*/React__namespace.createElement(mafs.Coordinates.Cartesian, {
28403
+ xAxis: axisOptions(props, 0),
28404
+ yAxis: axisOptions(props, 1)
28405
+ });
28406
+
28407
+ function interactiveGraphReducer(state, action) {
28408
+ switch (action.type) {
28409
+ case "move-control-point":
28410
+ {
28411
+ const newSegments = updateAtIndex(state.segments, action.objectIndex, segment => setAtIndex(segment, action.pointIndex, snap(state, bound$1(state, action.destination))));
28412
+ if (!validSegments(newSegments)) {
28413
+ return state;
28414
+ }
28415
+ return {
28416
+ ...state,
28417
+ hasBeenInteractedWith: true,
28418
+ segments: newSegments
28419
+ };
28420
+ }
28421
+ case "move-segment":
28422
+ {
28423
+ const oldSegment = state.segments[action.segmentIndex];
28424
+ const maxMoves = oldSegment.map(point => maxMove(state, point));
28425
+ const minMoves = oldSegment.map(point => minMove(state, point));
28426
+ const maxXMove = Math.min(...maxMoves.map(move => move[0]));
28427
+ const maxYMove = Math.min(...maxMoves.map(move => move[1]));
28428
+ const minXMove = Math.max(...minMoves.map(move => move[0]));
28429
+ const minYMove = Math.max(...minMoves.map(move => move[1]));
28430
+ const dx = clamp(action.delta[0], minXMove, maxXMove);
28431
+ const dy = clamp(action.delta[1], minYMove, maxYMove);
28432
+ const newSegment = oldSegment.map(point => snap(state, kmath.vector.add(point, [dx, dy])));
28433
+ const newSegments = setAtIndex(state.segments, action.segmentIndex, newSegment);
28434
+ return {
28435
+ ...state,
28436
+ hasBeenInteractedWith: true,
28437
+ segments: newSegments
28438
+ };
28439
+ }
28440
+ default:
28441
+ throw new wonderStuffCore.UnreachableCaseError(action);
28442
+ }
28443
+ }
28444
+ function snap(state, point) {
28445
+ const [requestedX, requestedY] = point;
28446
+ const [snapX, snapY] = state.snapStep;
28447
+ return [Math.round(requestedX / snapX) * snapX, Math.round(requestedY / snapY) * snapY];
28448
+ }
28449
+
28450
+ // Returns the closest point to the given `point` that is within the graph
28451
+ // bounds given in `state`.
28452
+ function bound$1(state, point) {
28453
+ const [requestedX, requestedY] = point;
28454
+ const [snapX, snapY] = state.snapStep;
28455
+ const [[minX, maxX], [minY, maxY]] = state.range;
28456
+ return [clamp(requestedX, minX + snapX, maxX - snapX), clamp(requestedY, minY + snapY, maxY - snapY)];
28457
+ }
28458
+
28459
+ // Returns the vector from the given point to the top-right corner of the graph
28460
+ function maxMove(state, point) {
28461
+ const topRight = bound$1(state, [Infinity, Infinity]);
28462
+ return mafs.vec.sub(topRight, point);
28463
+ }
28464
+
28465
+ // Returns the vector from the given point to the bottom-left corner of the
28466
+ // graph
28467
+ function minMove(state, point) {
28468
+ const bottomLeft = bound$1(state, [-Infinity, -Infinity]);
28469
+ return mafs.vec.sub(bottomLeft, point);
28470
+ }
28471
+ function clamp(value, min, max) {
28472
+ if (value < min) {
28473
+ return min;
28474
+ }
28475
+ if (value > max) {
28476
+ return max;
28477
+ }
28478
+ return value;
28479
+ }
28480
+ function validSegments(segments) {
28481
+ return segments.every(_ref => {
28482
+ let [start, end] = _ref;
28483
+ return !kmath.vector.equal(start, end);
28484
+ });
28485
+ }
28486
+ function updateAtIndex(array, index, update) {
28487
+ return setAtIndex(array, index, update(array[index]));
28488
+ }
28489
+ function setAtIndex(array, index, newValue) {
28490
+ const copy = [...array];
28491
+ copy[index] = newValue;
28492
+ return copy;
28493
+ }
28361
28494
 
28362
28495
  // same as pointsFromNormalized in interactive-graph.tsx
28363
28496
  const normalizePoints = (range, step, coordsList, noSnap) => coordsList.map(coords =>
@@ -28379,11 +28512,30 @@ const normalizeCoords = (coordsList, ranges) => coordsList.map(coords => coords.
28379
28512
  return (coord + ranges[i][1]) / extent;
28380
28513
  }));
28381
28514
 
28382
- const getSegmentCoords = props => {
28383
- const coords = props.graph.coords;
28384
- if (coords) {
28385
- return coords;
28515
+ function initializeGraphState(params) {
28516
+ const {
28517
+ graph,
28518
+ step,
28519
+ snapStep,
28520
+ range
28521
+ } = params;
28522
+ switch (graph.type) {
28523
+ case "segment":
28524
+ return {
28525
+ type: "segment",
28526
+ hasBeenInteractedWith: false,
28527
+ range,
28528
+ snapStep,
28529
+ segments: getDefaultSegments({
28530
+ graph,
28531
+ step,
28532
+ range
28533
+ })
28534
+ };
28386
28535
  }
28536
+ throw new Error("Mafs not yet implemented for graph type: " + graph.type);
28537
+ }
28538
+ const getDefaultSegments = props => {
28387
28539
  const ys = n => {
28388
28540
  switch (n) {
28389
28541
  case 2:
@@ -28401,60 +28553,12 @@ const getSegmentCoords = props => {
28401
28553
  }
28402
28554
  };
28403
28555
  return ys(props.graph.numSegments).map(y => {
28404
- let segment = [[-5, y], [5, y]];
28405
- segment = normalizeCoords(segment, props.range);
28406
- segment = normalizePoints(props.range, props.step, segment);
28407
- return segment;
28556
+ let endpoints = [[-5, y], [5, y]];
28557
+ endpoints = normalizeCoords(endpoints, props.range);
28558
+ endpoints = normalizePoints(props.range, props.step, endpoints);
28559
+ return endpoints;
28408
28560
  });
28409
28561
  };
28410
- const updateSegmentsArray = (segments, index, segment) => segments.map((seg, i) => index === i ? segment : seg);
28411
- const SegmentGraph = props => {
28412
- const segments = getSegmentCoords(props);
28413
- const handleChange = (i, segment) => props.onGraphChange(current => ({
28414
- ...current,
28415
- coords: current.coords ? updateSegmentsArray(current.coords, i, segment) : updateSegmentsArray(segments, i, segment)
28416
- }));
28417
- return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, segments.map((segment, i) => /*#__PURE__*/React__namespace.createElement(Segment, {
28418
- key: i,
28419
- i: i,
28420
- segment: segment,
28421
- snaps: props.snapStep,
28422
- range: props.range,
28423
- onChange: handleChange,
28424
- "data-testid": "segment" + i
28425
- })));
28426
- };
28427
- const Segment = props => {
28428
- const [start, end] = props.segment;
28429
- const {
28430
- point: pt1,
28431
- element: el1
28432
- } = useInteractivePoint(start, props.snaps, props.range);
28433
- const {
28434
- point: pt2,
28435
- element: el2
28436
- } = useInteractivePoint(end, props.snaps, props.range);
28437
- useEffectAfterFirstRender(() => props.onChange(props.i, [pt1, pt2]), [pt1, pt2]);
28438
- return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Line.Segment, {
28439
- point1: pt1,
28440
- point2: pt2
28441
- }), el1, el2);
28442
- };
28443
-
28444
- const renderLineLabel = (n, _ref) => {
28445
- let [min, max] = _ref;
28446
- return n !== -1 && n !== min && n !== max;
28447
- };
28448
- const axisOptions = (props, index) => ({
28449
- axis: props.markings === "graph",
28450
- lines: props.step[index],
28451
- subdivisions: props.step[index] / props.gridStep[index],
28452
- labels: n => renderLineLabel(n, props.range[index]) ? n : ""
28453
- });
28454
- const Grid = props => props.markings === "none" ? null : /*#__PURE__*/React__namespace.createElement(mafs.Coordinates.Cartesian, {
28455
- xAxis: axisOptions(props, 0),
28456
- yAxis: axisOptions(props, 1)
28457
- });
28458
28562
 
28459
28563
  // Displays a stylized open eye: lint warnings are visible
28460
28564
  const VisibleIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
@@ -29144,29 +29248,38 @@ const getLegacyGrid = (box, backgroundImage) => {
29144
29248
 
29145
29249
  const renderGraph = props => {
29146
29250
  const {
29147
- graph,
29148
- ...rest
29251
+ state,
29252
+ dispatch
29149
29253
  } = props;
29150
- switch (graph.type) {
29254
+ switch (state.type) {
29151
29255
  case "segment":
29152
- return /*#__PURE__*/React__namespace.createElement(SegmentGraph, _extends({}, rest, {
29153
- graph: graph,
29154
- onGraphChange: props.onGraphChange
29155
- }));
29256
+ return /*#__PURE__*/React__namespace.createElement(SegmentGraph, {
29257
+ graphState: state,
29258
+ dispatch: dispatch
29259
+ });
29156
29260
  }
29261
+ throw new Error("Mafs is not yet implemented for graph type: " + state.type);
29157
29262
  };
29263
+ function getGradableGraph(state, initialGraph) {
29264
+ if (!state.hasBeenInteractedWith) {
29265
+ return initialGraph;
29266
+ }
29267
+ switch (initialGraph.type) {
29268
+ case "segment":
29269
+ return {
29270
+ ...initialGraph,
29271
+ coords: state.segments
29272
+ };
29273
+ }
29274
+ throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
29275
+ }
29158
29276
  const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
29159
- // Storing the gradable state in a ref so that it can be updated without
29160
- // causing a re-render.
29161
- const graphRef = React__namespace.useRef(props.graph);
29162
- const handleGraphUpdate = callback => {
29163
- graphRef.current = callback(graphRef.current);
29164
- };
29165
- React__namespace.useImperativeHandle(ref, () => ({
29166
- getUserInput: () => graphRef.current
29167
- }));
29168
29277
  const [width, height] = props.box;
29169
29278
  const legacyGrid = getLegacyGrid([width, height], props.backgroundImage);
29279
+ const [state, dispatch] = React__namespace.useReducer(interactiveGraphReducer, props, initializeGraphState);
29280
+ React__namespace.useImperativeHandle(ref, () => ({
29281
+ getUserInput: () => getGradableGraph(state, props.graph)
29282
+ }));
29170
29283
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29171
29284
  style: {
29172
29285
  width: props.backgroundImage?.width ?? width,
@@ -29190,8 +29303,8 @@ const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
29190
29303
  width: width,
29191
29304
  height: height
29192
29305
  }, !legacyGrid && /*#__PURE__*/React__namespace.createElement(Grid, props), renderGraph({
29193
- ...props,
29194
- onGraphChange: handleGraphUpdate
29306
+ state,
29307
+ dispatch
29195
29308
  }))));
29196
29309
  });
29197
29310
 
@@ -32969,21 +33082,21 @@ class Tile extends React__namespace.Component {
32969
33082
  });
32970
33083
  }
32971
33084
  _flip = () => {
32972
- this.props.onChange(!this.props.value);
33085
+ // On change requires a value, but we don't actually have access
33086
+ // to the coordinates here, so we just pass the inverse value as a workaround.
33087
+ this.props.onChange({
33088
+ value: !this.props.value
33089
+ });
32973
33090
  };
32974
33091
  }
32975
33092
 
32976
33093
  // A grid of glowy cells
32977
33094
  class TileGrid extends React__namespace.Component {
32978
- static propTypes = {
32979
- cells: PropTypes__default["default"].arrayOf(PropTypes__default["default"].arrayOf(PropTypes__default["default"].bool)).isRequired,
32980
- size: PropTypes__default["default"].number.isRequired
32981
- };
32982
33095
  render() {
32983
33096
  return /*#__PURE__*/React__namespace.createElement("div", {
32984
33097
  style: TABLE_STYLE,
32985
33098
  className: "no-select"
32986
- }, ___default["default"].map(this.props.cells, (row, y) => {
33099
+ }, this.props.cells && ___default["default"].map(this.props.cells, (row, y) => {
32987
33100
  return /*#__PURE__*/React__namespace.createElement("div", {
32988
33101
  key: y,
32989
33102
  style: ROW_STYLE
@@ -32994,7 +33107,12 @@ class TileGrid extends React__namespace.Component {
32994
33107
  }, /*#__PURE__*/React__namespace.createElement(Tile, {
32995
33108
  value: cell,
32996
33109
  size: this.props.size,
32997
- onChange: ___default["default"].partial(this.props.onChange, y, x)
33110
+ onChange: ___default["default"].partial(this.props.onChange, {
33111
+ value: {
33112
+ y,
33113
+ x
33114
+ }
33115
+ })
32998
33116
  }));
32999
33117
  }));
33000
33118
  }));
@@ -33025,13 +33143,6 @@ const flipTilesPattern = (oldCells, tileY, tileX, pattern) => {
33025
33143
  class LightsPuzzle extends React__namespace.Component {
33026
33144
  // @ts-expect-error - TS2564 - Property '_patternIndex' has no initializer and is not definitely assigned in the constructor.
33027
33145
 
33028
- static propTypes = {
33029
- ...propTypes,
33030
- cells: PropTypes__default["default"].arrayOf(PropTypes__default["default"].arrayOf(PropTypes__default["default"].bool)),
33031
- startCells: PropTypes__default["default"].arrayOf(PropTypes__default["default"].arrayOf(PropTypes__default["default"].bool)),
33032
- flipPattern: PropTypes__default["default"].string.isRequired,
33033
- moveCount: PropTypes__default["default"].number.isRequired
33034
- };
33035
33146
  static defaultProps = {
33036
33147
  cells: [[false, false, false], [false, false, false], [false, false, false]],
33037
33148
  startCells: [[false, false, false], [false, false, false], [false, false, false]],
@@ -33077,7 +33188,7 @@ class LightsPuzzle extends React__namespace.Component {
33077
33188
  };
33078
33189
  })();
33079
33190
  _width = () => {
33080
- if (this.props.cells.length !== 0) {
33191
+ if (this.props.cells && this.props.cells.length !== 0) {
33081
33192
  return this.props.cells[0].length;
33082
33193
  }
33083
33194
  return 0; // default to 0
@@ -33092,21 +33203,31 @@ class LightsPuzzle extends React__namespace.Component {
33092
33203
  }
33093
33204
  }
33094
33205
  _initNextPatterns = () => {
33095
- this._currPattern = PATTERNS[this.props.flipPattern](0);
33096
- this._nextPattern = PATTERNS[this.props.flipPattern](1);
33206
+ if (this.props.flipPattern) {
33207
+ this._currPattern = PATTERNS[this.props.flipPattern](0);
33208
+ this._nextPattern = PATTERNS[this.props.flipPattern](1);
33209
+ }
33097
33210
  this._patternIndex = 2;
33098
33211
  };
33099
33212
  _shiftPatterns = () => {
33100
- this._currPattern = this._nextPattern;
33101
- this._nextPattern = PATTERNS[this.props.flipPattern](this._patternIndex);
33102
- this._patternIndex++;
33213
+ if (this.props.flipPattern) {
33214
+ this._currPattern = this._nextPattern;
33215
+ this._nextPattern = PATTERNS[this.props.flipPattern](this._patternIndex);
33216
+ this._patternIndex++;
33217
+ }
33103
33218
  };
33104
- _flipTile = (tileY, tileX) => {
33105
- const newCells = flipTilesPattern(this.props.cells, tileY, tileX, this._currPattern);
33219
+ _flipTile = _ref => {
33220
+ let {
33221
+ value: {
33222
+ y,
33223
+ x
33224
+ }
33225
+ } = _ref;
33226
+ const newCells = flipTilesPattern(this.props.cells, y, x, this._currPattern);
33106
33227
  this._shiftPatterns();
33107
33228
  this.change({
33108
33229
  cells: newCells,
33109
- moveCount: this.props.moveCount + 1
33230
+ moveCount: (this.props.moveCount || 0) + 1
33110
33231
  });
33111
33232
  };
33112
33233
  _reset = () => {
@@ -35516,11 +35637,6 @@ const parse$1 = SmilesParser.parse;
35516
35637
  const ParseError = SmilesParser.ParseError;
35517
35638
  const borderSize = 30;
35518
35639
  class Molecule extends React__namespace.Component {
35519
- static propTypes = {
35520
- id: PropTypes__default["default"].string.isRequired,
35521
- rotationAngle: PropTypes__default["default"].number,
35522
- smiles: PropTypes__default["default"].string
35523
- };
35524
35640
  state = {
35525
35641
  parsedSmiles: null,
35526
35642
  error: null
@@ -35593,7 +35709,7 @@ class Molecule extends React__namespace.Component {
35593
35709
  // screen readers?
35594
35710
  let content = /*#__PURE__*/React__namespace.createElement("canvas", {
35595
35711
  className: "molecule-canvas",
35596
- id: this.props.id + "-molecule"
35712
+ id: this.props.widgetId + "-molecule"
35597
35713
  // eslint-disable-next-line react/no-string-refs
35598
35714
  ,
35599
35715
  ref: "canvas"
@@ -35611,11 +35727,6 @@ class Molecule extends React__namespace.Component {
35611
35727
  }
35612
35728
  }
35613
35729
  class MoleculeWidget extends React__namespace.Component {
35614
- static propTypes = {
35615
- rotationAngle: PropTypes__default["default"].number,
35616
- smiles: PropTypes__default["default"].string,
35617
- widgetId: PropTypes__default["default"].string
35618
- };
35619
35730
  static defaultProps = {
35620
35731
  rotationAngle: 0
35621
35732
  };
@@ -35643,7 +35754,7 @@ class MoleculeWidget extends React__namespace.Component {
35643
35754
  };
35644
35755
  render() {
35645
35756
  return /*#__PURE__*/React__namespace.createElement(Molecule, {
35646
- id: this.props.widgetId,
35757
+ widgetId: this.props.widgetId,
35647
35758
  smiles: this.props.smiles,
35648
35759
  rotationAngle: this.props.rotationAngle
35649
35760
  });
@@ -38980,11 +39091,6 @@ var Passage$1 = {
38980
39091
 
38981
39092
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
38982
39093
  class PassageRefTarget extends React__namespace.Component {
38983
- static propTypes = {
38984
- ...propTypes,
38985
- content: PropTypes__default["default"].string,
38986
- linterContext: PerseusLinter.linterContextProps
38987
- };
38988
39094
  static defaultProps = {
38989
39095
  content: "",
38990
39096
  linterContext: PerseusLinter.linterContextDefault
@@ -39909,11 +40015,6 @@ var PythonProgram$1 = {
39909
40015
 
39910
40016
  class Separator extends React__namespace.Component {
39911
40017
  arrowLength = 100;
39912
- static propTypes = {
39913
- // TODO(colin): figure out and add shape.
39914
- data: PropTypes__default["default"].any,
39915
- index: PropTypes__default["default"].number
39916
- };
39917
40018
  componentDidMount() {
39918
40019
  this.drawArrow();
39919
40020
  }
@@ -39962,16 +40063,6 @@ class Separator extends React__namespace.Component {
39962
40063
  }
39963
40064
  }
39964
40065
  class ReactionDiagramWidget extends React__namespace.Component {
39965
- static propTypes = {
39966
- // TODO(colin): at the moment, these must be arrays of two elements;
39967
- // we're limited to a single reaction step. At some point, add support
39968
- // for more steps in the reaction.
39969
- rotationAngle: PropTypes__default["default"].arrayOf(PropTypes__default["default"].number),
39970
- // eslint-disable-next-line react/forbid-prop-types
39971
- separators: PropTypes__default["default"].arrayOf(PropTypes__default["default"].object),
39972
- smiles: PropTypes__default["default"].arrayOf(PropTypes__default["default"].string),
39973
- widgetId: PropTypes__default["default"].string
39974
- };
39975
40066
  static defaultProps = {
39976
40067
  smiles: [],
39977
40068
  rotationAngle: [],
@@ -40014,7 +40105,7 @@ class ReactionDiagramWidget extends React__namespace.Component {
40014
40105
  key: id,
40015
40106
  className: "molecule-container"
40016
40107
  }, /*#__PURE__*/React__namespace.createElement(Molecule, {
40017
- id: id,
40108
+ widgetId: id,
40018
40109
  rotationAngle: this.props.rotationAngle[i],
40019
40110
  smiles: s
40020
40111
  }), i === this.props.smiles.length - 1 ? null : /*#__PURE__*/React__namespace.createElement(Separator, {
@@ -42262,7 +42353,7 @@ const init = function (options) {
42262
42353
 
42263
42354
  // This file is processed by a Rollup plugin (replace) to inject the production
42264
42355
  const libName = "@khanacademy/perseus";
42265
- const libVersion = "19.7.3";
42356
+ const libVersion = "19.8.0";
42266
42357
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
42267
42358
 
42268
42359
  const apiVersion = {
@@ -43404,8 +43495,6 @@ const ItemExtras = [
43404
43495
  const PerseusExpressionAnswerFormConsidered = ["correct", "wrong", "ungraded"];
43405
43496
  const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
43406
43497
 
43407
- // TODO(FEI-3983): Create proper types for these.
43408
-
43409
43498
  /**
43410
43499
  * Traverses a {content, widgets, images} renderer props object,
43411
43500
  * such as `itemData.question`