@khanacademy/perseus 22.1.0 → 22.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.css +1 -0
- package/dist/es/index.js +186 -171
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.js +185 -170
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graphs/graph-locked-layer.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/components/vector.d.ts +2 -1
- package/dist/widgets/interactive-graphs/locked-line.d.ts +5 -1
- package/package.json +4 -4
package/dist/es/index.css
CHANGED
|
@@ -4172,6 +4172,7 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4172
4172
|
|
|
4173
4173
|
--mafs-origin-color: var(--mafs-fg);
|
|
4174
4174
|
--mafs-line-color: #555;
|
|
4175
|
+
--mafs-line-stroke-dash-style: 4, 3;
|
|
4175
4176
|
--grid-line-subdivision-color: #222;
|
|
4176
4177
|
|
|
4177
4178
|
--mafs-red: #f11d0e;
|
package/dist/es/index.js
CHANGED
|
@@ -28677,6 +28677,163 @@ const lockedFigureColors = {
|
|
|
28677
28677
|
};
|
|
28678
28678
|
const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
|
|
28679
28679
|
|
|
28680
|
+
function pathBuilder() {
|
|
28681
|
+
return new PathBuilder();
|
|
28682
|
+
}
|
|
28683
|
+
class PathBuilder {
|
|
28684
|
+
constructor() {
|
|
28685
|
+
this.path = [];
|
|
28686
|
+
this.scaleFactor = 1;
|
|
28687
|
+
}
|
|
28688
|
+
build() {
|
|
28689
|
+
return this.path.map(scaleCommandBy(this.scaleFactor)).map(commandToString).join("");
|
|
28690
|
+
}
|
|
28691
|
+
|
|
28692
|
+
// add a move (M) command to the path
|
|
28693
|
+
move(x, y) {
|
|
28694
|
+
this.path.push({
|
|
28695
|
+
action: "M",
|
|
28696
|
+
coords: [x, y]
|
|
28697
|
+
});
|
|
28698
|
+
return this;
|
|
28699
|
+
}
|
|
28700
|
+
|
|
28701
|
+
// add a curve (C) command to the path
|
|
28702
|
+
curve(control1X, control1Y, control2X, control2Y, endX, endY) {
|
|
28703
|
+
this.path.push({
|
|
28704
|
+
action: "C",
|
|
28705
|
+
coords: [control1X, control1Y, control2X, control2Y, endX, endY]
|
|
28706
|
+
});
|
|
28707
|
+
return this;
|
|
28708
|
+
}
|
|
28709
|
+
|
|
28710
|
+
// Scale all coordinates of the path by a factor
|
|
28711
|
+
scale(factor) {
|
|
28712
|
+
this.scaleFactor *= factor;
|
|
28713
|
+
return this;
|
|
28714
|
+
}
|
|
28715
|
+
}
|
|
28716
|
+
function commandToString(command) {
|
|
28717
|
+
return `${command.action}${command.coords.join(" ")}`;
|
|
28718
|
+
}
|
|
28719
|
+
function scaleCommandBy(scaleFactor) {
|
|
28720
|
+
return command => _extends({}, command, {
|
|
28721
|
+
coords: command.coords.map(c => c * scaleFactor)
|
|
28722
|
+
});
|
|
28723
|
+
}
|
|
28724
|
+
|
|
28725
|
+
// We use the pathBuilder here to scale up the SVG path coordinates used
|
|
28726
|
+
// elsewhere for arrowheads. We scale in the path itself instead of using a CSS
|
|
28727
|
+
// transform because a transform would also scale up the stroke weight, and we
|
|
28728
|
+
// don't want that.
|
|
28729
|
+
const arrowPath = pathBuilder().move(-3, 4).curve(-2.75, 2.5, 0, 0.25, 0.75, 0).curve(0, -0.25, -2.75, -2.5, -3, -4).scale(1.4).build();
|
|
28730
|
+
function Arrowhead(props) {
|
|
28731
|
+
var _props$color;
|
|
28732
|
+
const [point] = useTransformVectorsToPixels(props.tip);
|
|
28733
|
+
return /*#__PURE__*/React.createElement("g", {
|
|
28734
|
+
transform: `translate(${point[0]} ${point[1]}) rotate(${-props.angle})`
|
|
28735
|
+
}, /*#__PURE__*/React.createElement("g", {
|
|
28736
|
+
transform: "translate(-1.5)"
|
|
28737
|
+
}, /*#__PURE__*/React.createElement("path", {
|
|
28738
|
+
d: arrowPath,
|
|
28739
|
+
fill: "none",
|
|
28740
|
+
style: {
|
|
28741
|
+
stroke: (_props$color = props.color) != null ? _props$color : "inherit"
|
|
28742
|
+
},
|
|
28743
|
+
strokeLinejoin: "round",
|
|
28744
|
+
strokeLinecap: "round"
|
|
28745
|
+
})));
|
|
28746
|
+
}
|
|
28747
|
+
|
|
28748
|
+
function SVGLine(props) {
|
|
28749
|
+
const {
|
|
28750
|
+
start,
|
|
28751
|
+
end,
|
|
28752
|
+
style,
|
|
28753
|
+
className,
|
|
28754
|
+
testId
|
|
28755
|
+
} = props;
|
|
28756
|
+
return /*#__PURE__*/React.createElement("line", {
|
|
28757
|
+
x1: start[0],
|
|
28758
|
+
y1: start[1],
|
|
28759
|
+
x2: end[0],
|
|
28760
|
+
y2: end[1],
|
|
28761
|
+
style: style,
|
|
28762
|
+
className: className,
|
|
28763
|
+
"data-testid": testId
|
|
28764
|
+
});
|
|
28765
|
+
}
|
|
28766
|
+
|
|
28767
|
+
function Vector(props) {
|
|
28768
|
+
const {
|
|
28769
|
+
tail,
|
|
28770
|
+
tip,
|
|
28771
|
+
color,
|
|
28772
|
+
style
|
|
28773
|
+
} = props;
|
|
28774
|
+
const [tailPx, tipPx] = useTransformVectorsToPixels(tail, tip);
|
|
28775
|
+
const direction = vec.sub(tip, tail);
|
|
28776
|
+
return /*#__PURE__*/React.createElement("g", {
|
|
28777
|
+
style: {
|
|
28778
|
+
stroke: color,
|
|
28779
|
+
strokeWidth: 2
|
|
28780
|
+
}
|
|
28781
|
+
}, /*#__PURE__*/React.createElement(SVGLine, {
|
|
28782
|
+
start: tailPx,
|
|
28783
|
+
end: tipPx,
|
|
28784
|
+
style: style
|
|
28785
|
+
}), /*#__PURE__*/React.createElement(Arrowhead, {
|
|
28786
|
+
tip: tip,
|
|
28787
|
+
angle: angleDegrees(direction)
|
|
28788
|
+
}));
|
|
28789
|
+
}
|
|
28790
|
+
function angleDegrees([x, y]) {
|
|
28791
|
+
return Math.atan2(y, x) * 180 / Math.PI;
|
|
28792
|
+
}
|
|
28793
|
+
|
|
28794
|
+
/**
|
|
28795
|
+
* Given a ray and a rectangular box, find the point where the ray intersects
|
|
28796
|
+
* the edge of the box. Assumes the `initialPoint` is inside the box.
|
|
28797
|
+
* @param initialPoint - The starting point of the ray.
|
|
28798
|
+
* @param throughPoint - A point that the ray passes through. Must be different from initialPoint.
|
|
28799
|
+
* @param box - The box with which to intersect the ray, in the form [[xMin, xMax], [yMin, yMax]]
|
|
28800
|
+
*/
|
|
28801
|
+
const getIntersectionOfRayWithBox = (initialPoint, throughPoint, box) => {
|
|
28802
|
+
const [[xMin, xMax], [yMin, yMax]] = box;
|
|
28803
|
+
const [aX, aY] = throughPoint;
|
|
28804
|
+
const [bX, bY] = initialPoint;
|
|
28805
|
+
const yDiff = bY - aY;
|
|
28806
|
+
const xDiff = bX - aX;
|
|
28807
|
+
const slope = yDiff / xDiff;
|
|
28808
|
+
const yAtXMin = slope * (xMin - aX) + aY;
|
|
28809
|
+
const yAtXMax = slope * (xMax - aX) + aY;
|
|
28810
|
+
const xAtYMin = (yMin - aY) / slope + aX;
|
|
28811
|
+
const xAtYMax = (yMax - aY) / slope + aX;
|
|
28812
|
+
|
|
28813
|
+
// clock analogy to describe quadrants
|
|
28814
|
+
switch (true) {
|
|
28815
|
+
// 12 o'clock to 2:59
|
|
28816
|
+
case yDiff > 0 && xDiff >= 0:
|
|
28817
|
+
return xAtYMax > xMax ? [xMax, yAtXMax] : [xAtYMax, yMax];
|
|
28818
|
+
// 3 o'clock to 5:59
|
|
28819
|
+
case yDiff <= 0 && xDiff > 0:
|
|
28820
|
+
// xAtYMin evaluates to -Infinity here, so we use absolute value
|
|
28821
|
+
return Math.abs(xAtYMin) > xMax ? [xMax, yAtXMax] : [xAtYMin, yMin];
|
|
28822
|
+
// 9 o'clock to 11:59
|
|
28823
|
+
case yDiff >= 0 && xDiff < 0:
|
|
28824
|
+
return xAtYMax < xMin ? [xMin, yAtXMin] : [xAtYMax, yMax];
|
|
28825
|
+
// 6 o'clock to 8:59
|
|
28826
|
+
case yDiff < 0 && xDiff <= 0:
|
|
28827
|
+
return xAtYMin < xMin ? [xMin, yAtXMin] : [xAtYMin, yMin];
|
|
28828
|
+
default:
|
|
28829
|
+
return [xMax, yAtXMax];
|
|
28830
|
+
}
|
|
28831
|
+
};
|
|
28832
|
+
const getLines = points => points.map((point, i) => {
|
|
28833
|
+
const next = points[(i + 1) % points.length];
|
|
28834
|
+
return [point, next];
|
|
28835
|
+
});
|
|
28836
|
+
|
|
28680
28837
|
const LockedLine = props => {
|
|
28681
28838
|
const {
|
|
28682
28839
|
color: color$1,
|
|
@@ -28684,11 +28841,27 @@ const LockedLine = props => {
|
|
|
28684
28841
|
kind,
|
|
28685
28842
|
points,
|
|
28686
28843
|
showStartPoint,
|
|
28687
|
-
showEndPoint
|
|
28844
|
+
showEndPoint,
|
|
28845
|
+
range
|
|
28688
28846
|
} = props;
|
|
28689
28847
|
const [point1, point2] = points;
|
|
28690
28848
|
let line;
|
|
28691
|
-
if (kind === "
|
|
28849
|
+
if (kind === "ray") {
|
|
28850
|
+
// Rays extend to the end of the graph in one direction.
|
|
28851
|
+
const endExtend = getIntersectionOfRayWithBox(point2.coord, point1.coord, range);
|
|
28852
|
+
line = /*#__PURE__*/React.createElement(Vector, {
|
|
28853
|
+
tail: point1.coord,
|
|
28854
|
+
tip: endExtend,
|
|
28855
|
+
color: lockedFigureColors[color$1],
|
|
28856
|
+
style: {
|
|
28857
|
+
strokeDasharray: lineStyle === "dashed" ?
|
|
28858
|
+
// TODO(lems-1930): Uncomment this line when the
|
|
28859
|
+
// dashed style is updated in Mafs.
|
|
28860
|
+
// ? "var(--mafs-line-stroke-dash-style)"
|
|
28861
|
+
"4, 3" : undefined
|
|
28862
|
+
}
|
|
28863
|
+
});
|
|
28864
|
+
} else {
|
|
28692
28865
|
const LineType = kind === "segment" ? Line$3.Segment : Line$3.ThroughPoints;
|
|
28693
28866
|
line = /*#__PURE__*/React.createElement(LineType, {
|
|
28694
28867
|
point1: point1.coord,
|
|
@@ -28696,12 +28869,9 @@ const LockedLine = props => {
|
|
|
28696
28869
|
color: lockedFigureColors[color$1],
|
|
28697
28870
|
style: lineStyle
|
|
28698
28871
|
});
|
|
28699
|
-
} else {
|
|
28700
|
-
// TODO(LEMS-1928): Implement rays
|
|
28701
|
-
return null;
|
|
28702
28872
|
}
|
|
28703
28873
|
return /*#__PURE__*/React.createElement("g", {
|
|
28704
|
-
className: "locked-line"
|
|
28874
|
+
className: kind === "ray" ? "locked-ray" : "locked-line"
|
|
28705
28875
|
}, line, showStartPoint && /*#__PURE__*/React.createElement(Point$2, {
|
|
28706
28876
|
x: point1.coord[0],
|
|
28707
28877
|
y: point1.coord[1],
|
|
@@ -28750,14 +28920,16 @@ const GraphLockedLayer = props => {
|
|
|
28750
28920
|
lockedFigures
|
|
28751
28921
|
} = props;
|
|
28752
28922
|
return /*#__PURE__*/React.createElement(React.Fragment, null, lockedFigures.map((figure, index) => {
|
|
28753
|
-
let Figure;
|
|
28754
28923
|
switch (figure.type) {
|
|
28755
28924
|
case "point":
|
|
28756
|
-
|
|
28757
|
-
|
|
28925
|
+
return /*#__PURE__*/React.createElement(LockedPoint, _extends({
|
|
28926
|
+
key: `point-${index}`
|
|
28927
|
+
}, figure));
|
|
28758
28928
|
case "line":
|
|
28759
|
-
|
|
28760
|
-
|
|
28929
|
+
return /*#__PURE__*/React.createElement(LockedLine, _extends({
|
|
28930
|
+
key: `line-${index}`,
|
|
28931
|
+
range: props.range
|
|
28932
|
+
}, figure));
|
|
28761
28933
|
default:
|
|
28762
28934
|
/**
|
|
28763
28935
|
* Devlopment-time future-proofing: This should
|
|
@@ -28767,9 +28939,6 @@ const GraphLockedLayer = props => {
|
|
|
28767
28939
|
*/
|
|
28768
28940
|
throw new UnreachableCaseError(figure);
|
|
28769
28941
|
}
|
|
28770
|
-
return /*#__PURE__*/React.createElement(Figure, _extends({
|
|
28771
|
-
key: `${figure.type}-${index}`
|
|
28772
|
-
}, figure));
|
|
28773
28942
|
}));
|
|
28774
28943
|
};
|
|
28775
28944
|
|
|
@@ -28851,161 +29020,6 @@ function snap(snapStep, point) {
|
|
|
28851
29020
|
return [Math.round(requestedX / snapX) * snapX, Math.round(requestedY / snapY) * snapY];
|
|
28852
29021
|
}
|
|
28853
29022
|
|
|
28854
|
-
/**
|
|
28855
|
-
* Given a ray and a rectangular box, find the point where the ray intersects
|
|
28856
|
-
* the edge of the box. Assumes the `initialPoint` is inside the box.
|
|
28857
|
-
* @param initialPoint - The starting point of the ray.
|
|
28858
|
-
* @param throughPoint - A point that the ray passes through. Must be different from initialPoint.
|
|
28859
|
-
* @param box - The box with which to intersect the ray, in the form [[xMin, xMax], [yMin, yMax]]
|
|
28860
|
-
*/
|
|
28861
|
-
const getIntersectionOfRayWithBox = (initialPoint, throughPoint, box) => {
|
|
28862
|
-
const [[xMin, xMax], [yMin, yMax]] = box;
|
|
28863
|
-
const [aX, aY] = throughPoint;
|
|
28864
|
-
const [bX, bY] = initialPoint;
|
|
28865
|
-
const yDiff = bY - aY;
|
|
28866
|
-
const xDiff = bX - aX;
|
|
28867
|
-
const slope = yDiff / xDiff;
|
|
28868
|
-
const yAtXMin = slope * (xMin - aX) + aY;
|
|
28869
|
-
const yAtXMax = slope * (xMax - aX) + aY;
|
|
28870
|
-
const xAtYMin = (yMin - aY) / slope + aX;
|
|
28871
|
-
const xAtYMax = (yMax - aY) / slope + aX;
|
|
28872
|
-
|
|
28873
|
-
// clock analogy to describe quadrants
|
|
28874
|
-
switch (true) {
|
|
28875
|
-
// 12 o'clock to 2:59
|
|
28876
|
-
case yDiff > 0 && xDiff >= 0:
|
|
28877
|
-
return xAtYMax > xMax ? [xMax, yAtXMax] : [xAtYMax, yMax];
|
|
28878
|
-
// 3 o'clock to 5:59
|
|
28879
|
-
case yDiff <= 0 && xDiff > 0:
|
|
28880
|
-
// xAtYMin evaluates to -Infinity here, so we use absolute value
|
|
28881
|
-
return Math.abs(xAtYMin) > xMax ? [xMax, yAtXMax] : [xAtYMin, yMin];
|
|
28882
|
-
// 9 o'clock to 11:59
|
|
28883
|
-
case yDiff >= 0 && xDiff < 0:
|
|
28884
|
-
return xAtYMax < xMin ? [xMin, yAtXMin] : [xAtYMax, yMax];
|
|
28885
|
-
// 6 o'clock to 8:59
|
|
28886
|
-
case yDiff < 0 && xDiff <= 0:
|
|
28887
|
-
return xAtYMin < xMin ? [xMin, yAtXMin] : [xAtYMin, yMin];
|
|
28888
|
-
default:
|
|
28889
|
-
return [xMax, yAtXMax];
|
|
28890
|
-
}
|
|
28891
|
-
};
|
|
28892
|
-
const getLines = points => points.map((point, i) => {
|
|
28893
|
-
const next = points[(i + 1) % points.length];
|
|
28894
|
-
return [point, next];
|
|
28895
|
-
});
|
|
28896
|
-
|
|
28897
|
-
function SVGLine(props) {
|
|
28898
|
-
const {
|
|
28899
|
-
start,
|
|
28900
|
-
end,
|
|
28901
|
-
style,
|
|
28902
|
-
className,
|
|
28903
|
-
testId
|
|
28904
|
-
} = props;
|
|
28905
|
-
return /*#__PURE__*/React.createElement("line", {
|
|
28906
|
-
x1: start[0],
|
|
28907
|
-
y1: start[1],
|
|
28908
|
-
x2: end[0],
|
|
28909
|
-
y2: end[1],
|
|
28910
|
-
style: style,
|
|
28911
|
-
className: `${className}`,
|
|
28912
|
-
"data-testid": testId
|
|
28913
|
-
});
|
|
28914
|
-
}
|
|
28915
|
-
|
|
28916
|
-
function pathBuilder() {
|
|
28917
|
-
return new PathBuilder();
|
|
28918
|
-
}
|
|
28919
|
-
class PathBuilder {
|
|
28920
|
-
constructor() {
|
|
28921
|
-
this.path = [];
|
|
28922
|
-
this.scaleFactor = 1;
|
|
28923
|
-
}
|
|
28924
|
-
build() {
|
|
28925
|
-
return this.path.map(scaleCommandBy(this.scaleFactor)).map(commandToString).join("");
|
|
28926
|
-
}
|
|
28927
|
-
|
|
28928
|
-
// add a move (M) command to the path
|
|
28929
|
-
move(x, y) {
|
|
28930
|
-
this.path.push({
|
|
28931
|
-
action: "M",
|
|
28932
|
-
coords: [x, y]
|
|
28933
|
-
});
|
|
28934
|
-
return this;
|
|
28935
|
-
}
|
|
28936
|
-
|
|
28937
|
-
// add a curve (C) command to the path
|
|
28938
|
-
curve(control1X, control1Y, control2X, control2Y, endX, endY) {
|
|
28939
|
-
this.path.push({
|
|
28940
|
-
action: "C",
|
|
28941
|
-
coords: [control1X, control1Y, control2X, control2Y, endX, endY]
|
|
28942
|
-
});
|
|
28943
|
-
return this;
|
|
28944
|
-
}
|
|
28945
|
-
|
|
28946
|
-
// Scale all coordinates of the path by a factor
|
|
28947
|
-
scale(factor) {
|
|
28948
|
-
this.scaleFactor *= factor;
|
|
28949
|
-
return this;
|
|
28950
|
-
}
|
|
28951
|
-
}
|
|
28952
|
-
function commandToString(command) {
|
|
28953
|
-
return `${command.action}${command.coords.join(" ")}`;
|
|
28954
|
-
}
|
|
28955
|
-
function scaleCommandBy(scaleFactor) {
|
|
28956
|
-
return command => _extends({}, command, {
|
|
28957
|
-
coords: command.coords.map(c => c * scaleFactor)
|
|
28958
|
-
});
|
|
28959
|
-
}
|
|
28960
|
-
|
|
28961
|
-
// We use the pathBuilder here to scale up the SVG path coordinates used
|
|
28962
|
-
// elsewhere for arrowheads. We scale in the path itself instead of using a CSS
|
|
28963
|
-
// transform because a transform would also scale up the stroke weight, and we
|
|
28964
|
-
// don't want that.
|
|
28965
|
-
const arrowPath = pathBuilder().move(-3, 4).curve(-2.75, 2.5, 0, 0.25, 0.75, 0).curve(0, -0.25, -2.75, -2.5, -3, -4).scale(1.4).build();
|
|
28966
|
-
function Arrowhead(props) {
|
|
28967
|
-
var _props$color;
|
|
28968
|
-
const [point] = useTransformVectorsToPixels(props.tip);
|
|
28969
|
-
return /*#__PURE__*/React.createElement("g", {
|
|
28970
|
-
transform: `translate(${point[0]} ${point[1]}) rotate(${-props.angle})`
|
|
28971
|
-
}, /*#__PURE__*/React.createElement("g", {
|
|
28972
|
-
transform: "translate(-1.5)"
|
|
28973
|
-
}, /*#__PURE__*/React.createElement("path", {
|
|
28974
|
-
d: arrowPath,
|
|
28975
|
-
fill: "none",
|
|
28976
|
-
style: {
|
|
28977
|
-
stroke: (_props$color = props.color) != null ? _props$color : "inherit"
|
|
28978
|
-
},
|
|
28979
|
-
strokeLinejoin: "round",
|
|
28980
|
-
strokeLinecap: "round"
|
|
28981
|
-
})));
|
|
28982
|
-
}
|
|
28983
|
-
|
|
28984
|
-
function Vector(props) {
|
|
28985
|
-
const {
|
|
28986
|
-
tail,
|
|
28987
|
-
tip,
|
|
28988
|
-
color
|
|
28989
|
-
} = props;
|
|
28990
|
-
const [tailPx, tipPx] = useTransformVectorsToPixels(tail, tip);
|
|
28991
|
-
const direction = vec.sub(tip, tail);
|
|
28992
|
-
return /*#__PURE__*/React.createElement("g", {
|
|
28993
|
-
style: {
|
|
28994
|
-
stroke: color,
|
|
28995
|
-
strokeWidth: 2
|
|
28996
|
-
}
|
|
28997
|
-
}, /*#__PURE__*/React.createElement(SVGLine, {
|
|
28998
|
-
start: tailPx,
|
|
28999
|
-
end: tipPx
|
|
29000
|
-
}), /*#__PURE__*/React.createElement(Arrowhead, {
|
|
29001
|
-
tip: tip,
|
|
29002
|
-
angle: angleDegrees(direction)
|
|
29003
|
-
}));
|
|
29004
|
-
}
|
|
29005
|
-
function angleDegrees([x, y]) {
|
|
29006
|
-
return Math.atan2(y, x) * 180 / Math.PI;
|
|
29007
|
-
}
|
|
29008
|
-
|
|
29009
29023
|
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
29010
29024
|
const MovableLine = props => {
|
|
29011
29025
|
const {
|
|
@@ -30953,7 +30967,8 @@ const MafsGraph = props => {
|
|
|
30953
30967
|
containerSizeClass: props.containerSizeClass,
|
|
30954
30968
|
markings: props.markings
|
|
30955
30969
|
}), props.lockedFigures && /*#__PURE__*/React.createElement(GraphLockedLayer, {
|
|
30956
|
-
lockedFigures: props.lockedFigures
|
|
30970
|
+
lockedFigures: props.lockedFigures,
|
|
30971
|
+
range: props.range
|
|
30957
30972
|
}), renderGraph({
|
|
30958
30973
|
state,
|
|
30959
30974
|
dispatch
|
|
@@ -43054,7 +43069,7 @@ const init = function init(options) {
|
|
|
43054
43069
|
|
|
43055
43070
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
43056
43071
|
const libName = "@khanacademy/perseus";
|
|
43057
|
-
const libVersion = "22.
|
|
43072
|
+
const libVersion = "22.2.0";
|
|
43058
43073
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
43059
43074
|
|
|
43060
43075
|
const apiVersion = {
|