@khanacademy/perseus 21.1.0 → 21.2.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 +227 -64
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +235 -72
- package/dist/index.js.map +1 -1
- package/dist/perseus-api.d.ts +1 -1
- package/dist/perseus-types.d.ts +6 -2
- package/dist/server-item-renderer.d.ts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/util.d.ts +3 -0
- package/dist/widgets/expression.d.ts +6 -6
- package/dist/widgets/interactive-graph.d.ts +4 -1
- package/dist/widgets/interactive-graphs/axis-ticks.d.ts +8 -0
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +6 -4
- package/dist/widgets/interactive-graphs/grid.d.ts +14 -3
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +2 -2
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +14 -1
- package/dist/widgets/interactive-graphs/utils.d.ts +2 -0
- package/dist/widgets/label-image.d.ts +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3281,6 +3281,15 @@ const textarea = {
|
|
|
3281
3281
|
*/
|
|
3282
3282
|
const unescapeMathMode$1 = label => label.startsWith("$") && label.endsWith("$") ? label.slice(1, -1) : label;
|
|
3283
3283
|
const random$1 = seededRNG$1(new Date().getTime() & 0xffffffff);
|
|
3284
|
+
|
|
3285
|
+
// TODO(benchristel): in the future, we may want to make deepClone work for
|
|
3286
|
+
// Record<string, Cloneable> as well. Currently, it only does arrays.
|
|
3287
|
+
function deepClone(obj) {
|
|
3288
|
+
if (Array.isArray(obj)) {
|
|
3289
|
+
return obj.map(deepClone);
|
|
3290
|
+
}
|
|
3291
|
+
return obj;
|
|
3292
|
+
}
|
|
3284
3293
|
const Util = {
|
|
3285
3294
|
inputPathsEqual,
|
|
3286
3295
|
nestedMap: nestedMap$2,
|
|
@@ -3326,7 +3335,8 @@ const Util = {
|
|
|
3326
3335
|
getDataUrl: getDataUrl,
|
|
3327
3336
|
textarea,
|
|
3328
3337
|
unescapeMathMode: unescapeMathMode$1,
|
|
3329
|
-
random: random$1
|
|
3338
|
+
random: random$1,
|
|
3339
|
+
deepClone
|
|
3330
3340
|
};
|
|
3331
3341
|
|
|
3332
3342
|
// Derived from the MIT-licensed:
|
|
@@ -28364,6 +28374,28 @@ function movePoint(index, destination) {
|
|
|
28364
28374
|
destination
|
|
28365
28375
|
};
|
|
28366
28376
|
}
|
|
28377
|
+
const CHANGE_SNAP_STEP = "change-snap-step";
|
|
28378
|
+
function changeSnapStep(snapStep) {
|
|
28379
|
+
return {
|
|
28380
|
+
type: CHANGE_SNAP_STEP,
|
|
28381
|
+
snapStep
|
|
28382
|
+
};
|
|
28383
|
+
}
|
|
28384
|
+
const CHANGE_RANGE = "change-range";
|
|
28385
|
+
function changeRange(range) {
|
|
28386
|
+
return {
|
|
28387
|
+
type: CHANGE_RANGE,
|
|
28388
|
+
range
|
|
28389
|
+
};
|
|
28390
|
+
}
|
|
28391
|
+
|
|
28392
|
+
const GraphStateContext = /*#__PURE__*/React.createContext({
|
|
28393
|
+
state: {},
|
|
28394
|
+
dispatch: () => {}
|
|
28395
|
+
});
|
|
28396
|
+
function useGraphState() {
|
|
28397
|
+
return React__default["default"].useContext(GraphStateContext);
|
|
28398
|
+
}
|
|
28367
28399
|
|
|
28368
28400
|
/**
|
|
28369
28401
|
* 44 is touch best practice and AAA compliant for WCAG
|
|
@@ -28390,6 +28422,11 @@ const normalizeCoords = (coordsList, ranges) => coordsList.map(coords => coords.
|
|
|
28390
28422
|
const extent = ranges[i][1] - ranges[i][0];
|
|
28391
28423
|
return (coord + ranges[i][1]) / extent;
|
|
28392
28424
|
}));
|
|
28425
|
+
function snap(snapStep, point) {
|
|
28426
|
+
const [requestedX, requestedY] = point;
|
|
28427
|
+
const [snapX, snapY] = snapStep;
|
|
28428
|
+
return [Math.round(requestedX / snapX) * snapX, Math.round(requestedY / snapY) * snapY];
|
|
28429
|
+
}
|
|
28393
28430
|
|
|
28394
28431
|
const useTransform = function () {
|
|
28395
28432
|
const {
|
|
@@ -28448,6 +28485,9 @@ const getLines = points => points.map((point, i) => {
|
|
|
28448
28485
|
|
|
28449
28486
|
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
28450
28487
|
const MovableLine = props => {
|
|
28488
|
+
const {
|
|
28489
|
+
state
|
|
28490
|
+
} = useGraphState();
|
|
28451
28491
|
const {
|
|
28452
28492
|
start,
|
|
28453
28493
|
end,
|
|
@@ -28472,7 +28512,7 @@ const MovableLine = props => {
|
|
|
28472
28512
|
onMove: newPoint => {
|
|
28473
28513
|
onMove(mafs.vec.sub(newPoint, midpoint));
|
|
28474
28514
|
},
|
|
28475
|
-
constrain: p => p
|
|
28515
|
+
constrain: p => snap(state.snapStep, p)
|
|
28476
28516
|
});
|
|
28477
28517
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("g", {
|
|
28478
28518
|
ref: line,
|
|
@@ -28523,7 +28563,13 @@ function SVGLine(props) {
|
|
|
28523
28563
|
});
|
|
28524
28564
|
}
|
|
28525
28565
|
|
|
28566
|
+
// The hitbox size of 48px by 48px is preserved from the legacy interactive
|
|
28567
|
+
// graph.
|
|
28568
|
+
const hitboxSizePx = 48;
|
|
28526
28569
|
const StyledMovablePoint = props => {
|
|
28570
|
+
const {
|
|
28571
|
+
state
|
|
28572
|
+
} = useGraphState();
|
|
28527
28573
|
const hitboxRef = React.useRef(null);
|
|
28528
28574
|
const {
|
|
28529
28575
|
point,
|
|
@@ -28536,7 +28582,7 @@ const StyledMovablePoint = props => {
|
|
|
28536
28582
|
gestureTarget: hitboxRef,
|
|
28537
28583
|
point,
|
|
28538
28584
|
onMove,
|
|
28539
|
-
constrain: p => p
|
|
28585
|
+
constrain: p => snap(state.snapStep, p)
|
|
28540
28586
|
});
|
|
28541
28587
|
const [[x, y]] = useTransform(point);
|
|
28542
28588
|
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
@@ -28551,7 +28597,7 @@ const StyledMovablePoint = props => {
|
|
|
28551
28597
|
}
|
|
28552
28598
|
}, /*#__PURE__*/React__namespace.createElement("circle", {
|
|
28553
28599
|
className: "movable-point-hitbox",
|
|
28554
|
-
r:
|
|
28600
|
+
r: hitboxSizePx / 2,
|
|
28555
28601
|
cx: x,
|
|
28556
28602
|
cy: y
|
|
28557
28603
|
}), /*#__PURE__*/React__namespace.createElement("circle", {
|
|
@@ -28887,7 +28933,8 @@ const PolygonGraph = props => {
|
|
|
28887
28933
|
type,
|
|
28888
28934
|
showAngles,
|
|
28889
28935
|
showSides,
|
|
28890
|
-
range
|
|
28936
|
+
range,
|
|
28937
|
+
snapStep
|
|
28891
28938
|
} = props.graphState;
|
|
28892
28939
|
const points = coords ?? [[0, 0]];
|
|
28893
28940
|
const pointsSum = points.reduce((acc, point) => mafs.vec.add(acc, point), [0, 0]);
|
|
@@ -28902,7 +28949,7 @@ const PolygonGraph = props => {
|
|
|
28902
28949
|
const delta = mafs.vec.sub(newPoint, midpoint);
|
|
28903
28950
|
dispatch(moveAll(delta));
|
|
28904
28951
|
},
|
|
28905
|
-
constrain: p => p
|
|
28952
|
+
constrain: p => snap(snapStep, p)
|
|
28906
28953
|
});
|
|
28907
28954
|
const active = hovered || focused || dragging;
|
|
28908
28955
|
const lines = getLines(points);
|
|
@@ -28971,14 +29018,6 @@ function PointGraph(props) {
|
|
|
28971
29018
|
})));
|
|
28972
29019
|
}
|
|
28973
29020
|
|
|
28974
|
-
const GraphStateContext = /*#__PURE__*/React.createContext({
|
|
28975
|
-
state: {},
|
|
28976
|
-
dispatch: () => {}
|
|
28977
|
-
});
|
|
28978
|
-
function useGraphState() {
|
|
28979
|
-
return React__default["default"].useContext(GraphStateContext);
|
|
28980
|
-
}
|
|
28981
|
-
|
|
28982
29021
|
function Arrow(props) {
|
|
28983
29022
|
const {
|
|
28984
29023
|
userTransform,
|
|
@@ -29022,20 +29061,122 @@ function AxisArrows() {
|
|
|
29022
29061
|
}));
|
|
29023
29062
|
}
|
|
29024
29063
|
|
|
29025
|
-
const
|
|
29026
|
-
|
|
29027
|
-
|
|
29064
|
+
const tickSize = 10;
|
|
29065
|
+
const tickStyle = {
|
|
29066
|
+
stroke: "black",
|
|
29067
|
+
strokeWidth: 1
|
|
29068
|
+
};
|
|
29069
|
+
const YGridTick = _ref => {
|
|
29070
|
+
let {
|
|
29071
|
+
y
|
|
29072
|
+
} = _ref;
|
|
29073
|
+
const pointOnAxis = [0, y];
|
|
29074
|
+
const [[xPosition, yPosition]] = useTransform(pointOnAxis);
|
|
29075
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29076
|
+
className: "y-axis-ticks"
|
|
29077
|
+
}, /*#__PURE__*/React__namespace.createElement("line", {
|
|
29078
|
+
x1: xPosition - tickSize / 2,
|
|
29079
|
+
y1: yPosition,
|
|
29080
|
+
x2: xPosition + tickSize / 2,
|
|
29081
|
+
y2: yPosition,
|
|
29082
|
+
style: tickStyle
|
|
29083
|
+
}));
|
|
29084
|
+
};
|
|
29085
|
+
const XGridTick = _ref2 => {
|
|
29086
|
+
let {
|
|
29087
|
+
x
|
|
29088
|
+
} = _ref2;
|
|
29089
|
+
const pointOnAxis = [x, 0];
|
|
29090
|
+
const [[xPosition, yPosition]] = useTransform(pointOnAxis);
|
|
29091
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29092
|
+
className: "x-axis-ticks"
|
|
29093
|
+
}, /*#__PURE__*/React__namespace.createElement("line", {
|
|
29094
|
+
x1: xPosition,
|
|
29095
|
+
y1: yPosition + tickSize / 2,
|
|
29096
|
+
x2: xPosition,
|
|
29097
|
+
y2: yPosition - tickSize / 2,
|
|
29098
|
+
style: tickStyle
|
|
29099
|
+
}));
|
|
29100
|
+
};
|
|
29101
|
+
function generateTickLocations(tickStep, min, max) {
|
|
29102
|
+
const ticks = [];
|
|
29103
|
+
for (let i = 0 + tickStep; i < max; i += tickStep) {
|
|
29104
|
+
ticks.push(i);
|
|
29105
|
+
}
|
|
29106
|
+
for (let i = 0 - tickStep; i > min; i -= tickStep) {
|
|
29107
|
+
ticks.push(i);
|
|
29108
|
+
}
|
|
29109
|
+
return ticks;
|
|
29110
|
+
}
|
|
29111
|
+
const AxisTicks = props => {
|
|
29112
|
+
const range = props.range;
|
|
29113
|
+
const [xMin, xMax] = range[0];
|
|
29114
|
+
const [yMin, yMax] = range[1];
|
|
29115
|
+
const yTickStep = props.tickStep[1];
|
|
29116
|
+
const xTickStep = props.tickStep[0];
|
|
29117
|
+
const yGridTicks = generateTickLocations(yTickStep, yMin, yMax);
|
|
29118
|
+
const xGridTicks = generateTickLocations(xTickStep, xMin, xMax);
|
|
29119
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29120
|
+
className: "axis-ticks"
|
|
29121
|
+
}, yGridTicks.map(y => {
|
|
29122
|
+
return /*#__PURE__*/React__namespace.createElement(YGridTick, {
|
|
29123
|
+
y: y,
|
|
29124
|
+
key: `y-grid-tick-${y}`
|
|
29125
|
+
});
|
|
29126
|
+
}), xGridTicks.map(x => {
|
|
29127
|
+
return /*#__PURE__*/React__namespace.createElement(XGridTick, {
|
|
29128
|
+
x: x,
|
|
29129
|
+
key: `x-grid-tick-${x}`
|
|
29130
|
+
});
|
|
29131
|
+
}));
|
|
29132
|
+
};
|
|
29133
|
+
|
|
29134
|
+
/**
|
|
29135
|
+
* lineLabelText get the text that should
|
|
29136
|
+
* be displayed for a specific tick place
|
|
29137
|
+
*
|
|
29138
|
+
* @param {number} n the tick number
|
|
29139
|
+
* @param {number} tickStep how frequently a label should appear
|
|
29140
|
+
* @param {vec.Vector2} range the min/max range on the axis
|
|
29141
|
+
*/
|
|
29142
|
+
const lineLabelText = (n, tickStep, range) => {
|
|
29143
|
+
const [min, max] = range;
|
|
29144
|
+
const isOnStep = n % tickStep === 0;
|
|
29145
|
+
const isNegativeOne = n === -1;
|
|
29146
|
+
const isMin = n === min;
|
|
29147
|
+
const isMax = n === max;
|
|
29148
|
+
const shouldRender = isOnStep && !isNegativeOne && !isMin && !isMax;
|
|
29149
|
+
return shouldRender ? `${n}` : "";
|
|
29150
|
+
};
|
|
29151
|
+
|
|
29152
|
+
/**
|
|
29153
|
+
* axisOptions determine axis options for Mafs
|
|
29154
|
+
*
|
|
29155
|
+
* axisIndex is for grabbing data in an array that contains
|
|
29156
|
+
* data for multiple axes. For example range: [[-10, 10], [-10, 10]]
|
|
29157
|
+
* range[0] is data for the x axis and range[1] is data for the y axis
|
|
29158
|
+
*
|
|
29159
|
+
* @param {GridProps} props
|
|
29160
|
+
* @param {number} axisIndex which axis we're getting options for
|
|
29161
|
+
*/
|
|
29162
|
+
const axisOptions = (props, axisIndex) => {
|
|
29163
|
+
const axisStep = props.tickStep[axisIndex];
|
|
29164
|
+
const axisRange = props.range[axisIndex];
|
|
29165
|
+
return {
|
|
29166
|
+
axis: props.markings === "graph",
|
|
29167
|
+
lines: props.gridStep[axisIndex],
|
|
29168
|
+
labels: n => lineLabelText(n, axisStep, axisRange)
|
|
29169
|
+
};
|
|
29170
|
+
};
|
|
29171
|
+
const Grid = props => {
|
|
29172
|
+
return props.markings === "none" ? null : /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Coordinates.Cartesian, {
|
|
29173
|
+
xAxis: axisOptions(props, 0),
|
|
29174
|
+
yAxis: axisOptions(props, 1)
|
|
29175
|
+
}), /*#__PURE__*/React__namespace.createElement(AxisTicks, {
|
|
29176
|
+
range: props.range,
|
|
29177
|
+
tickStep: props.tickStep
|
|
29178
|
+
}), props.markings === "graph" && /*#__PURE__*/React__namespace.createElement(AxisArrows, null));
|
|
29028
29179
|
};
|
|
29029
|
-
const axisOptions = (props, index) => ({
|
|
29030
|
-
axis: props.markings === "graph",
|
|
29031
|
-
lines: props.step[index],
|
|
29032
|
-
subdivisions: props.step[index] / props.gridStep[index],
|
|
29033
|
-
labels: n => renderLineLabel(n, props.range[index]) ? n : ""
|
|
29034
|
-
});
|
|
29035
|
-
const Grid = props => props.markings === "none" ? null : /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Coordinates.Cartesian, {
|
|
29036
|
-
xAxis: axisOptions(props, 0),
|
|
29037
|
-
yAxis: axisOptions(props, 1)
|
|
29038
|
-
}), props.markings === "graph" && /*#__PURE__*/React__namespace.createElement(AxisArrows, null));
|
|
29039
29180
|
|
|
29040
29181
|
// Displays a stylized open eye: lint warnings are visible
|
|
29041
29182
|
const VisibleIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
|
|
@@ -29743,6 +29884,10 @@ function interactiveGraphReducer(state, action) {
|
|
|
29743
29884
|
return doMoveAll(state, action);
|
|
29744
29885
|
case MOVE_POINT:
|
|
29745
29886
|
return doMovePoint(state, action);
|
|
29887
|
+
case CHANGE_SNAP_STEP:
|
|
29888
|
+
return doChangeSnapStep(state, action);
|
|
29889
|
+
case CHANGE_RANGE:
|
|
29890
|
+
return doChangeRange(state, action);
|
|
29746
29891
|
default:
|
|
29747
29892
|
throw new wonderStuffCore.UnreachableCaseError(action);
|
|
29748
29893
|
}
|
|
@@ -29764,14 +29909,11 @@ function doMoveControlPoint(state, action) {
|
|
|
29764
29909
|
update: tuple => setAtIndex({
|
|
29765
29910
|
array: tuple,
|
|
29766
29911
|
index: action.pointIndex,
|
|
29767
|
-
newValue: snap({
|
|
29912
|
+
newValue: snap(snapStep, bound$1({
|
|
29768
29913
|
snapStep,
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
point: action.destination
|
|
29773
|
-
})
|
|
29774
|
-
})
|
|
29914
|
+
range,
|
|
29915
|
+
point: action.destination
|
|
29916
|
+
}))
|
|
29775
29917
|
})
|
|
29776
29918
|
});
|
|
29777
29919
|
const coordsToCheck = newCoords[action.itemIndex];
|
|
@@ -29815,13 +29957,7 @@ function doMoveLine(state, action) {
|
|
|
29815
29957
|
snapStep,
|
|
29816
29958
|
range
|
|
29817
29959
|
});
|
|
29818
|
-
const newLine = [snap(
|
|
29819
|
-
snapStep,
|
|
29820
|
-
point: mafs.vec.add(currentLine[0], change)
|
|
29821
|
-
}), snap({
|
|
29822
|
-
snapStep,
|
|
29823
|
-
point: mafs.vec.add(currentLine[1], change)
|
|
29824
|
-
})];
|
|
29960
|
+
const newLine = [snap(snapStep, mafs.vec.add(currentLine[0], change)), snap(snapStep, mafs.vec.add(currentLine[1], change))];
|
|
29825
29961
|
const newCoords = setAtIndex({
|
|
29826
29962
|
array: state.coords,
|
|
29827
29963
|
index: action.itemIndex,
|
|
@@ -29852,10 +29988,7 @@ function doMoveAll(state, action) {
|
|
|
29852
29988
|
snapStep,
|
|
29853
29989
|
range
|
|
29854
29990
|
});
|
|
29855
|
-
const newCoords = state.coords.map(point => snap(
|
|
29856
|
-
snapStep,
|
|
29857
|
-
point: mafs.vec.add(point, change)
|
|
29858
|
-
}));
|
|
29991
|
+
const newCoords = state.coords.map(point => snap(snapStep, mafs.vec.add(point, change)));
|
|
29859
29992
|
return {
|
|
29860
29993
|
...state,
|
|
29861
29994
|
hasBeenInteractedWith: true,
|
|
@@ -29878,14 +30011,11 @@ function doMovePoint(state, action) {
|
|
|
29878
30011
|
coords: setAtIndex({
|
|
29879
30012
|
array: state.coords,
|
|
29880
30013
|
index: action.index,
|
|
29881
|
-
newValue: snap({
|
|
30014
|
+
newValue: snap(state.snapStep, bound$1({
|
|
29882
30015
|
snapStep: state.snapStep,
|
|
29883
|
-
|
|
29884
|
-
|
|
29885
|
-
|
|
29886
|
-
point: action.destination
|
|
29887
|
-
})
|
|
29888
|
-
})
|
|
30016
|
+
range: state.range,
|
|
30017
|
+
point: action.destination
|
|
30018
|
+
}))
|
|
29889
30019
|
})
|
|
29890
30020
|
};
|
|
29891
30021
|
}
|
|
@@ -29893,6 +30023,28 @@ function doMovePoint(state, action) {
|
|
|
29893
30023
|
throw new Error("The movePoint action is only for point and polygon graphs");
|
|
29894
30024
|
}
|
|
29895
30025
|
}
|
|
30026
|
+
function doChangeSnapStep(state, action) {
|
|
30027
|
+
if (
|
|
30028
|
+
// Deep equality check since these are arrays
|
|
30029
|
+
___default["default"].isEqual(state.snapStep, action.snapStep)) {
|
|
30030
|
+
return state;
|
|
30031
|
+
}
|
|
30032
|
+
return {
|
|
30033
|
+
...state,
|
|
30034
|
+
snapStep: action.snapStep
|
|
30035
|
+
};
|
|
30036
|
+
}
|
|
30037
|
+
function doChangeRange(state, action) {
|
|
30038
|
+
if (
|
|
30039
|
+
// Deep equality check since these are arrays
|
|
30040
|
+
___default["default"].isEqual(state.range, action.range)) {
|
|
30041
|
+
return state;
|
|
30042
|
+
}
|
|
30043
|
+
return {
|
|
30044
|
+
...state,
|
|
30045
|
+
range: action.range
|
|
30046
|
+
};
|
|
30047
|
+
}
|
|
29896
30048
|
const getChange = (coords, delta, constraintOpts) => {
|
|
29897
30049
|
const [deltaX, deltaY] = delta;
|
|
29898
30050
|
const maxMoves = coords.map(point => maxMove({
|
|
@@ -29911,24 +30063,14 @@ const getChange = (coords, delta, constraintOpts) => {
|
|
|
29911
30063
|
const dy = clamp(deltaY, minYMove, maxYMove);
|
|
29912
30064
|
return [dx, dy];
|
|
29913
30065
|
};
|
|
29914
|
-
function snap(_ref) {
|
|
29915
|
-
let {
|
|
29916
|
-
snapStep,
|
|
29917
|
-
point
|
|
29918
|
-
} = _ref;
|
|
29919
|
-
const [requestedX, requestedY] = point;
|
|
29920
|
-
const [snapX, snapY] = snapStep;
|
|
29921
|
-
return [Math.round(requestedX / snapX) * snapX, Math.round(requestedY / snapY) * snapY];
|
|
29922
|
-
}
|
|
29923
|
-
|
|
29924
30066
|
// Returns the closest point to the given `point` that is within the graph
|
|
29925
30067
|
// bounds given in `state`.
|
|
29926
|
-
function bound$1(
|
|
30068
|
+
function bound$1(_ref) {
|
|
29927
30069
|
let {
|
|
29928
30070
|
snapStep,
|
|
29929
30071
|
range,
|
|
29930
30072
|
point
|
|
29931
|
-
} =
|
|
30073
|
+
} = _ref;
|
|
29932
30074
|
const [requestedX, requestedY] = point;
|
|
29933
30075
|
const [snapX, snapY] = snapStep;
|
|
29934
30076
|
const [[minX, maxX], [minY, maxY]] = range;
|
|
@@ -29936,12 +30078,12 @@ function bound$1(_ref2) {
|
|
|
29936
30078
|
}
|
|
29937
30079
|
|
|
29938
30080
|
// Returns the vector from the given point to the top-right corner of the graph
|
|
29939
|
-
function maxMove(
|
|
30081
|
+
function maxMove(_ref2) {
|
|
29940
30082
|
let {
|
|
29941
30083
|
snapStep,
|
|
29942
30084
|
range,
|
|
29943
30085
|
point
|
|
29944
|
-
} =
|
|
30086
|
+
} = _ref2;
|
|
29945
30087
|
const topRight = bound$1({
|
|
29946
30088
|
snapStep,
|
|
29947
30089
|
range,
|
|
@@ -29952,12 +30094,12 @@ function maxMove(_ref3) {
|
|
|
29952
30094
|
|
|
29953
30095
|
// Returns the vector from the given point to the bottom-left corner of the
|
|
29954
30096
|
// graph
|
|
29955
|
-
function minMove(
|
|
30097
|
+
function minMove(_ref3) {
|
|
29956
30098
|
let {
|
|
29957
30099
|
snapStep,
|
|
29958
30100
|
range,
|
|
29959
30101
|
point
|
|
29960
|
-
} =
|
|
30102
|
+
} = _ref3;
|
|
29961
30103
|
const bottomLeft = bound$1({
|
|
29962
30104
|
snapStep,
|
|
29963
30105
|
range,
|
|
@@ -30282,6 +30424,18 @@ const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
|
30282
30424
|
}
|
|
30283
30425
|
prevState.current = state;
|
|
30284
30426
|
}, [props, state]);
|
|
30427
|
+
|
|
30428
|
+
// Destructuring first to keep useEffect from making excess calls
|
|
30429
|
+
const [xSnap, ySnap] = props.snapStep;
|
|
30430
|
+
React.useEffect(() => {
|
|
30431
|
+
dispatch(changeSnapStep([xSnap, ySnap]));
|
|
30432
|
+
}, [xSnap, ySnap]);
|
|
30433
|
+
|
|
30434
|
+
// Destructuring first to keep useEffect from making excess calls
|
|
30435
|
+
const [[xMinRange, xMaxRange], [yMinRange, yMaxRange]] = props.range;
|
|
30436
|
+
React.useEffect(() => {
|
|
30437
|
+
dispatch(changeRange([[xMinRange, xMaxRange], [yMinRange, yMaxRange]]));
|
|
30438
|
+
}, [xMinRange, xMaxRange, yMinRange, yMaxRange]);
|
|
30285
30439
|
React__namespace.useImperativeHandle(ref, () => ({
|
|
30286
30440
|
getUserInput: () => getGradableGraph(state, props.graph)
|
|
30287
30441
|
}));
|
|
@@ -30316,7 +30470,13 @@ const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
|
30316
30470
|
zoom: false,
|
|
30317
30471
|
width: width,
|
|
30318
30472
|
height: height
|
|
30319
|
-
}, /*#__PURE__*/React__namespace.createElement(SvgDefs, null), /*#__PURE__*/React__namespace.createElement(Grid,
|
|
30473
|
+
}, /*#__PURE__*/React__namespace.createElement(SvgDefs, null), /*#__PURE__*/React__namespace.createElement(Grid, {
|
|
30474
|
+
tickStep: props.step,
|
|
30475
|
+
gridStep: props.gridStep,
|
|
30476
|
+
range: props.range,
|
|
30477
|
+
containerSizeClass: props.containerSizeClass,
|
|
30478
|
+
markings: props.markings
|
|
30479
|
+
}), props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLayer, {
|
|
30320
30480
|
lockedFigures: props.lockedFigures
|
|
30321
30481
|
}), renderGraph({
|
|
30322
30482
|
state,
|
|
@@ -32066,8 +32226,8 @@ class InteractiveGraph extends React__namespace.Component {
|
|
|
32066
32226
|
};
|
|
32067
32227
|
}
|
|
32068
32228
|
} else if (userInput.type === "segment" && rubric.correct.type === "segment" && userInput.coords != null) {
|
|
32069
|
-
let guess = userInput.coords
|
|
32070
|
-
let correct = rubric.correct
|
|
32229
|
+
let guess = Util.deepClone(userInput.coords);
|
|
32230
|
+
let correct = Util.deepClone(rubric.correct?.coords);
|
|
32071
32231
|
guess = ___default["default"].invoke(guess, "sort").sort();
|
|
32072
32232
|
// @ts-expect-error - TS2345 - Argument of type '(readonly Coord[])[] | undefined' is not assignable to parameter of type 'Collection<any>'.
|
|
32073
32233
|
correct = ___default["default"].invoke(correct, "sort").sort();
|
|
@@ -42329,7 +42489,7 @@ const init = function (options) {
|
|
|
42329
42489
|
|
|
42330
42490
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
42331
42491
|
const libName = "@khanacademy/perseus";
|
|
42332
|
-
const libVersion = "21.
|
|
42492
|
+
const libVersion = "21.2.0";
|
|
42333
42493
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
42334
42494
|
|
|
42335
42495
|
const apiVersion = {
|
|
@@ -43458,6 +43618,9 @@ const ItemExtras = [
|
|
|
43458
43618
|
// A background image applied to various widgets.
|
|
43459
43619
|
|
|
43460
43620
|
const PerseusExpressionAnswerFormConsidered = ["correct", "wrong", "ungraded"];
|
|
43621
|
+
|
|
43622
|
+
// 2D range: xMin, xMax, yMin, yMax
|
|
43623
|
+
|
|
43461
43624
|
const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
|
|
43462
43625
|
|
|
43463
43626
|
/**
|