@khanacademy/perseus 22.0.1 → 22.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/info-tip/info-tip.d.ts +2 -10
- package/dist/components/math-input.d.ts +1 -0
- package/dist/es/index.css +14 -1
- package/dist/es/index.js +196 -160
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +14 -1
- package/dist/index.js +190 -152
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graph.d.ts +3 -3
- package/dist/widgets/interactive-graphs/axis-labels.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/components/arrowhead.d.ts +2 -2
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/use-transform.d.ts +9 -2
- package/dist/widgets/interactive-graphs/graphs/utils.d.ts +6 -4
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -0
- package/dist/widgets/interactive-graphs/reducer/use-graph-config.d.ts +4 -0
- package/package.json +2 -2
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
type Props = {
|
|
3
|
-
children: React.
|
|
3
|
+
children: string | React.ReactElement | React.ReactElement[];
|
|
4
4
|
};
|
|
5
|
-
|
|
6
|
-
hover: boolean;
|
|
7
|
-
};
|
|
8
|
-
declare class InfoTip extends React.Component<Props, State> {
|
|
9
|
-
state: State;
|
|
10
|
-
handleMouseEnter: () => void;
|
|
11
|
-
handleMouseLeave: () => void;
|
|
12
|
-
render(): React.ReactNode;
|
|
13
|
-
}
|
|
5
|
+
export declare const InfoTip: (props: Props) => JSX.Element;
|
|
14
6
|
export default InfoTip;
|
|
@@ -83,6 +83,7 @@ declare class MathInput extends React.Component<Props, State> {
|
|
|
83
83
|
}>;
|
|
84
84
|
context: React.ContextType<typeof MathInputI18nContext>;
|
|
85
85
|
inputRef: React.RefObject<InnerMathInput>;
|
|
86
|
+
blur(): void;
|
|
86
87
|
focus(): void;
|
|
87
88
|
insert(value: any): void;
|
|
88
89
|
render(): JSX.Element;
|
package/dist/es/index.css
CHANGED
|
@@ -2470,7 +2470,10 @@ img.zoom-img {
|
|
|
2470
2470
|
padding-top: 5px;
|
|
2471
2471
|
}
|
|
2472
2472
|
.framework-perseus .svg-image {
|
|
2473
|
-
display:
|
|
2473
|
+
display: block;
|
|
2474
|
+
margin: 0 auto;
|
|
2475
|
+
margin-inline-start: auto;
|
|
2476
|
+
margin-inline-end: auto;
|
|
2474
2477
|
}
|
|
2475
2478
|
.framework-perseus .unresponsive-svg-image,
|
|
2476
2479
|
.framework-perseus .perseus-rendered-radio .unresponsive-svg-image {
|
|
@@ -2750,6 +2753,16 @@ body.mobile .categorizer-container td.category input[type="radio"] + span:active
|
|
|
2750
2753
|
.perseus-image-editor .graph-settings {
|
|
2751
2754
|
margin-top: 5px;
|
|
2752
2755
|
}
|
|
2756
|
+
.perseus-image-widget {
|
|
2757
|
+
margin-inline-start: auto;
|
|
2758
|
+
margin-inline-end: auto;
|
|
2759
|
+
}
|
|
2760
|
+
.perseus-hint-renderer .perseus-image-widget {
|
|
2761
|
+
margin-inline-start: 0;
|
|
2762
|
+
}
|
|
2763
|
+
.perseus-hint-renderer .svg-image {
|
|
2764
|
+
margin-inline-start: 0;
|
|
2765
|
+
}
|
|
2753
2766
|
.perseus-widget-interactive-graph {
|
|
2754
2767
|
box-sizing: content-box;
|
|
2755
2768
|
padding: 25px 25px 0 0;
|
package/dist/es/index.js
CHANGED
|
@@ -29,10 +29,10 @@ import { OptionItem, SingleSelect, MultiSelect } from '@khanacademy/wonder-block
|
|
|
29
29
|
import caretDown from '@phosphor-icons/core/assets/regular/caret-down.svg';
|
|
30
30
|
import caretUp from '@phosphor-icons/core/assets/regular/caret-up.svg';
|
|
31
31
|
import debounce$2 from 'lodash.debounce';
|
|
32
|
-
import { Line as Line$3, Point as Point$2,
|
|
32
|
+
import { vec, Line as Line$3, Point as Point$2, useMovable, Text as Text$1, Polygon, Coordinates, Mafs } from 'mafs';
|
|
33
33
|
import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
|
|
34
|
+
import { Body, LabelSmall, LabelMedium } from '@khanacademy/wonder-blocks-typography';
|
|
34
35
|
import questionIcon from '@phosphor-icons/core/regular/question.svg';
|
|
35
|
-
import { LabelSmall, LabelMedium } from '@khanacademy/wonder-blocks-typography';
|
|
36
36
|
import createReactClass from 'create-react-class';
|
|
37
37
|
import Switch from '@khanacademy/wonder-blocks-switch';
|
|
38
38
|
import Pill from '@khanacademy/wonder-blocks-pill';
|
|
@@ -542,13 +542,17 @@ class MathInput extends React.Component {
|
|
|
542
542
|
super(...args);
|
|
543
543
|
this.inputRef = /*#__PURE__*/React.createRef();
|
|
544
544
|
}
|
|
545
|
-
|
|
545
|
+
blur() {
|
|
546
546
|
var _this$inputRef$curren;
|
|
547
|
-
(_this$inputRef$curren = this.inputRef.current) == null || _this$inputRef$curren.
|
|
547
|
+
(_this$inputRef$curren = this.inputRef.current) == null || _this$inputRef$curren.blur();
|
|
548
548
|
}
|
|
549
|
-
|
|
549
|
+
focus() {
|
|
550
550
|
var _this$inputRef$curren2;
|
|
551
|
-
(_this$inputRef$curren2 = this.inputRef.current) == null || _this$inputRef$curren2.
|
|
551
|
+
(_this$inputRef$curren2 = this.inputRef.current) == null || _this$inputRef$curren2.focus();
|
|
552
|
+
}
|
|
553
|
+
insert(value) {
|
|
554
|
+
var _this$inputRef$curren3;
|
|
555
|
+
(_this$inputRef$curren3 = this.inputRef.current) == null || _this$inputRef$curren3.insert(value);
|
|
552
556
|
}
|
|
553
557
|
render() {
|
|
554
558
|
return /*#__PURE__*/React.createElement(InnerMathInput, _extends({}, this.props, {
|
|
@@ -2323,7 +2327,12 @@ class Expression extends React.Component {
|
|
|
2323
2327
|
var _this$refs$input;
|
|
2324
2328
|
// eslint-disable-next-line react/no-string-refs
|
|
2325
2329
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
2326
|
-
(_this$refs$input = this.refs.input) == null
|
|
2330
|
+
if (typeof ((_this$refs$input = this.refs.input) == null ? void 0 : _this$refs$input.blur) === "function") {
|
|
2331
|
+
var _this$refs$input2;
|
|
2332
|
+
// eslint-disable-next-line react/no-string-refs
|
|
2333
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
2334
|
+
(_this$refs$input2 = this.refs.input) == null || _this$refs$input2.blur();
|
|
2335
|
+
}
|
|
2327
2336
|
};
|
|
2328
2337
|
this.getInputPaths = () => {
|
|
2329
2338
|
// The widget itself is an input, so we return a single empty list to
|
|
@@ -21720,10 +21729,15 @@ class SimpleKeypadInput extends React.Component {
|
|
|
21720
21729
|
|
|
21721
21730
|
blur() {
|
|
21722
21731
|
var _this$refs$input;
|
|
21732
|
+
// eslint-disable-next-line react/no-string-refs
|
|
21723
21733
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21724
|
-
(_this$refs$input = this.refs.input) == null
|
|
21734
|
+
if (typeof ((_this$refs$input = this.refs.input) == null ? void 0 : _this$refs$input.blur) === "function") {
|
|
21735
|
+
var _this$refs$input2;
|
|
21736
|
+
// eslint-disable-next-line react/no-string-refs
|
|
21737
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21738
|
+
(_this$refs$input2 = this.refs.input) == null || _this$refs$input2.blur();
|
|
21739
|
+
}
|
|
21725
21740
|
}
|
|
21726
|
-
|
|
21727
21741
|
getValue() {
|
|
21728
21742
|
return this.props.value;
|
|
21729
21743
|
}
|
|
@@ -21871,7 +21885,12 @@ class InputNumber extends React.Component {
|
|
|
21871
21885
|
var _this$refs$input;
|
|
21872
21886
|
// eslint-disable-next-line react/no-string-refs
|
|
21873
21887
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21874
|
-
(_this$refs$input = this.refs.input) == null
|
|
21888
|
+
if (typeof ((_this$refs$input = this.refs.input) == null ? void 0 : _this$refs$input.blur) === "function") {
|
|
21889
|
+
var _this$refs$input2;
|
|
21890
|
+
// eslint-disable-next-line react/no-string-refs
|
|
21891
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21892
|
+
(_this$refs$input2 = this.refs.input) == null || _this$refs$input2.blur();
|
|
21893
|
+
}
|
|
21875
21894
|
};
|
|
21876
21895
|
this.getInputPaths = () => {
|
|
21877
21896
|
// The widget itself is an input, so we return a single empty list to
|
|
@@ -28458,6 +28477,89 @@ Graph.defaultProps = {
|
|
|
28458
28477
|
isMobile: false
|
|
28459
28478
|
};
|
|
28460
28479
|
|
|
28480
|
+
const defaultGraphConfig = {
|
|
28481
|
+
range: [[0, 1], [0, 1]],
|
|
28482
|
+
snapStep: [1, 1],
|
|
28483
|
+
markings: "none",
|
|
28484
|
+
showTooltips: false,
|
|
28485
|
+
graphDimensionsInPixels: [1, 1],
|
|
28486
|
+
width: 0,
|
|
28487
|
+
height: 0,
|
|
28488
|
+
labels: []
|
|
28489
|
+
};
|
|
28490
|
+
const GraphConfigContext = /*#__PURE__*/createContext(defaultGraphConfig);
|
|
28491
|
+
function useGraphConfig() {
|
|
28492
|
+
return React__default.useContext(GraphConfigContext);
|
|
28493
|
+
}
|
|
28494
|
+
|
|
28495
|
+
const matrixBuilder = vec.matrixBuilder;
|
|
28496
|
+
// When converting vectors, we don't need to translate because a vector
|
|
28497
|
+
// is like a pair of x and y distances, which are not bound to specific graph locations.
|
|
28498
|
+
function vectorsToPixels(vectors, graphState, translation = [0, 0]) {
|
|
28499
|
+
const {
|
|
28500
|
+
range,
|
|
28501
|
+
width,
|
|
28502
|
+
height
|
|
28503
|
+
} = graphState;
|
|
28504
|
+
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28505
|
+
const transformToPx = matrixBuilder().translate(...translation).scale(width / (xMax - xMin), -height / (yMax - yMin)).get();
|
|
28506
|
+
return vectors.map(p => vec.transform(p, transformToPx));
|
|
28507
|
+
}
|
|
28508
|
+
|
|
28509
|
+
// When converting points, we translate so the pixel point ends up in the right location.
|
|
28510
|
+
// This is because points are specific locations on graphs, unlike vectors.
|
|
28511
|
+
function pointToPixel(point, graphState) {
|
|
28512
|
+
const [[xMin], [, yMax]] = graphState.range;
|
|
28513
|
+
const [a, b] = [-xMin, -yMax];
|
|
28514
|
+
return vectorsToPixels([point], graphState, [a, b])[0];
|
|
28515
|
+
}
|
|
28516
|
+
const useTransformVectorsToPixels = (...vectors) => {
|
|
28517
|
+
const graphState = useGraphConfig();
|
|
28518
|
+
return vectorsToPixels(vectors, graphState);
|
|
28519
|
+
};
|
|
28520
|
+
|
|
28521
|
+
function AxisLabels() {
|
|
28522
|
+
const {
|
|
28523
|
+
range,
|
|
28524
|
+
labels,
|
|
28525
|
+
width,
|
|
28526
|
+
height
|
|
28527
|
+
} = useGraphConfig();
|
|
28528
|
+
const yAxisLabelLocation = [0, range[1][1]];
|
|
28529
|
+
const xAxisLabelLocation = [range[0][1], 0];
|
|
28530
|
+
const [xAxisLabelText, yAxisLabelText] = labels;
|
|
28531
|
+
const graphInfo = {
|
|
28532
|
+
range,
|
|
28533
|
+
width,
|
|
28534
|
+
height
|
|
28535
|
+
};
|
|
28536
|
+
const [x1, y1] = pointToPixel(xAxisLabelLocation, graphInfo);
|
|
28537
|
+
// The default location for the y-axis-label is at the maximum y point
|
|
28538
|
+
// This is just underneath the tick line for that point. The -24 moves the
|
|
28539
|
+
// label up one grid square, so it sits on top of the graph
|
|
28540
|
+
const [x2, y2] = vec.add(pointToPixel(yAxisLabelLocation, graphInfo), [0, -24]);
|
|
28541
|
+
const {
|
|
28542
|
+
TeX
|
|
28543
|
+
} = getDependencies();
|
|
28544
|
+
return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("span", {
|
|
28545
|
+
style: {
|
|
28546
|
+
position: "absolute",
|
|
28547
|
+
left: x1,
|
|
28548
|
+
top: y1,
|
|
28549
|
+
fontSize: "14px",
|
|
28550
|
+
transform: "translate(7px, -50%)"
|
|
28551
|
+
}
|
|
28552
|
+
}, /*#__PURE__*/React__default.createElement(TeX, null, xAxisLabelText)), /*#__PURE__*/React__default.createElement("span", {
|
|
28553
|
+
style: {
|
|
28554
|
+
position: "absolute",
|
|
28555
|
+
left: x2,
|
|
28556
|
+
top: y2,
|
|
28557
|
+
fontSize: "14px",
|
|
28558
|
+
transform: "translate(-50%, 0px)"
|
|
28559
|
+
}
|
|
28560
|
+
}, /*#__PURE__*/React__default.createElement(TeX, null, yAxisLabelText)));
|
|
28561
|
+
}
|
|
28562
|
+
|
|
28461
28563
|
// TODO(FEI-4010): Remove `Perseus` prefix for all types here
|
|
28462
28564
|
// TODO(FEI-4011): Use types generated by https://github.com/jaredly/generate-perseus-flowtypes
|
|
28463
28565
|
|
|
@@ -28749,26 +28851,17 @@ function snap(snapStep, point) {
|
|
|
28749
28851
|
return [Math.round(requestedX / snapX) * snapX, Math.round(requestedY / snapY) * snapY];
|
|
28750
28852
|
}
|
|
28751
28853
|
|
|
28752
|
-
const useTransform = (...points) => {
|
|
28753
|
-
const {
|
|
28754
|
-
viewTransform,
|
|
28755
|
-
userTransform
|
|
28756
|
-
} = useTransformContext();
|
|
28757
|
-
const transformToPx = vec.matrixMult(viewTransform, userTransform);
|
|
28758
|
-
const transformedPoints = points.map(point => vec.transform(point, transformToPx));
|
|
28759
|
-
return transformedPoints;
|
|
28760
|
-
};
|
|
28761
|
-
|
|
28762
28854
|
/**
|
|
28763
|
-
* Given
|
|
28764
|
-
*
|
|
28765
|
-
* @param
|
|
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]]
|
|
28766
28860
|
*/
|
|
28767
|
-
const
|
|
28768
|
-
|
|
28769
|
-
const [
|
|
28770
|
-
const [
|
|
28771
|
-
const [bX, bY] = extendFrom;
|
|
28861
|
+
const getIntersectionOfRayWithBox = (initialPoint, throughPoint, box) => {
|
|
28862
|
+
const [[xMin, xMax], [yMin, yMax]] = box;
|
|
28863
|
+
const [aX, aY] = throughPoint;
|
|
28864
|
+
const [bX, bY] = initialPoint;
|
|
28772
28865
|
const yDiff = bY - aY;
|
|
28773
28866
|
const xDiff = bX - aX;
|
|
28774
28867
|
const slope = yDiff / xDiff;
|
|
@@ -28872,7 +28965,7 @@ function scaleCommandBy(scaleFactor) {
|
|
|
28872
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();
|
|
28873
28966
|
function Arrowhead(props) {
|
|
28874
28967
|
var _props$color;
|
|
28875
|
-
const [point] =
|
|
28968
|
+
const [point] = useTransformVectorsToPixels(props.tip);
|
|
28876
28969
|
return /*#__PURE__*/React.createElement("g", {
|
|
28877
28970
|
transform: `translate(${point[0]} ${point[1]}) rotate(${-props.angle})`
|
|
28878
28971
|
}, /*#__PURE__*/React.createElement("g", {
|
|
@@ -28894,7 +28987,7 @@ function Vector(props) {
|
|
|
28894
28987
|
tip,
|
|
28895
28988
|
color
|
|
28896
28989
|
} = props;
|
|
28897
|
-
const [tailPx, tipPx] =
|
|
28990
|
+
const [tailPx, tipPx] = useTransformVectorsToPixels(tail, tip);
|
|
28898
28991
|
const direction = vec.sub(tip, tail);
|
|
28899
28992
|
return /*#__PURE__*/React.createElement("g", {
|
|
28900
28993
|
style: {
|
|
@@ -28905,8 +28998,7 @@ function Vector(props) {
|
|
|
28905
28998
|
start: tailPx,
|
|
28906
28999
|
end: tipPx
|
|
28907
29000
|
}), /*#__PURE__*/React.createElement(Arrowhead, {
|
|
28908
|
-
|
|
28909
|
-
y: tip[1],
|
|
29001
|
+
tip: tip,
|
|
28910
29002
|
angle: angleDegrees(direction)
|
|
28911
29003
|
}));
|
|
28912
29004
|
}
|
|
@@ -28924,12 +29016,16 @@ const MovableLine = props => {
|
|
|
28924
29016
|
stroke = defaultStroke
|
|
28925
29017
|
} = props;
|
|
28926
29018
|
const midpoint = vec.midpoint(start, end);
|
|
28927
|
-
const [startPtPx, endPtPx] =
|
|
29019
|
+
const [startPtPx, endPtPx] = useTransformVectorsToPixels(start, end);
|
|
29020
|
+
const {
|
|
29021
|
+
graphDimensionsInPixels
|
|
29022
|
+
} = useGraphConfig();
|
|
28928
29023
|
let startExtend = undefined;
|
|
28929
29024
|
let endExtend = undefined;
|
|
28930
29025
|
if (extend) {
|
|
28931
|
-
|
|
28932
|
-
|
|
29026
|
+
const trimmedRange = trimRange(extend.range, graphDimensionsInPixels);
|
|
29027
|
+
startExtend = extend.start ? getIntersectionOfRayWithBox(start, end, trimmedRange) : undefined;
|
|
29028
|
+
endExtend = extend.end ? getIntersectionOfRayWithBox(end, start, trimmedRange) : undefined;
|
|
28933
29029
|
}
|
|
28934
29030
|
const line = useRef(null);
|
|
28935
29031
|
const {
|
|
@@ -28986,16 +29082,24 @@ const MovableLine = props => {
|
|
|
28986
29082
|
color: stroke
|
|
28987
29083
|
}));
|
|
28988
29084
|
};
|
|
28989
|
-
|
|
28990
|
-
const
|
|
28991
|
-
|
|
28992
|
-
|
|
28993
|
-
|
|
28994
|
-
|
|
28995
|
-
|
|
28996
|
-
const
|
|
28997
|
-
|
|
28998
|
-
|
|
29085
|
+
function trimRange(range, graphDimensionsInPixels) {
|
|
29086
|
+
const pixelsToTrim = 4;
|
|
29087
|
+
const [xRange, yRange] = range;
|
|
29088
|
+
const [pixelsWide, pixelsTall] = graphDimensionsInPixels;
|
|
29089
|
+
const graphUnitsPerPixelX = size(xRange) / pixelsWide;
|
|
29090
|
+
const graphUnitsPerPixelY = size(yRange) / pixelsTall;
|
|
29091
|
+
const graphUnitsToTrimX = pixelsToTrim * graphUnitsPerPixelX;
|
|
29092
|
+
const graphUnitsToTrimY = pixelsToTrim * graphUnitsPerPixelY;
|
|
29093
|
+
return [trim(xRange, graphUnitsToTrimX), trim(yRange, graphUnitsToTrimY)];
|
|
29094
|
+
}
|
|
29095
|
+
function trim(interval, amount) {
|
|
29096
|
+
if (size(interval) < amount * 2) {
|
|
29097
|
+
return [0, 0];
|
|
29098
|
+
}
|
|
29099
|
+
return [interval[0] + amount, interval[1] - amount];
|
|
29100
|
+
}
|
|
29101
|
+
function size(interval) {
|
|
29102
|
+
return interval[1] - interval[0];
|
|
28999
29103
|
}
|
|
29000
29104
|
|
|
29001
29105
|
// The hitbox size of 48px by 48px is preserved from the legacy interactive
|
|
@@ -29028,13 +29132,13 @@ const StyledMovablePoint = props => {
|
|
|
29028
29132
|
constrain: p => snap(snapStep, p)
|
|
29029
29133
|
});
|
|
29030
29134
|
const pointClasses = `movable-point ${dragging ? "movable-point--dragging" : ""}`;
|
|
29031
|
-
const [[x, y]] =
|
|
29135
|
+
const [[x, y]] = useTransformVectorsToPixels(point);
|
|
29032
29136
|
const [xMin, xMax] = range[0];
|
|
29033
29137
|
const [yMin, yMax] = range[1];
|
|
29034
|
-
const [[verticalStartX]] =
|
|
29035
|
-
const [[verticalEndX]] =
|
|
29036
|
-
const [[_, horizontalStartY]] =
|
|
29037
|
-
const [[__, horizontalEndY]] =
|
|
29138
|
+
const [[verticalStartX]] = useTransformVectorsToPixels([xMin, 0]);
|
|
29139
|
+
const [[verticalEndX]] = useTransformVectorsToPixels([xMax, 0]);
|
|
29140
|
+
const [[_, horizontalStartY]] = useTransformVectorsToPixels([0, yMin]);
|
|
29141
|
+
const [[__, horizontalEndY]] = useTransformVectorsToPixels([0, yMax]);
|
|
29038
29142
|
const showHairlines = dragging && markings !== "none";
|
|
29039
29143
|
const hairlines = /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("line", {
|
|
29040
29144
|
x1: verticalStartX,
|
|
@@ -29356,7 +29460,7 @@ const isRightAngle = angle => Math.abs(angle - Math.PI / 2) < 0.01;
|
|
|
29356
29460
|
*/
|
|
29357
29461
|
const shouldDrawArcOutside = (midpoint, vertex, range, polygonLines) => {
|
|
29358
29462
|
// Create a ray from the midpoint (inside angle) to the edge of the range
|
|
29359
|
-
const rangeIntersectionPoint =
|
|
29463
|
+
const rangeIntersectionPoint = getIntersectionOfRayWithBox(vertex, midpoint, range);
|
|
29360
29464
|
let lineIntersectionCount = 0;
|
|
29361
29465
|
polygonLines.forEach(line => linesIntersect([vertex, rangeIntersectionPoint], line) && lineIntersectionCount++);
|
|
29362
29466
|
|
|
@@ -29479,23 +29583,19 @@ function AxisArrows() {
|
|
|
29479
29583
|
const axisColor = "var(--mafs-fg)";
|
|
29480
29584
|
return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Arrowhead, {
|
|
29481
29585
|
color: axisColor,
|
|
29482
|
-
|
|
29483
|
-
y: 0,
|
|
29586
|
+
tip: [xMin, 0],
|
|
29484
29587
|
angle: 180
|
|
29485
29588
|
}), /*#__PURE__*/React__default.createElement(Arrowhead, {
|
|
29486
29589
|
color: axisColor,
|
|
29487
|
-
|
|
29488
|
-
y: 0,
|
|
29590
|
+
tip: [xMax, 0],
|
|
29489
29591
|
angle: 0
|
|
29490
29592
|
}), /*#__PURE__*/React__default.createElement(Arrowhead, {
|
|
29491
29593
|
color: axisColor,
|
|
29492
|
-
|
|
29493
|
-
y: yMin,
|
|
29594
|
+
tip: [0, yMin],
|
|
29494
29595
|
angle: 270
|
|
29495
29596
|
}), /*#__PURE__*/React__default.createElement(Arrowhead, {
|
|
29496
29597
|
color: axisColor,
|
|
29497
|
-
|
|
29498
|
-
y: yMax,
|
|
29598
|
+
tip: [0, yMax],
|
|
29499
29599
|
angle: 90
|
|
29500
29600
|
}));
|
|
29501
29601
|
}
|
|
@@ -29520,7 +29620,7 @@ const YGridTick = ({
|
|
|
29520
29620
|
tickStep
|
|
29521
29621
|
}) => {
|
|
29522
29622
|
const pointOnAxis = [0, y];
|
|
29523
|
-
const [[xPosition, yPosition]] =
|
|
29623
|
+
const [[xPosition, yPosition]] = useTransformVectorsToPixels(pointOnAxis);
|
|
29524
29624
|
return /*#__PURE__*/React.createElement("g", {
|
|
29525
29625
|
className: "y-axis-ticks"
|
|
29526
29626
|
}, /*#__PURE__*/React.createElement("line", {
|
|
@@ -29543,7 +29643,7 @@ const XGridTick = ({
|
|
|
29543
29643
|
tickStep
|
|
29544
29644
|
}) => {
|
|
29545
29645
|
const pointOnAxis = [x, 0];
|
|
29546
|
-
const [[xPosition, yPosition]] =
|
|
29646
|
+
const [[xPosition, yPosition]] = useTransformVectorsToPixels(pointOnAxis);
|
|
29547
29647
|
return /*#__PURE__*/React.createElement("g", {
|
|
29548
29648
|
className: "x-axis-ticks"
|
|
29549
29649
|
}, /*#__PURE__*/React.createElement("line", {
|
|
@@ -29764,97 +29864,26 @@ const styles$k = StyleSheet.create({
|
|
|
29764
29864
|
}
|
|
29765
29865
|
});
|
|
29766
29866
|
|
|
29767
|
-
const
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
}
|
|
29772
|
-
|
|
29773
|
-
|
|
29774
|
-
|
|
29775
|
-
|
|
29776
|
-
|
|
29777
|
-
|
|
29778
|
-
top: "0",
|
|
29779
|
-
width: "0"
|
|
29867
|
+
const InfoTip$1 = props => {
|
|
29868
|
+
return /*#__PURE__*/React.createElement(Tooltip$1, {
|
|
29869
|
+
content: /*#__PURE__*/React.createElement(Body, {
|
|
29870
|
+
style: styles$j.body
|
|
29871
|
+
}, props.children),
|
|
29872
|
+
placement: "right"
|
|
29873
|
+
}, /*#__PURE__*/React.createElement(PhosphorIcon, {
|
|
29874
|
+
size: "small",
|
|
29875
|
+
icon: questionIcon,
|
|
29876
|
+
style: styles$j.spacingLeft
|
|
29877
|
+
}));
|
|
29780
29878
|
};
|
|
29781
29879
|
const styles$j = StyleSheet.create({
|
|
29782
|
-
|
|
29783
|
-
|
|
29784
|
-
marginLeft: "5px",
|
|
29785
|
-
position: "relative"
|
|
29786
|
-
},
|
|
29787
|
-
infoTipContainer: {
|
|
29788
|
-
position: "absolute",
|
|
29789
|
-
top: "-12px",
|
|
29790
|
-
left: "22px",
|
|
29791
|
-
zIndex: 1000
|
|
29792
|
-
},
|
|
29793
|
-
infoTipTriangle: {
|
|
29794
|
-
height: "10px",
|
|
29795
|
-
left: "0",
|
|
29796
|
-
position: "absolute",
|
|
29797
|
-
top: "8px",
|
|
29798
|
-
width: "0",
|
|
29799
|
-
zIndex: 1,
|
|
29800
|
-
":before": _extends({}, triangleBeforeAfter, {
|
|
29801
|
-
borderRight: "9px solid #bbb",
|
|
29802
|
-
right: "0"
|
|
29803
|
-
}),
|
|
29804
|
-
":after": _extends({}, triangleBeforeAfter, {
|
|
29805
|
-
borderRight: `9px solid ${colors$1.white}`,
|
|
29806
|
-
right: "-1px"
|
|
29807
|
-
})
|
|
29808
|
-
},
|
|
29809
|
-
verticalShadow: {
|
|
29810
|
-
border: `1px solid ${colors$1.basicBorderColor}`,
|
|
29811
|
-
boxShadow: `0 1px 3px ${colors$1.basicBorderColor}`,
|
|
29812
|
-
borderBottom: `1px solid ${colors$1.grayLight}`
|
|
29880
|
+
spacingLeft: {
|
|
29881
|
+
marginInlineStart: spacing.xxxSmall_4
|
|
29813
29882
|
},
|
|
29814
|
-
|
|
29815
|
-
|
|
29816
|
-
padding: "5px 10px",
|
|
29817
|
-
width: "240px"
|
|
29883
|
+
body: {
|
|
29884
|
+
padding: spacing.medium_16
|
|
29818
29885
|
}
|
|
29819
29886
|
});
|
|
29820
|
-
class InfoTip$1 extends React.Component {
|
|
29821
|
-
constructor(...args) {
|
|
29822
|
-
super(...args);
|
|
29823
|
-
this.state = {
|
|
29824
|
-
hover: false
|
|
29825
|
-
};
|
|
29826
|
-
this.handleMouseEnter = () => {
|
|
29827
|
-
this.setState({
|
|
29828
|
-
hover: true
|
|
29829
|
-
});
|
|
29830
|
-
};
|
|
29831
|
-
this.handleMouseLeave = () => {
|
|
29832
|
-
this.setState({
|
|
29833
|
-
hover: false
|
|
29834
|
-
});
|
|
29835
|
-
};
|
|
29836
|
-
}
|
|
29837
|
-
render() {
|
|
29838
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
29839
|
-
className: css(styles$j.infoTip)
|
|
29840
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
29841
|
-
onMouseEnter: this.handleMouseEnter,
|
|
29842
|
-
onMouseLeave: this.handleMouseLeave
|
|
29843
|
-
}, /*#__PURE__*/React.createElement(PhosphorIcon, {
|
|
29844
|
-
size: "small",
|
|
29845
|
-
icon: questionIcon
|
|
29846
|
-
})), /*#__PURE__*/React.createElement("div", {
|
|
29847
|
-
className: css(styles$j.infoTipContainer),
|
|
29848
|
-
style: {
|
|
29849
|
-
display: this.state.hover ? "block" : "none"
|
|
29850
|
-
}
|
|
29851
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
29852
|
-
className: css(styles$j.infoTipTriangle)
|
|
29853
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
29854
|
-
className: css(styles$j.verticalShadow, styles$j.infoTipContentContainer)
|
|
29855
|
-
}, this.props.children)));
|
|
29856
|
-
}
|
|
29857
|
-
}
|
|
29858
29887
|
|
|
29859
29888
|
/**
|
|
29860
29889
|
* A wrapper around info-tip/info-tip.jsx that can be rendered on the
|
|
@@ -30694,9 +30723,7 @@ const getDefaultPoints = ({
|
|
|
30694
30723
|
// Instead of updating to v5, using generic type to relate input and output types.
|
|
30695
30724
|
function getGradableGraph(state, initialGraph) {
|
|
30696
30725
|
if (!state.hasBeenInteractedWith) {
|
|
30697
|
-
return {
|
|
30698
|
-
type: initialGraph.type
|
|
30699
|
-
};
|
|
30726
|
+
return _extends({}, initialGraph);
|
|
30700
30727
|
}
|
|
30701
30728
|
if (initialGraph.type === "linear-system" && state.type === "linear-system") {
|
|
30702
30729
|
return _extends({}, initialGraph, {
|
|
@@ -30855,7 +30882,8 @@ const StatefulMafsGraph = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
30855
30882
|
const MafsGraph = props => {
|
|
30856
30883
|
const {
|
|
30857
30884
|
state,
|
|
30858
|
-
dispatch
|
|
30885
|
+
dispatch,
|
|
30886
|
+
labels
|
|
30859
30887
|
} = props;
|
|
30860
30888
|
const [width, height] = props.box;
|
|
30861
30889
|
const prevState = useRef(state);
|
|
@@ -30884,7 +30912,11 @@ const MafsGraph = props => {
|
|
|
30884
30912
|
range: state.range,
|
|
30885
30913
|
snapStep: state.snapStep,
|
|
30886
30914
|
markings: props.markings,
|
|
30887
|
-
showTooltips: !!props.showTooltips
|
|
30915
|
+
showTooltips: !!props.showTooltips,
|
|
30916
|
+
graphDimensionsInPixels: props.box,
|
|
30917
|
+
width,
|
|
30918
|
+
height,
|
|
30919
|
+
labels
|
|
30888
30920
|
}
|
|
30889
30921
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30890
30922
|
style: {
|
|
@@ -30903,7 +30935,7 @@ const MafsGraph = props => {
|
|
|
30903
30935
|
bottom: 0,
|
|
30904
30936
|
left: 0
|
|
30905
30937
|
}
|
|
30906
|
-
}, /*#__PURE__*/React.createElement(Mafs, {
|
|
30938
|
+
}, props.markings === "graph" && /*#__PURE__*/React.createElement(AxisLabels, null), /*#__PURE__*/React.createElement(Mafs, {
|
|
30907
30939
|
preserveAspectRatio: false,
|
|
30908
30940
|
viewBox: {
|
|
30909
30941
|
x: props.range[0],
|
|
@@ -32085,8 +32117,6 @@ class LegacyInteractiveGraph extends React.Component {
|
|
|
32085
32117
|
graph: graph
|
|
32086
32118
|
});
|
|
32087
32119
|
};
|
|
32088
|
-
this.getUserInput = () => InteractiveGraph.getUserInputFromProps(this.props);
|
|
32089
|
-
this.simpleValidate = rubric => InteractiveGraph.validate(this.getUserInput(), rubric, this);
|
|
32090
32120
|
this.focus = $.noop;
|
|
32091
32121
|
}
|
|
32092
32122
|
// TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
|
|
@@ -32138,6 +32168,12 @@ class LegacyInteractiveGraph extends React.Component {
|
|
|
32138
32168
|
areSegmentGraphsEqual(prevGraph, currentGraph) {
|
|
32139
32169
|
return prevGraph.numSegments !== currentGraph.numSegments;
|
|
32140
32170
|
}
|
|
32171
|
+
getUserInput() {
|
|
32172
|
+
return InteractiveGraph.getUserInputFromProps(this.props);
|
|
32173
|
+
}
|
|
32174
|
+
simpleValidate(rubric) {
|
|
32175
|
+
return InteractiveGraph.validate(this.getUserInput(), rubric, this);
|
|
32176
|
+
}
|
|
32141
32177
|
render() {
|
|
32142
32178
|
const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
|
|
32143
32179
|
const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, box[0]);
|
|
@@ -32219,10 +32255,10 @@ class InteractiveGraph extends React.Component {
|
|
|
32219
32255
|
}
|
|
32220
32256
|
throw new PerseusError("Cannot getUserInput from a graph that has never rendered", Errors.NotAllowed);
|
|
32221
32257
|
};
|
|
32222
|
-
|
|
32223
|
-
|
|
32224
|
-
|
|
32225
|
-
|
|
32258
|
+
}
|
|
32259
|
+
simpleValidate(rubric) {
|
|
32260
|
+
var _this$getUserInput;
|
|
32261
|
+
return InteractiveGraph.validate((_this$getUserInput = this.getUserInput) == null ? void 0 : _this$getUserInput.call(this), rubric, this);
|
|
32226
32262
|
}
|
|
32227
32263
|
render() {
|
|
32228
32264
|
var _this$props$apiOption;
|
|
@@ -43018,7 +43054,7 @@ const init = function init(options) {
|
|
|
43018
43054
|
|
|
43019
43055
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
43020
43056
|
const libName = "@khanacademy/perseus";
|
|
43021
|
-
const libVersion = "22.0
|
|
43057
|
+
const libVersion = "22.1.0";
|
|
43022
43058
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
43023
43059
|
|
|
43024
43060
|
const apiVersion = {
|