@khanacademy/perseus 23.1.0 → 23.3.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 +230 -79
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +239 -79
- package/dist/index.js.map +1 -1
- package/dist/perseus-api.d.ts +0 -1
- package/dist/perseus-types.d.ts +16 -8
- package/dist/server-item-renderer.d.ts +0 -1
- package/dist/types.d.ts +1 -1
- package/dist/util/geometry.d.ts +1 -0
- package/dist/widgets/expression.d.ts +0 -6
- package/dist/widgets/interactive-graphs/graphs/components/css-cursor.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/components/movable-point-view.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/components/movable-point.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/index.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/linear-system.d.ts +5 -0
- package/dist/widgets/interactive-graphs/graphs/linear.d.ts +1 -1
- package/dist/widgets/interactive-graphs/interactive-graph-question-builder.d.ts +5 -3
- package/dist/widgets/interactive-graphs/locked-ellipse.d.ts +4 -0
- package/dist/widgets/interactive-graphs/locked-vector.d.ts +4 -0
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-state.d.ts +1 -1
- package/dist/widgets/interactive-graphs/types.d.ts +8 -9
- package/dist/widgets/label-image.d.ts +0 -2
- package/package.json +1 -1
- package/dist/widgets/interactive-graphs/locked-circle.d.ts +0 -4
package/dist/es/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import { OptionItem, SingleSelect, MultiSelect } from '@khanacademy/wonder-block
|
|
|
29
29
|
import caretDown from '@phosphor-icons/core/regular/caret-down.svg';
|
|
30
30
|
import caretUp from '@phosphor-icons/core/regular/caret-up.svg';
|
|
31
31
|
import debounce$2 from 'lodash.debounce';
|
|
32
|
-
import { vec,
|
|
32
|
+
import { vec, Ellipse, Line as Line$4, Point as Point$2, useMovable, Text as Text$1, Polygon, Plot as Plot$3, Coordinates, Mafs } from 'mafs';
|
|
33
33
|
import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
|
|
34
34
|
import { Body, LabelSmall, LabelMedium } from '@khanacademy/wonder-blocks-typography';
|
|
35
35
|
import questionIcon from '@phosphor-icons/core/regular/question.svg';
|
|
@@ -10827,6 +10827,33 @@ function intersects(ab, cd) {
|
|
|
10827
10827
|
}
|
|
10828
10828
|
return false;
|
|
10829
10829
|
}
|
|
10830
|
+
|
|
10831
|
+
// Whether any two sides of a polygon intersect each other
|
|
10832
|
+
function polygonSidesIntersect(vertices) {
|
|
10833
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
10834
|
+
for (let k = i + 1; k < vertices.length; k++) {
|
|
10835
|
+
// If any two vertices are the same point, sides overlap
|
|
10836
|
+
if (point.equal(vertices[i], vertices[k])) {
|
|
10837
|
+
return true;
|
|
10838
|
+
}
|
|
10839
|
+
|
|
10840
|
+
// Find the other end of the sides starting at vertices i and k
|
|
10841
|
+
const iNext = (i + 1) % vertices.length;
|
|
10842
|
+
const kNext = (k + 1) % vertices.length;
|
|
10843
|
+
|
|
10844
|
+
// Adjacent sides always intersect (at the vertex); skip those
|
|
10845
|
+
if (iNext === k || kNext === i) {
|
|
10846
|
+
continue;
|
|
10847
|
+
}
|
|
10848
|
+
const side1 = [vertices[i], vertices[iNext]];
|
|
10849
|
+
const side2 = [vertices[k], vertices[kNext]];
|
|
10850
|
+
if (intersects(side1, side2)) {
|
|
10851
|
+
return true;
|
|
10852
|
+
}
|
|
10853
|
+
}
|
|
10854
|
+
}
|
|
10855
|
+
return false;
|
|
10856
|
+
}
|
|
10830
10857
|
function vector(a, b) {
|
|
10831
10858
|
return _.map(_.zip(a, b), function (pair) {
|
|
10832
10859
|
return pair[0] - pair[1];
|
|
@@ -28631,25 +28658,27 @@ const lockedFigureColors = {
|
|
|
28631
28658
|
pink: "#B25071",
|
|
28632
28659
|
red: "#D92916"
|
|
28633
28660
|
};
|
|
28661
|
+
const lockedEllipseFillStyles = {
|
|
28662
|
+
none: 0,
|
|
28663
|
+
solid: 1,
|
|
28664
|
+
translucent: 0.4
|
|
28665
|
+
};
|
|
28634
28666
|
const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
|
|
28635
28667
|
|
|
28636
|
-
const
|
|
28668
|
+
const LockedEllipse = props => {
|
|
28637
28669
|
const {
|
|
28638
28670
|
center,
|
|
28639
28671
|
radius,
|
|
28672
|
+
angle,
|
|
28640
28673
|
color,
|
|
28641
28674
|
fillStyle,
|
|
28642
28675
|
strokeStyle
|
|
28643
28676
|
} = props;
|
|
28644
|
-
|
|
28645
|
-
none: 0,
|
|
28646
|
-
solid: 1,
|
|
28647
|
-
translucent: 0.4
|
|
28648
|
-
};
|
|
28649
|
-
return /*#__PURE__*/React.createElement(Circle$1, {
|
|
28677
|
+
return /*#__PURE__*/React.createElement(Ellipse, {
|
|
28650
28678
|
center: center,
|
|
28651
28679
|
radius: radius,
|
|
28652
|
-
|
|
28680
|
+
angle: angle,
|
|
28681
|
+
fillOpacity: lockedEllipseFillStyles[fillStyle],
|
|
28653
28682
|
strokeStyle: strokeStyle,
|
|
28654
28683
|
color: lockedFigureColors[color]
|
|
28655
28684
|
});
|
|
@@ -28909,6 +28938,21 @@ const LockedPoint = props => {
|
|
|
28909
28938
|
});
|
|
28910
28939
|
};
|
|
28911
28940
|
|
|
28941
|
+
const LockedVector = props => {
|
|
28942
|
+
const {
|
|
28943
|
+
color,
|
|
28944
|
+
points
|
|
28945
|
+
} = props;
|
|
28946
|
+
const [tail, tip] = points;
|
|
28947
|
+
return /*#__PURE__*/React.createElement("g", {
|
|
28948
|
+
className: "locked-vector"
|
|
28949
|
+
}, /*#__PURE__*/React.createElement(Vector, {
|
|
28950
|
+
tail: tail,
|
|
28951
|
+
tip: tip,
|
|
28952
|
+
color: lockedFigureColors[color]
|
|
28953
|
+
}));
|
|
28954
|
+
};
|
|
28955
|
+
|
|
28912
28956
|
const GraphLockedLayer = props => {
|
|
28913
28957
|
const {
|
|
28914
28958
|
lockedFigures
|
|
@@ -28924,9 +28968,13 @@ const GraphLockedLayer = props => {
|
|
|
28924
28968
|
key: `line-${index}`,
|
|
28925
28969
|
range: props.range
|
|
28926
28970
|
}, figure));
|
|
28927
|
-
case "
|
|
28928
|
-
return /*#__PURE__*/React.createElement(
|
|
28929
|
-
key: `
|
|
28971
|
+
case "ellipse":
|
|
28972
|
+
return /*#__PURE__*/React.createElement(LockedEllipse, _extends({
|
|
28973
|
+
key: `ellipse-${index}`
|
|
28974
|
+
}, figure));
|
|
28975
|
+
case "vector":
|
|
28976
|
+
return /*#__PURE__*/React.createElement(LockedVector, _extends({
|
|
28977
|
+
key: `vector-${index}`
|
|
28930
28978
|
}, figure));
|
|
28931
28979
|
default:
|
|
28932
28980
|
/**
|
|
@@ -29056,7 +29104,8 @@ const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
|
|
|
29056
29104
|
point,
|
|
29057
29105
|
color: color$1 = color.blue,
|
|
29058
29106
|
dragging,
|
|
29059
|
-
focusBehavior
|
|
29107
|
+
focusBehavior,
|
|
29108
|
+
cursor
|
|
29060
29109
|
} = props;
|
|
29061
29110
|
|
|
29062
29111
|
// WB Tooltip requires a color name for the background color.
|
|
@@ -29088,7 +29137,8 @@ const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
|
|
|
29088
29137
|
ref: hitboxRef,
|
|
29089
29138
|
className: pointClasses,
|
|
29090
29139
|
style: {
|
|
29091
|
-
"--movable-point-color": color$1
|
|
29140
|
+
"--movable-point-color": color$1,
|
|
29141
|
+
cursor
|
|
29092
29142
|
},
|
|
29093
29143
|
"data-testid": "movable-point",
|
|
29094
29144
|
tabIndex: tabIndex(focusBehavior)
|
|
@@ -29336,7 +29386,33 @@ const SegmentGraph = props => {
|
|
|
29336
29386
|
})));
|
|
29337
29387
|
};
|
|
29338
29388
|
|
|
29339
|
-
const LinearGraph = props => {
|
|
29389
|
+
const LinearGraph = (props, key) => {
|
|
29390
|
+
const {
|
|
29391
|
+
dispatch
|
|
29392
|
+
} = props;
|
|
29393
|
+
const {
|
|
29394
|
+
coords: line
|
|
29395
|
+
} = props.graphState;
|
|
29396
|
+
|
|
29397
|
+
// Linear graphs only have one line
|
|
29398
|
+
// (LEMS-2050): Update the reducer so that we have a separate action for moving one line
|
|
29399
|
+
// and another action for moving multiple lines
|
|
29400
|
+
return /*#__PURE__*/React.createElement(MovableLine, {
|
|
29401
|
+
key: 0,
|
|
29402
|
+
points: line,
|
|
29403
|
+
onMoveLine: delta => {
|
|
29404
|
+
dispatch(moveLine(0, delta));
|
|
29405
|
+
},
|
|
29406
|
+
extend: {
|
|
29407
|
+
start: true,
|
|
29408
|
+
end: true
|
|
29409
|
+
},
|
|
29410
|
+
onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(endpointIndex, destination, 0)),
|
|
29411
|
+
color: "var(--movable-line-stroke-color)"
|
|
29412
|
+
});
|
|
29413
|
+
};
|
|
29414
|
+
|
|
29415
|
+
const LinearSystemGraph = props => {
|
|
29340
29416
|
const {
|
|
29341
29417
|
dispatch
|
|
29342
29418
|
} = props;
|
|
@@ -29356,7 +29432,7 @@ const LinearGraph = props => {
|
|
|
29356
29432
|
},
|
|
29357
29433
|
onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(endpointIndex, destination, i)),
|
|
29358
29434
|
color: colors[i]
|
|
29359
|
-
})));
|
|
29435
|
+
})), ";");
|
|
29360
29436
|
};
|
|
29361
29437
|
|
|
29362
29438
|
const RayGraph = props => {
|
|
@@ -29364,14 +29440,14 @@ const RayGraph = props => {
|
|
|
29364
29440
|
dispatch
|
|
29365
29441
|
} = props;
|
|
29366
29442
|
const {
|
|
29367
|
-
coords:
|
|
29443
|
+
coords: line
|
|
29368
29444
|
} = props.graphState;
|
|
29369
29445
|
const handleMoveLine = delta => dispatch(moveLine(0, delta));
|
|
29370
29446
|
const handleMovePoint = (pointIndex, newPoint) => dispatch(moveControlPoint(pointIndex, newPoint, 0));
|
|
29371
|
-
|
|
29372
|
-
//
|
|
29373
|
-
, {
|
|
29374
|
-
points:
|
|
29447
|
+
|
|
29448
|
+
// Ray graphs only have one line
|
|
29449
|
+
return /*#__PURE__*/React.createElement(MovableLine, {
|
|
29450
|
+
points: line,
|
|
29375
29451
|
onMoveLine: handleMoveLine,
|
|
29376
29452
|
onMovePoint: handleMovePoint,
|
|
29377
29453
|
extend: {
|
|
@@ -29550,6 +29626,7 @@ const StyledMovablePoint = props => {
|
|
|
29550
29626
|
const {
|
|
29551
29627
|
point,
|
|
29552
29628
|
onMove,
|
|
29629
|
+
cursor,
|
|
29553
29630
|
color: color$1 = color.blue
|
|
29554
29631
|
} = props;
|
|
29555
29632
|
const {
|
|
@@ -29568,7 +29645,8 @@ const StyledMovablePoint = props => {
|
|
|
29568
29645
|
focusBehavior: {
|
|
29569
29646
|
type: "uncontrolled",
|
|
29570
29647
|
tabIndex: 0
|
|
29571
|
-
}
|
|
29648
|
+
},
|
|
29649
|
+
cursor: cursor
|
|
29572
29650
|
});
|
|
29573
29651
|
};
|
|
29574
29652
|
|
|
@@ -29672,25 +29750,39 @@ function initializeGraphState(params) {
|
|
|
29672
29750
|
case "segment":
|
|
29673
29751
|
return _extends({}, shared, {
|
|
29674
29752
|
type: "segment",
|
|
29675
|
-
coords:
|
|
29753
|
+
coords: getSegmentCoords({
|
|
29676
29754
|
graph,
|
|
29677
29755
|
step,
|
|
29678
29756
|
range
|
|
29679
29757
|
})
|
|
29680
29758
|
});
|
|
29681
29759
|
case "linear":
|
|
29682
|
-
|
|
29760
|
+
return _extends({}, shared, {
|
|
29761
|
+
type: graph.type,
|
|
29762
|
+
coords: getLineCoords({
|
|
29763
|
+
graph,
|
|
29764
|
+
range,
|
|
29765
|
+
step
|
|
29766
|
+
})
|
|
29767
|
+
});
|
|
29683
29768
|
case "ray":
|
|
29684
29769
|
return _extends({}, shared, {
|
|
29685
29770
|
type: graph.type,
|
|
29686
|
-
// Linear and ray graphs have a single tuple of points, while a
|
|
29687
|
-
// linear system has two tuples of points.
|
|
29688
29771
|
coords: getLineCoords({
|
|
29689
29772
|
graph,
|
|
29690
29773
|
range,
|
|
29691
29774
|
step
|
|
29692
29775
|
})
|
|
29693
29776
|
});
|
|
29777
|
+
case "linear-system":
|
|
29778
|
+
return _extends({}, shared, {
|
|
29779
|
+
type: graph.type,
|
|
29780
|
+
coords: getLinearSystemCoords({
|
|
29781
|
+
graph,
|
|
29782
|
+
range,
|
|
29783
|
+
step
|
|
29784
|
+
})
|
|
29785
|
+
});
|
|
29694
29786
|
case "polygon":
|
|
29695
29787
|
return _extends({}, shared, {
|
|
29696
29788
|
type: "polygon",
|
|
@@ -29713,10 +29805,8 @@ function initializeGraphState(params) {
|
|
|
29713
29805
|
});
|
|
29714
29806
|
case "circle":
|
|
29715
29807
|
return _extends({}, shared, {
|
|
29716
|
-
type: graph.type
|
|
29717
|
-
|
|
29718
|
-
radiusPoint: [1, 0]
|
|
29719
|
-
});
|
|
29808
|
+
type: graph.type
|
|
29809
|
+
}, getCircleCoords(graph));
|
|
29720
29810
|
case "quadratic":
|
|
29721
29811
|
return _extends({}, shared, {
|
|
29722
29812
|
type: graph.type,
|
|
@@ -29792,12 +29882,12 @@ function getGradableGraph(state, initialGraph) {
|
|
|
29792
29882
|
}
|
|
29793
29883
|
if (state.type === "linear" && initialGraph.type === "linear") {
|
|
29794
29884
|
return _extends({}, initialGraph, {
|
|
29795
|
-
coords: state.coords
|
|
29885
|
+
coords: state.coords
|
|
29796
29886
|
});
|
|
29797
29887
|
}
|
|
29798
29888
|
if (state.type === "ray" && initialGraph.type === "ray") {
|
|
29799
29889
|
return _extends({}, initialGraph, {
|
|
29800
|
-
coords: state.coords
|
|
29890
|
+
coords: state.coords
|
|
29801
29891
|
});
|
|
29802
29892
|
}
|
|
29803
29893
|
if (state.type === "polygon" && initialGraph.type === "polygon") {
|
|
@@ -29828,11 +29918,14 @@ function getGradableGraph(state, initialGraph) {
|
|
|
29828
29918
|
}
|
|
29829
29919
|
throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
|
|
29830
29920
|
}
|
|
29831
|
-
const
|
|
29921
|
+
const getSegmentCoords = ({
|
|
29832
29922
|
graph,
|
|
29833
29923
|
range,
|
|
29834
29924
|
step
|
|
29835
29925
|
}) => {
|
|
29926
|
+
if (graph.coords) {
|
|
29927
|
+
return graph.coords;
|
|
29928
|
+
}
|
|
29836
29929
|
const ys = n => {
|
|
29837
29930
|
switch (n) {
|
|
29838
29931
|
case 2:
|
|
@@ -29863,16 +29956,20 @@ const getLineCoords = ({
|
|
|
29863
29956
|
range,
|
|
29864
29957
|
step
|
|
29865
29958
|
}) => {
|
|
29866
|
-
|
|
29867
|
-
|
|
29868
|
-
|
|
29869
|
-
|
|
29870
|
-
|
|
29871
|
-
|
|
29872
|
-
|
|
29873
|
-
|
|
29874
|
-
|
|
29959
|
+
if (graph.coords) {
|
|
29960
|
+
return graph.coords;
|
|
29961
|
+
}
|
|
29962
|
+
return normalizePoints(range, step, defaultLinearCoords[0]);
|
|
29963
|
+
};
|
|
29964
|
+
const getLinearSystemCoords = ({
|
|
29965
|
+
graph,
|
|
29966
|
+
range,
|
|
29967
|
+
step
|
|
29968
|
+
}) => {
|
|
29969
|
+
if (graph.coords) {
|
|
29970
|
+
return graph.coords;
|
|
29875
29971
|
}
|
|
29972
|
+
return defaultLinearCoords.map(points => normalizePoints(range, step, points));
|
|
29876
29973
|
};
|
|
29877
29974
|
const getPolygonCoords = ({
|
|
29878
29975
|
graph,
|
|
@@ -29904,14 +30001,31 @@ const getPolygonCoords = ({
|
|
|
29904
30001
|
return coords;
|
|
29905
30002
|
};
|
|
29906
30003
|
const getSinusoidCoords = (graph, range, step) => {
|
|
30004
|
+
if (graph.coords) {
|
|
30005
|
+
return [graph.coords[0], graph.coords[1]];
|
|
30006
|
+
}
|
|
29907
30007
|
let coords = [[0.5, 0.5], [0.65, 0.6]];
|
|
29908
30008
|
coords = normalizePoints(range, step, coords, true);
|
|
29909
30009
|
return coords;
|
|
29910
30010
|
};
|
|
29911
30011
|
const getQuadraticCoords = (graph, range, step) => {
|
|
29912
|
-
|
|
29913
|
-
|
|
29914
|
-
|
|
30012
|
+
if (graph.coords) {
|
|
30013
|
+
return graph.coords;
|
|
30014
|
+
}
|
|
30015
|
+
const defaultCoords = [[0.25, 0.75], [0.5, 0.25], [0.75, 0.75]];
|
|
30016
|
+
return normalizePoints(range, step, defaultCoords, true);
|
|
30017
|
+
};
|
|
30018
|
+
const getCircleCoords = (graph, range, step) => {
|
|
30019
|
+
if (graph.center != null && graph.radius != null) {
|
|
30020
|
+
return {
|
|
30021
|
+
center: graph.center,
|
|
30022
|
+
radiusPoint: vec.add(graph.center, [graph.radius, 0])
|
|
30023
|
+
};
|
|
30024
|
+
}
|
|
30025
|
+
return {
|
|
30026
|
+
center: [0, 0],
|
|
30027
|
+
radiusPoint: [1, 0]
|
|
30028
|
+
};
|
|
29915
30029
|
};
|
|
29916
30030
|
|
|
29917
30031
|
/**
|
|
@@ -29941,6 +30055,7 @@ function CircleGraph(props) {
|
|
|
29941
30055
|
onMove: newCenter => dispatch(moveCenter(newCenter))
|
|
29942
30056
|
}), /*#__PURE__*/React.createElement(StyledMovablePoint, {
|
|
29943
30057
|
point: radiusPoint,
|
|
30058
|
+
cursor: "ew-resize",
|
|
29944
30059
|
onMove: newRadiusPoint => {
|
|
29945
30060
|
dispatch(moveRadiusPoint(newRadiusPoint));
|
|
29946
30061
|
}
|
|
@@ -31243,15 +31358,9 @@ function interactiveGraphReducer(state, action) {
|
|
|
31243
31358
|
}
|
|
31244
31359
|
}
|
|
31245
31360
|
function doMoveControlPoint(state, action) {
|
|
31246
|
-
const {
|
|
31247
|
-
snapStep,
|
|
31248
|
-
range
|
|
31249
|
-
} = state;
|
|
31250
31361
|
switch (state.type) {
|
|
31251
31362
|
case "segment":
|
|
31252
|
-
case "linear":
|
|
31253
31363
|
case "linear-system":
|
|
31254
|
-
case "ray":
|
|
31255
31364
|
{
|
|
31256
31365
|
const newCoords = updateAtIndex({
|
|
31257
31366
|
array: state.coords,
|
|
@@ -31259,11 +31368,7 @@ function doMoveControlPoint(state, action) {
|
|
|
31259
31368
|
update: tuple => setAtIndex({
|
|
31260
31369
|
array: tuple,
|
|
31261
31370
|
index: action.pointIndex,
|
|
31262
|
-
newValue:
|
|
31263
|
-
snapStep,
|
|
31264
|
-
range,
|
|
31265
|
-
point: action.destination
|
|
31266
|
-
}))
|
|
31371
|
+
newValue: boundAndSnapToGrid(action.destination, state)
|
|
31267
31372
|
})
|
|
31268
31373
|
});
|
|
31269
31374
|
const coordsToCheck = newCoords[action.itemIndex];
|
|
@@ -31275,6 +31380,19 @@ function doMoveControlPoint(state, action) {
|
|
|
31275
31380
|
coords: newCoords
|
|
31276
31381
|
});
|
|
31277
31382
|
}
|
|
31383
|
+
case "linear":
|
|
31384
|
+
case "ray":
|
|
31385
|
+
{
|
|
31386
|
+
const newCoords = setAtIndex({
|
|
31387
|
+
array: state.coords,
|
|
31388
|
+
index: action.pointIndex,
|
|
31389
|
+
newValue: boundAndSnapToGrid(action.destination, state)
|
|
31390
|
+
});
|
|
31391
|
+
return _extends({}, state, {
|
|
31392
|
+
hasBeenInteractedWith: true,
|
|
31393
|
+
coords: newCoords
|
|
31394
|
+
});
|
|
31395
|
+
}
|
|
31278
31396
|
case "circle":
|
|
31279
31397
|
throw new Error("FIXME implement circle reducer");
|
|
31280
31398
|
case "point":
|
|
@@ -31286,6 +31404,9 @@ function doMoveControlPoint(state, action) {
|
|
|
31286
31404
|
throw new UnreachableCaseError(state);
|
|
31287
31405
|
}
|
|
31288
31406
|
}
|
|
31407
|
+
|
|
31408
|
+
// (LEMS-2050): Update the reducer so that we have a separate action for moving one line
|
|
31409
|
+
// and another action for moving multiple lines
|
|
31289
31410
|
function doMoveLine(state, action) {
|
|
31290
31411
|
const {
|
|
31291
31412
|
snapStep,
|
|
@@ -31293,9 +31414,7 @@ function doMoveLine(state, action) {
|
|
|
31293
31414
|
} = state;
|
|
31294
31415
|
switch (state.type) {
|
|
31295
31416
|
case "segment":
|
|
31296
|
-
case "linear":
|
|
31297
31417
|
case "linear-system":
|
|
31298
|
-
case "ray":
|
|
31299
31418
|
{
|
|
31300
31419
|
if (action.itemIndex === undefined) {
|
|
31301
31420
|
throw new Error("Please provide index of line to move");
|
|
@@ -31320,6 +31439,21 @@ function doMoveLine(state, action) {
|
|
|
31320
31439
|
coords: newCoords
|
|
31321
31440
|
});
|
|
31322
31441
|
}
|
|
31442
|
+
case "linear":
|
|
31443
|
+
case "ray":
|
|
31444
|
+
{
|
|
31445
|
+
const currentLine = state.coords;
|
|
31446
|
+
const change = getChange(currentLine, action.delta, {
|
|
31447
|
+
snapStep,
|
|
31448
|
+
range
|
|
31449
|
+
});
|
|
31450
|
+
const newLine = [snap(snapStep, vec.add(currentLine[0], change)), snap(snapStep, vec.add(currentLine[1], change))];
|
|
31451
|
+
return _extends({}, state, {
|
|
31452
|
+
type: state.type,
|
|
31453
|
+
hasBeenInteractedWith: true,
|
|
31454
|
+
coords: newLine
|
|
31455
|
+
});
|
|
31456
|
+
}
|
|
31323
31457
|
default:
|
|
31324
31458
|
// The MoveLine action doesn't make sense for other graph types;
|
|
31325
31459
|
// ignore it if it somehow happens
|
|
@@ -31352,6 +31486,20 @@ function doMoveAll(state, action) {
|
|
|
31352
31486
|
function doMovePoint(state, action) {
|
|
31353
31487
|
switch (state.type) {
|
|
31354
31488
|
case "polygon":
|
|
31489
|
+
const newCoords = setAtIndex({
|
|
31490
|
+
array: state.coords,
|
|
31491
|
+
index: action.index,
|
|
31492
|
+
newValue: boundAndSnapToGrid(action.destination, state)
|
|
31493
|
+
});
|
|
31494
|
+
|
|
31495
|
+
// Reject the move if it would cause the sides of the polygon to cross
|
|
31496
|
+
if (polygonSidesIntersect(newCoords)) {
|
|
31497
|
+
return state;
|
|
31498
|
+
}
|
|
31499
|
+
return _extends({}, state, {
|
|
31500
|
+
hasBeenInteractedWith: true,
|
|
31501
|
+
coords: newCoords
|
|
31502
|
+
});
|
|
31355
31503
|
case "point":
|
|
31356
31504
|
{
|
|
31357
31505
|
return _extends({}, state, {
|
|
@@ -31359,11 +31507,7 @@ function doMovePoint(state, action) {
|
|
|
31359
31507
|
coords: setAtIndex({
|
|
31360
31508
|
array: state.coords,
|
|
31361
31509
|
index: action.index,
|
|
31362
|
-
newValue:
|
|
31363
|
-
snapStep: state.snapStep,
|
|
31364
|
-
range: state.range,
|
|
31365
|
-
point: action.destination
|
|
31366
|
-
}))
|
|
31510
|
+
newValue: boundAndSnapToGrid(action.destination, state)
|
|
31367
31511
|
})
|
|
31368
31512
|
});
|
|
31369
31513
|
}
|
|
@@ -31372,9 +31516,9 @@ function doMovePoint(state, action) {
|
|
|
31372
31516
|
// First, we need to verify that the new coordinates are not on the same vertical line
|
|
31373
31517
|
// If they are, we don't want to move the point
|
|
31374
31518
|
const destination = action.destination;
|
|
31375
|
-
const
|
|
31376
|
-
|
|
31377
|
-
if (
|
|
31519
|
+
const _newCoords = [...state.coords];
|
|
31520
|
+
_newCoords[action.index] = action.destination;
|
|
31521
|
+
if (_newCoords[0][0] === _newCoords[1][0]) {
|
|
31378
31522
|
return state;
|
|
31379
31523
|
}
|
|
31380
31524
|
return _extends({}, state, {
|
|
@@ -31382,11 +31526,7 @@ function doMovePoint(state, action) {
|
|
|
31382
31526
|
coords: setAtIndex({
|
|
31383
31527
|
array: state.coords,
|
|
31384
31528
|
index: action.index,
|
|
31385
|
-
newValue:
|
|
31386
|
-
snapStep: state.snapStep,
|
|
31387
|
-
range: state.range,
|
|
31388
|
-
point: destination
|
|
31389
|
-
}))
|
|
31529
|
+
newValue: boundAndSnapToGrid(destination, state)
|
|
31390
31530
|
})
|
|
31391
31531
|
});
|
|
31392
31532
|
}
|
|
@@ -31397,11 +31537,7 @@ function doMovePoint(state, action) {
|
|
|
31397
31537
|
coords: setAtIndex({
|
|
31398
31538
|
array: state.coords,
|
|
31399
31539
|
index: action.index,
|
|
31400
|
-
newValue:
|
|
31401
|
-
snapStep: state.snapStep,
|
|
31402
|
-
range: state.range,
|
|
31403
|
-
point: action.destination
|
|
31404
|
-
}))
|
|
31540
|
+
newValue: boundAndSnapToGrid(action.destination, state)
|
|
31405
31541
|
})
|
|
31406
31542
|
});
|
|
31407
31543
|
}
|
|
@@ -31504,6 +31640,17 @@ const getChange = (coords, delta, constraintOpts) => {
|
|
|
31504
31640
|
const dy = clamp(deltaY, minYMove, maxYMove);
|
|
31505
31641
|
return [dx, dy];
|
|
31506
31642
|
};
|
|
31643
|
+
function boundAndSnapToGrid(point, {
|
|
31644
|
+
snapStep,
|
|
31645
|
+
range
|
|
31646
|
+
}) {
|
|
31647
|
+
return snap(snapStep, bound$1({
|
|
31648
|
+
snapStep,
|
|
31649
|
+
range,
|
|
31650
|
+
point
|
|
31651
|
+
}));
|
|
31652
|
+
}
|
|
31653
|
+
|
|
31507
31654
|
// Returns the closest point to the given `point` that is within the graph
|
|
31508
31655
|
// bounds given in `state`.
|
|
31509
31656
|
function bound$1({
|
|
@@ -31593,8 +31740,12 @@ const renderGraph = props => {
|
|
|
31593
31740
|
graphState: state,
|
|
31594
31741
|
dispatch: dispatch
|
|
31595
31742
|
});
|
|
31596
|
-
case "linear":
|
|
31597
31743
|
case "linear-system":
|
|
31744
|
+
return /*#__PURE__*/React.createElement(LinearSystemGraph, {
|
|
31745
|
+
graphState: state,
|
|
31746
|
+
dispatch: dispatch
|
|
31747
|
+
});
|
|
31748
|
+
case "linear":
|
|
31598
31749
|
return /*#__PURE__*/React.createElement(LinearGraph, {
|
|
31599
31750
|
graphState: state,
|
|
31600
31751
|
dispatch: dispatch
|
|
@@ -43843,7 +43994,7 @@ const init = function init(options) {
|
|
|
43843
43994
|
|
|
43844
43995
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
43845
43996
|
const libName = "@khanacademy/perseus";
|
|
43846
|
-
const libVersion = "23.
|
|
43997
|
+
const libVersion = "23.3.0";
|
|
43847
43998
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
43848
43999
|
|
|
43849
44000
|
const apiVersion = {
|
|
@@ -46844,5 +46995,5 @@ const EditorJsonify = {
|
|
|
46844
46995
|
}
|
|
46845
46996
|
};
|
|
46846
46997
|
|
|
46847
|
-
export { ApiOptions, ArrowPicker, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, ColorPicker, DashPicker, dependencies as Dependencies, EditorJsonify, ElementContainer, Errors, Expression, util as GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusError, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, sizingUtils as SizingUtils, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, WidgetJsonifyDeprecated, widgets$1 as Widgets, addWidget, apiVersion, buildEmptyItemTreeForShape, buildMapper, components, constants, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAnswerFromUserInput, getAnswersFromWidgets, getCorrectAnswerForWidgetId, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, globalConstants, globalStyles, iconPaths as icons, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedFigureColors, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
|
|
46998
|
+
export { ApiOptions, ArrowPicker, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, ColorPicker, DashPicker, dependencies as Dependencies, EditorJsonify, ElementContainer, Errors, Expression, util as GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusError, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, sizingUtils as SizingUtils, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, WidgetJsonifyDeprecated, widgets$1 as Widgets, addWidget, apiVersion, buildEmptyItemTreeForShape, buildMapper, components, constants, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAnswerFromUserInput, getAnswersFromWidgets, getCorrectAnswerForWidgetId, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, globalConstants, globalStyles, iconPaths as icons, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedEllipseFillStyles, lockedFigureColors, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
|
|
46848
46999
|
//# sourceMappingURL=index.js.map
|