@khanacademy/perseus 21.3.1 → 21.5.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 +257 -135
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +253 -124
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +1 -0
- package/dist/renderer.d.ts +19 -16
- package/dist/server-item-renderer.d.ts +4 -7
- package/dist/util/svg.d.ts +9 -0
- package/dist/widgets/interactive-graphs/axis-ticks.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/components/arrowhead.d.ts +8 -0
- package/dist/widgets/interactive-graphs/graphs/components/svg-line.d.ts +10 -0
- package/dist/widgets/interactive-graphs/graphs/components/vector.d.ts +9 -0
- package/dist/widgets/interactive-graphs/graphs/types.d.ts +2 -5
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-state.d.ts +9 -8
- package/dist/widgets/interactive-graphs/reducer/use-graph-config.d.ts +10 -0
- package/dist/widgets/interactive-graphs/types.d.ts +1 -0
- package/dist/widgets/radio/radio.d.ts +5 -8
- package/package.json +1 -1
- package/dist/widgets/interactive-graphs/reducer/use-graph-state.d.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -10366,7 +10366,7 @@ class WrappedPath extends WrappedDrawing {
|
|
|
10366
10366
|
}
|
|
10367
10367
|
}
|
|
10368
10368
|
|
|
10369
|
-
class Arrowhead extends WrappedPath {
|
|
10369
|
+
class Arrowhead$1 extends WrappedPath {
|
|
10370
10370
|
static scale = 1.4;
|
|
10371
10371
|
constructor(graphie, style) {
|
|
10372
10372
|
// Points that define the arrowhead
|
|
@@ -10374,7 +10374,7 @@ class Arrowhead extends WrappedPath {
|
|
|
10374
10374
|
const points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]].map(point => {
|
|
10375
10375
|
// Scale points by `Arrowhead.scale` around `center`
|
|
10376
10376
|
const pv = kmath.vector.subtract(point, center);
|
|
10377
|
-
const pvScaled = kmath.vector.scale(pv, Arrowhead.scale);
|
|
10377
|
+
const pvScaled = kmath.vector.scale(pv, Arrowhead$1.scale);
|
|
10378
10378
|
return kmath.vector.add(center, pvScaled);
|
|
10379
10379
|
});
|
|
10380
10380
|
const unscaledPoints = points.map(graphie.unscalePoint);
|
|
@@ -10391,7 +10391,7 @@ class Arrowhead extends WrappedPath {
|
|
|
10391
10391
|
}
|
|
10392
10392
|
toCoordAtAngle(coord, angle) {
|
|
10393
10393
|
const clipPoint = this.graphie.scalePoint(getClipPoint(this.graphie, coord, angle));
|
|
10394
|
-
this.transform("translateX(" + (clipPoint[0] + Arrowhead.scale * this.center[0]) + "px) " + "translateY(" + (clipPoint[1] + Arrowhead.scale * this.center[1]) + "px) " + "translateZ(0) " + "rotate(" + (360 - KhanMath.bound(angle)) + "deg)");
|
|
10394
|
+
this.transform("translateX(" + (clipPoint[0] + Arrowhead$1.scale * this.center[0]) + "px) " + "translateY(" + (clipPoint[1] + Arrowhead$1.scale * this.center[1]) + "px) " + "translateZ(0) " + "rotate(" + (360 - KhanMath.bound(angle)) + "deg)");
|
|
10395
10395
|
}
|
|
10396
10396
|
}
|
|
10397
10397
|
|
|
@@ -11632,10 +11632,10 @@ ___default["default"].extend(GraphUtils.Graphie.prototype, {
|
|
|
11632
11632
|
if (this._arrows == null) {
|
|
11633
11633
|
this._arrows = [];
|
|
11634
11634
|
if (this.extendLine) {
|
|
11635
|
-
this._arrows.push(new Arrowhead(graph, this.normalStyle));
|
|
11636
|
-
this._arrows.push(new Arrowhead(graph, this.normalStyle));
|
|
11635
|
+
this._arrows.push(new Arrowhead$1(graph, this.normalStyle));
|
|
11636
|
+
this._arrows.push(new Arrowhead$1(graph, this.normalStyle));
|
|
11637
11637
|
} else if (this.extendRay) {
|
|
11638
|
-
this._arrows.push(new Arrowhead(graph, this.normalStyle));
|
|
11638
|
+
this._arrows.push(new Arrowhead$1(graph, this.normalStyle));
|
|
11639
11639
|
}
|
|
11640
11640
|
}
|
|
11641
11641
|
const coordForArrow = [this.coordA, this.coordZ];
|
|
@@ -14162,16 +14162,16 @@ const draw$3 = {
|
|
|
14162
14162
|
// @ts-expect-error - TS2551 - Property '_arrows' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. Did you mean 'arrows'?
|
|
14163
14163
|
this._arrows.push(
|
|
14164
14164
|
// @ts-expect-error - TS2339 - Property 'graphie' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. | TS2339 - Property 'normalStyle' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'.
|
|
14165
|
-
new Arrowhead(this.graphie, this.normalStyle()));
|
|
14165
|
+
new Arrowhead$1(this.graphie, this.normalStyle()));
|
|
14166
14166
|
// @ts-expect-error - TS2551 - Property '_arrows' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. Did you mean 'arrows'?
|
|
14167
14167
|
this._arrows.push(
|
|
14168
14168
|
// @ts-expect-error - TS2339 - Property 'graphie' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. | TS2339 - Property 'normalStyle' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'.
|
|
14169
|
-
new Arrowhead(this.graphie, this.normalStyle()));
|
|
14169
|
+
new Arrowhead$1(this.graphie, this.normalStyle()));
|
|
14170
14170
|
} else if (state.extendRay) {
|
|
14171
14171
|
// @ts-expect-error - TS2551 - Property '_arrows' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. Did you mean 'arrows'?
|
|
14172
14172
|
this._arrows.push(
|
|
14173
14173
|
// @ts-expect-error - TS2339 - Property 'graphie' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. | TS2339 - Property 'normalStyle' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'.
|
|
14174
|
-
new Arrowhead(this.graphie, this.normalStyle()));
|
|
14174
|
+
new Arrowhead$1(this.graphie, this.normalStyle()));
|
|
14175
14175
|
}
|
|
14176
14176
|
}
|
|
14177
14177
|
|
|
@@ -19398,6 +19398,7 @@ class Renderer extends React__namespace.Component {
|
|
|
19398
19398
|
images: {},
|
|
19399
19399
|
highlightedWidgets: [],
|
|
19400
19400
|
questionCompleted: false,
|
|
19401
|
+
showSolutions: "none",
|
|
19401
19402
|
// onRender may be called multiple times per render, for example
|
|
19402
19403
|
// if there are multiple images or TeX pieces within `content`.
|
|
19403
19404
|
// It is a good idea to debounce any functions passed here.
|
|
@@ -19688,6 +19689,7 @@ class Renderer extends React__namespace.Component {
|
|
|
19688
19689
|
apiOptions: this.getApiOptions(),
|
|
19689
19690
|
keypadElement: this.props.keypadElement,
|
|
19690
19691
|
questionCompleted: this.props.questionCompleted,
|
|
19692
|
+
showSolutions: this.props.showSolutions,
|
|
19691
19693
|
onFocus: ___default["default"].partial(this._onWidgetFocus, id),
|
|
19692
19694
|
onBlur: ___default["default"].partial(this._onWidgetBlur, id),
|
|
19693
19695
|
findWidgets: this.findWidgets,
|
|
@@ -23171,14 +23173,6 @@ const ellipsisHorizontalIcon = {
|
|
|
23171
23173
|
width: 100,
|
|
23172
23174
|
height: 27.284
|
|
23173
23175
|
};
|
|
23174
|
-
// Note(TB): Received errors when using useUniqueIdWithMock
|
|
23175
|
-
// so created this workaround function. Will update when
|
|
23176
|
-
// useUniqueIdWithMock is available.
|
|
23177
|
-
// https://khanacademy.atlassian.net/browse/FEI-4861?atlOrigin=eyJpIjoiNDJlZWMwNjM1NWJhNDBkMWFjY2FmN2I0ZjcxZmQxOGUiLCJwIjoiaiJ9
|
|
23178
|
-
let id = 0;
|
|
23179
|
-
function uniqueId() {
|
|
23180
|
-
return `choice-${id++}`;
|
|
23181
|
-
}
|
|
23182
23176
|
const Choice = function (props) {
|
|
23183
23177
|
const {
|
|
23184
23178
|
disabled = false,
|
|
@@ -23228,7 +23222,8 @@ const Choice = function (props) {
|
|
|
23228
23222
|
const showDimmed = !reviewMode && apiOptions.readOnly || crossedOut;
|
|
23229
23223
|
const letter = getChoiceLetter(pos);
|
|
23230
23224
|
const a11yText = getA11yText(letter, checked, correct, crossedOut, showCorrectness);
|
|
23231
|
-
const
|
|
23225
|
+
const idFactory = wonderBlocksCore.useUniqueIdWithMock(`choice`);
|
|
23226
|
+
const choiceId = idFactory.get(letter);
|
|
23232
23227
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
23233
23228
|
style: {
|
|
23234
23229
|
// @ts-expect-error - TS2322 - Type '{ dispay: string; flexDirection: "column"; color: string; }' is not assignable to type 'Properties<string | number, string & {}>'.
|
|
@@ -23815,7 +23810,8 @@ class Radio$1 extends React__namespace.Component {
|
|
|
23815
23810
|
multipleSelect: false,
|
|
23816
23811
|
countChoices: false,
|
|
23817
23812
|
deselectEnabled: false,
|
|
23818
|
-
linterContext: PerseusLinter.linterContextDefault
|
|
23813
|
+
linterContext: PerseusLinter.linterContextDefault,
|
|
23814
|
+
showSolutions: "none"
|
|
23819
23815
|
};
|
|
23820
23816
|
static validate(userInput, rubric) {
|
|
23821
23817
|
const numSelected = userInput.choicesSelected.reduce((sum, selected) => {
|
|
@@ -23925,6 +23921,11 @@ class Radio$1 extends React__namespace.Component {
|
|
|
23925
23921
|
choicesSelected: props.choices.map(() => false)
|
|
23926
23922
|
};
|
|
23927
23923
|
}
|
|
23924
|
+
componentDidUpdate(prevProps) {
|
|
23925
|
+
if (this.props.showSolutions === "selected" && prevProps.showSolutions !== "selected") {
|
|
23926
|
+
this.showRationalesForCurrentlySelectedChoices(this.props);
|
|
23927
|
+
}
|
|
23928
|
+
}
|
|
23928
23929
|
_renderRenderer = (() => {
|
|
23929
23930
|
var _this = this;
|
|
23930
23931
|
return function () {
|
|
@@ -24047,6 +24048,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
24047
24048
|
* Turn on rationale display for the currently selected choices. Note that
|
|
24048
24049
|
* this leaves rationales on for choices that are already showing
|
|
24049
24050
|
* rationales.
|
|
24051
|
+
* @deprecated Internal only. Use `showSolutions` prop instead.
|
|
24050
24052
|
*/
|
|
24051
24053
|
showRationalesForCurrentlySelectedChoices = rubric => {
|
|
24052
24054
|
const {
|
|
@@ -24068,7 +24070,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
24068
24070
|
// We use the same behavior for the readOnly flag as for
|
|
24069
24071
|
// rationaleShown, but we keep it separate in case other
|
|
24070
24072
|
// behaviors want to disable choices without showing rationales.
|
|
24071
|
-
readOnly: state.selected || state.readOnly || widgetCorrect,
|
|
24073
|
+
readOnly: state.selected || state.readOnly || widgetCorrect || this.props.showSolutions !== "none",
|
|
24072
24074
|
correctnessShown: state.selected || state.correctnessShown,
|
|
24073
24075
|
previouslyAnswered: state.previouslyAnswered || state.selected
|
|
24074
24076
|
}));
|
|
@@ -24119,6 +24121,23 @@ class Radio$1 extends React__namespace.Component {
|
|
|
24119
24121
|
correctnessShown: true,
|
|
24120
24122
|
previouslyAnswered: false
|
|
24121
24123
|
}));
|
|
24124
|
+
} else if (this.props.showSolutions === "all") {
|
|
24125
|
+
choiceStates = choices.map(_ref => {
|
|
24126
|
+
let {
|
|
24127
|
+
correct
|
|
24128
|
+
} = _ref;
|
|
24129
|
+
return {
|
|
24130
|
+
selected: correct,
|
|
24131
|
+
// to draw the eye to the correct answer
|
|
24132
|
+
crossedOut: false,
|
|
24133
|
+
readOnly: true,
|
|
24134
|
+
highlighted: false,
|
|
24135
|
+
// has no effect in this mode
|
|
24136
|
+
rationaleShown: true,
|
|
24137
|
+
correctnessShown: true,
|
|
24138
|
+
previouslyAnswered: false
|
|
24139
|
+
};
|
|
24140
|
+
});
|
|
24122
24141
|
} else if (this.props.choiceStates) {
|
|
24123
24142
|
choiceStates = this.props.choiceStates;
|
|
24124
24143
|
} else if (this.props.values) {
|
|
@@ -28477,6 +28496,118 @@ const getLines = points => points.map((point, i) => {
|
|
|
28477
28496
|
return [point, next];
|
|
28478
28497
|
});
|
|
28479
28498
|
|
|
28499
|
+
function SVGLine(props) {
|
|
28500
|
+
const {
|
|
28501
|
+
start,
|
|
28502
|
+
end,
|
|
28503
|
+
style,
|
|
28504
|
+
className,
|
|
28505
|
+
testId
|
|
28506
|
+
} = props;
|
|
28507
|
+
return /*#__PURE__*/React__namespace.createElement("line", {
|
|
28508
|
+
x1: start[0],
|
|
28509
|
+
y1: start[1],
|
|
28510
|
+
x2: end[0],
|
|
28511
|
+
y2: end[1],
|
|
28512
|
+
style: style,
|
|
28513
|
+
className: `${className}`,
|
|
28514
|
+
"data-test-id": testId
|
|
28515
|
+
});
|
|
28516
|
+
}
|
|
28517
|
+
|
|
28518
|
+
function pathBuilder() {
|
|
28519
|
+
return new PathBuilder();
|
|
28520
|
+
}
|
|
28521
|
+
class PathBuilder {
|
|
28522
|
+
path = [];
|
|
28523
|
+
scaleFactor = 1;
|
|
28524
|
+
build() {
|
|
28525
|
+
return this.path.map(scaleCommandBy(this.scaleFactor)).map(commandToString).join("");
|
|
28526
|
+
}
|
|
28527
|
+
|
|
28528
|
+
// add a move (M) command to the path
|
|
28529
|
+
move(x, y) {
|
|
28530
|
+
this.path.push({
|
|
28531
|
+
action: "M",
|
|
28532
|
+
coords: [x, y]
|
|
28533
|
+
});
|
|
28534
|
+
return this;
|
|
28535
|
+
}
|
|
28536
|
+
|
|
28537
|
+
// add a curve (C) command to the path
|
|
28538
|
+
curve(control1X, control1Y, control2X, control2Y, endX, endY) {
|
|
28539
|
+
this.path.push({
|
|
28540
|
+
action: "C",
|
|
28541
|
+
coords: [control1X, control1Y, control2X, control2Y, endX, endY]
|
|
28542
|
+
});
|
|
28543
|
+
return this;
|
|
28544
|
+
}
|
|
28545
|
+
|
|
28546
|
+
// Scale all coordinates of the path by a factor
|
|
28547
|
+
scale(factor) {
|
|
28548
|
+
this.scaleFactor *= factor;
|
|
28549
|
+
return this;
|
|
28550
|
+
}
|
|
28551
|
+
}
|
|
28552
|
+
function commandToString(command) {
|
|
28553
|
+
return `${command.action}${command.coords.join(" ")}`;
|
|
28554
|
+
}
|
|
28555
|
+
function scaleCommandBy(scaleFactor) {
|
|
28556
|
+
return command => ({
|
|
28557
|
+
...command,
|
|
28558
|
+
coords: command.coords.map(c => c * scaleFactor)
|
|
28559
|
+
});
|
|
28560
|
+
}
|
|
28561
|
+
|
|
28562
|
+
// We use the pathBuilder here to scale up the SVG path coordinates used
|
|
28563
|
+
// elsewhere for arrowheads. We scale in the path itself instead of using a CSS
|
|
28564
|
+
// transform because a transform would also scale up the stroke weight, and we
|
|
28565
|
+
// don't want that.
|
|
28566
|
+
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();
|
|
28567
|
+
function Arrowhead(props) {
|
|
28568
|
+
const [point] = useTransform([props.x, props.y]);
|
|
28569
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
28570
|
+
transform: `translate(${point[0]} ${point[1]}) rotate(${-props.angle})`
|
|
28571
|
+
}, /*#__PURE__*/React__namespace.createElement("g", {
|
|
28572
|
+
transform: "translate(-1.5)"
|
|
28573
|
+
}, /*#__PURE__*/React__namespace.createElement("path", {
|
|
28574
|
+
d: arrowPath,
|
|
28575
|
+
fill: "none",
|
|
28576
|
+
style: {
|
|
28577
|
+
stroke: "inherit"
|
|
28578
|
+
},
|
|
28579
|
+
strokeLinejoin: "round",
|
|
28580
|
+
strokeLinecap: "round"
|
|
28581
|
+
})));
|
|
28582
|
+
}
|
|
28583
|
+
|
|
28584
|
+
function Vector(props) {
|
|
28585
|
+
const {
|
|
28586
|
+
tail,
|
|
28587
|
+
tip,
|
|
28588
|
+
color
|
|
28589
|
+
} = props;
|
|
28590
|
+
const [tailPx, tipPx] = useTransform(tail, tip);
|
|
28591
|
+
const direction = mafs.vec.sub(tip, tail);
|
|
28592
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
28593
|
+
style: {
|
|
28594
|
+
stroke: color,
|
|
28595
|
+
strokeWidth: 2
|
|
28596
|
+
}
|
|
28597
|
+
}, /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
28598
|
+
start: tailPx,
|
|
28599
|
+
end: tipPx
|
|
28600
|
+
}), /*#__PURE__*/React__namespace.createElement(Arrowhead, {
|
|
28601
|
+
x: tip[0],
|
|
28602
|
+
y: tip[1],
|
|
28603
|
+
angle: angleDegrees(direction)
|
|
28604
|
+
}));
|
|
28605
|
+
}
|
|
28606
|
+
function angleDegrees(_ref) {
|
|
28607
|
+
let [x, y] = _ref;
|
|
28608
|
+
return Math.atan2(y, x) * 180 / Math.PI;
|
|
28609
|
+
}
|
|
28610
|
+
|
|
28480
28611
|
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
28481
28612
|
const MovableLine = props => {
|
|
28482
28613
|
const {
|
|
@@ -28537,45 +28668,27 @@ const MovableLine = props => {
|
|
|
28537
28668
|
stroke,
|
|
28538
28669
|
strokeWidth: "var(--movable-line-stroke-weight)"
|
|
28539
28670
|
},
|
|
28540
|
-
dragging:
|
|
28671
|
+
className: dragging ? "movable-dragging" : "",
|
|
28541
28672
|
testId: "movable-line__line"
|
|
28542
|
-
})), startExtend && /*#__PURE__*/React__namespace.createElement(
|
|
28673
|
+
})), startExtend && /*#__PURE__*/React__namespace.createElement(Vector, {
|
|
28543
28674
|
tail: start,
|
|
28544
28675
|
tip: startExtend,
|
|
28545
28676
|
color: stroke
|
|
28546
|
-
}), endExtend && /*#__PURE__*/React__namespace.createElement(
|
|
28677
|
+
}), endExtend && /*#__PURE__*/React__namespace.createElement(Vector, {
|
|
28547
28678
|
tail: end,
|
|
28548
28679
|
tip: endExtend,
|
|
28549
28680
|
color: stroke
|
|
28550
28681
|
}));
|
|
28551
28682
|
};
|
|
28552
|
-
function SVGLine(props) {
|
|
28553
|
-
const {
|
|
28554
|
-
start,
|
|
28555
|
-
end,
|
|
28556
|
-
style,
|
|
28557
|
-
dragging,
|
|
28558
|
-
className,
|
|
28559
|
-
testId
|
|
28560
|
-
} = props;
|
|
28561
|
-
const draggingClass = dragging ? "movable-dragging" : "";
|
|
28562
|
-
return /*#__PURE__*/React__namespace.createElement("line", {
|
|
28563
|
-
x1: start[0],
|
|
28564
|
-
y1: start[1],
|
|
28565
|
-
x2: end[0],
|
|
28566
|
-
y2: end[1],
|
|
28567
|
-
style: style,
|
|
28568
|
-
className: `${className} ${draggingClass}`,
|
|
28569
|
-
"data-test-id": testId
|
|
28570
|
-
});
|
|
28571
|
-
}
|
|
28572
28683
|
|
|
28573
|
-
const
|
|
28574
|
-
|
|
28575
|
-
|
|
28576
|
-
|
|
28577
|
-
|
|
28578
|
-
|
|
28684
|
+
const defaultGraphConfig = {
|
|
28685
|
+
range: [[0, 1], [0, 1]],
|
|
28686
|
+
snapStep: [1, 1],
|
|
28687
|
+
markings: "none"
|
|
28688
|
+
};
|
|
28689
|
+
const GraphConfigContext = /*#__PURE__*/React.createContext(defaultGraphConfig);
|
|
28690
|
+
function useGraphConfig() {
|
|
28691
|
+
return React__default["default"].useContext(GraphConfigContext);
|
|
28579
28692
|
}
|
|
28580
28693
|
|
|
28581
28694
|
// The hitbox size of 48px by 48px is preserved from the legacy interactive
|
|
@@ -28583,8 +28696,10 @@ function useGraphState() {
|
|
|
28583
28696
|
const hitboxSizePx = 48;
|
|
28584
28697
|
const StyledMovablePoint = props => {
|
|
28585
28698
|
const {
|
|
28586
|
-
|
|
28587
|
-
|
|
28699
|
+
range,
|
|
28700
|
+
snapStep,
|
|
28701
|
+
markings
|
|
28702
|
+
} = useGraphConfig();
|
|
28588
28703
|
const hitboxRef = React.useRef(null);
|
|
28589
28704
|
const {
|
|
28590
28705
|
point,
|
|
@@ -28597,11 +28712,30 @@ const StyledMovablePoint = props => {
|
|
|
28597
28712
|
gestureTarget: hitboxRef,
|
|
28598
28713
|
point,
|
|
28599
28714
|
onMove,
|
|
28600
|
-
constrain: p => snap(
|
|
28715
|
+
constrain: p => snap(snapStep, p)
|
|
28601
28716
|
});
|
|
28602
28717
|
const pointClasses = `movable-point ${dragging ? "movable-point--dragging" : ""}`;
|
|
28603
28718
|
const [[x, y]] = useTransform(point);
|
|
28604
|
-
|
|
28719
|
+
const [xMin, xMax] = range[0];
|
|
28720
|
+
const [yMin, yMax] = range[1];
|
|
28721
|
+
const [[verticalStartX]] = useTransform([xMin, 0]);
|
|
28722
|
+
const [[verticalEndX]] = useTransform([xMax, 0]);
|
|
28723
|
+
const [[_, horizontalStartY]] = useTransform([0, yMin]);
|
|
28724
|
+
const [[__, horizontalEndY]] = useTransform([0, yMax]);
|
|
28725
|
+
const showHairlines = dragging && markings !== "none";
|
|
28726
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, showHairlines && /*#__PURE__*/React__namespace.createElement("g", null, /*#__PURE__*/React__namespace.createElement("line", {
|
|
28727
|
+
x1: verticalStartX,
|
|
28728
|
+
y1: y,
|
|
28729
|
+
x2: verticalEndX,
|
|
28730
|
+
y2: y,
|
|
28731
|
+
stroke: wonderBlocksTokens.color.green
|
|
28732
|
+
}), /*#__PURE__*/React__namespace.createElement("line", {
|
|
28733
|
+
x1: x,
|
|
28734
|
+
y1: horizontalStartY,
|
|
28735
|
+
x2: x,
|
|
28736
|
+
y2: horizontalEndY,
|
|
28737
|
+
stroke: wonderBlocksTokens.color.green
|
|
28738
|
+
})), /*#__PURE__*/React__namespace.createElement("g", {
|
|
28605
28739
|
ref: hitboxRef,
|
|
28606
28740
|
className: pointClasses,
|
|
28607
28741
|
tabIndex: 0,
|
|
@@ -28634,7 +28768,7 @@ const StyledMovablePoint = props => {
|
|
|
28634
28768
|
fill: color
|
|
28635
28769
|
},
|
|
28636
28770
|
"data-test-id": "movable-point__center"
|
|
28637
|
-
}));
|
|
28771
|
+
})));
|
|
28638
28772
|
};
|
|
28639
28773
|
|
|
28640
28774
|
const SegmentGraph = props => {
|
|
@@ -28642,15 +28776,11 @@ const SegmentGraph = props => {
|
|
|
28642
28776
|
dispatch
|
|
28643
28777
|
} = props;
|
|
28644
28778
|
const {
|
|
28645
|
-
coords: segments
|
|
28646
|
-
snapStep,
|
|
28647
|
-
range
|
|
28779
|
+
coords: segments
|
|
28648
28780
|
} = props.graphState;
|
|
28649
28781
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, segments?.map((segment, i) => /*#__PURE__*/React__namespace.createElement(SegmentView, {
|
|
28650
28782
|
key: i,
|
|
28651
|
-
|
|
28652
|
-
snaps: snapStep,
|
|
28653
|
-
range: range,
|
|
28783
|
+
points: segment,
|
|
28654
28784
|
onMoveLine: delta => {
|
|
28655
28785
|
dispatch(moveLine(i, delta));
|
|
28656
28786
|
},
|
|
@@ -28663,7 +28793,7 @@ const SegmentGraph = props => {
|
|
|
28663
28793
|
const SegmentView = props => {
|
|
28664
28794
|
const {
|
|
28665
28795
|
onMoveLine: onMoveSegment,
|
|
28666
|
-
|
|
28796
|
+
points: [start, end]
|
|
28667
28797
|
} = props;
|
|
28668
28798
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
28669
28799
|
start: start,
|
|
@@ -28688,16 +28818,12 @@ const LinearGraph = props => {
|
|
|
28688
28818
|
} = props;
|
|
28689
28819
|
const {
|
|
28690
28820
|
coords: lines,
|
|
28691
|
-
snapStep,
|
|
28692
|
-
range,
|
|
28693
28821
|
type
|
|
28694
28822
|
} = props.graphState;
|
|
28695
28823
|
const colors = ["var(--movable-line-stroke-color)", "var(--mafs-violet)"];
|
|
28696
28824
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, lines?.map((line, i) => /*#__PURE__*/React__namespace.createElement(LineView, {
|
|
28697
28825
|
key: i,
|
|
28698
|
-
|
|
28699
|
-
snaps: snapStep,
|
|
28700
|
-
range: range,
|
|
28826
|
+
points: line,
|
|
28701
28827
|
onMoveLine: delta => {
|
|
28702
28828
|
dispatch(moveLine(i, delta));
|
|
28703
28829
|
},
|
|
@@ -28712,10 +28838,12 @@ const LineView = props => {
|
|
|
28712
28838
|
const {
|
|
28713
28839
|
onMoveLine,
|
|
28714
28840
|
onMovePoint,
|
|
28715
|
-
|
|
28716
|
-
range,
|
|
28841
|
+
points: [start, end],
|
|
28717
28842
|
stroke
|
|
28718
28843
|
} = props;
|
|
28844
|
+
const {
|
|
28845
|
+
range
|
|
28846
|
+
} = useGraphConfig();
|
|
28719
28847
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
28720
28848
|
start: start,
|
|
28721
28849
|
end: end,
|
|
@@ -29037,46 +29165,26 @@ function PointGraph(props) {
|
|
|
29037
29165
|
})));
|
|
29038
29166
|
}
|
|
29039
29167
|
|
|
29040
|
-
function Arrow(props) {
|
|
29041
|
-
const {
|
|
29042
|
-
userTransform,
|
|
29043
|
-
viewTransform
|
|
29044
|
-
} = mafs.useTransformContext();
|
|
29045
|
-
const point = [props.x, props.y];
|
|
29046
|
-
const userTransformedPoint = mafs.vec.transform(point, userTransform);
|
|
29047
|
-
const viewTransformedPoint = mafs.vec.transform(userTransformedPoint, viewTransform);
|
|
29048
|
-
return /*#__PURE__*/React__default["default"].createElement("g", {
|
|
29049
|
-
transform: `translate(${viewTransformedPoint[0]} ${viewTransformedPoint[1]}) rotate(${props.rotate}) scale(1.25)`
|
|
29050
|
-
}, /*#__PURE__*/React__default["default"].createElement("g", {
|
|
29051
|
-
transform: "translate(-1)"
|
|
29052
|
-
}, /*#__PURE__*/React__default["default"].createElement("path", {
|
|
29053
|
-
d: "M-3 4 C-2.75 2.5 0 0.25 0.75 0C0 -0.25 -2.75 -2.5 -3 -4",
|
|
29054
|
-
fill: "none"
|
|
29055
|
-
})));
|
|
29056
|
-
}
|
|
29057
29168
|
function AxisArrows() {
|
|
29058
29169
|
const {
|
|
29059
|
-
|
|
29060
|
-
} =
|
|
29061
|
-
|
|
29062
|
-
const [xMin, xMax] = range[0];
|
|
29063
|
-
const [yMin, yMax] = range[1];
|
|
29064
|
-
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(Arrow, {
|
|
29170
|
+
range: [[xMin, xMax], [yMin, yMax]]
|
|
29171
|
+
} = useGraphConfig();
|
|
29172
|
+
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29065
29173
|
x: xMax,
|
|
29066
29174
|
y: 0,
|
|
29067
|
-
|
|
29068
|
-
}), /*#__PURE__*/React__default["default"].createElement(
|
|
29175
|
+
angle: 0
|
|
29176
|
+
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29069
29177
|
x: 0,
|
|
29070
29178
|
y: yMin,
|
|
29071
|
-
|
|
29072
|
-
}), /*#__PURE__*/React__default["default"].createElement(
|
|
29179
|
+
angle: 90
|
|
29180
|
+
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29073
29181
|
x: xMin,
|
|
29074
29182
|
y: 0,
|
|
29075
|
-
|
|
29076
|
-
}), /*#__PURE__*/React__default["default"].createElement(
|
|
29183
|
+
angle: 180
|
|
29184
|
+
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29077
29185
|
x: 0,
|
|
29078
29186
|
y: yMax,
|
|
29079
|
-
|
|
29187
|
+
angle: 270
|
|
29080
29188
|
}));
|
|
29081
29189
|
}
|
|
29082
29190
|
|
|
@@ -29085,9 +29193,20 @@ const tickStyle = {
|
|
|
29085
29193
|
stroke: "black",
|
|
29086
29194
|
strokeWidth: 1
|
|
29087
29195
|
};
|
|
29196
|
+
|
|
29197
|
+
// We only want to show the initial negative tick labels (e.g. -1) on each
|
|
29198
|
+
// axis if the tickStep > gridStep, to ensure that these labels do not overlap.
|
|
29199
|
+
// e.g. If gridStep = 1 and tickStep = 2, there are 2 grid lines for every 1 tick,
|
|
29200
|
+
// which allows enough room for both these tick labels to render.
|
|
29201
|
+
const showTickLabel = (gridStep, tickStep, label) => {
|
|
29202
|
+
const showLabel = tickStep > gridStep ? true : label !== -tickStep;
|
|
29203
|
+
return showLabel;
|
|
29204
|
+
};
|
|
29088
29205
|
const YGridTick = _ref => {
|
|
29089
29206
|
let {
|
|
29090
|
-
y
|
|
29207
|
+
y,
|
|
29208
|
+
gridStep,
|
|
29209
|
+
tickStep
|
|
29091
29210
|
} = _ref;
|
|
29092
29211
|
const pointOnAxis = [0, y];
|
|
29093
29212
|
const [[xPosition, yPosition]] = useTransform(pointOnAxis);
|
|
@@ -29099,7 +29218,7 @@ const YGridTick = _ref => {
|
|
|
29099
29218
|
x2: xPosition + tickSize / 2,
|
|
29100
29219
|
y2: yPosition,
|
|
29101
29220
|
style: tickStyle
|
|
29102
|
-
}),
|
|
29221
|
+
}), showTickLabel(gridStep, tickStep, y) && /*#__PURE__*/React__namespace.createElement("text", {
|
|
29103
29222
|
height: 20,
|
|
29104
29223
|
width: 50,
|
|
29105
29224
|
textAnchor: "end",
|
|
@@ -29109,7 +29228,9 @@ const YGridTick = _ref => {
|
|
|
29109
29228
|
};
|
|
29110
29229
|
const XGridTick = _ref2 => {
|
|
29111
29230
|
let {
|
|
29112
|
-
x
|
|
29231
|
+
x,
|
|
29232
|
+
gridStep,
|
|
29233
|
+
tickStep
|
|
29113
29234
|
} = _ref2;
|
|
29114
29235
|
const pointOnAxis = [x, 0];
|
|
29115
29236
|
const [[xPosition, yPosition]] = useTransform(pointOnAxis);
|
|
@@ -29121,7 +29242,7 @@ const XGridTick = _ref2 => {
|
|
|
29121
29242
|
x2: xPosition,
|
|
29122
29243
|
y2: yPosition - tickSize / 2,
|
|
29123
29244
|
style: tickStyle
|
|
29124
|
-
}),
|
|
29245
|
+
}), showTickLabel(gridStep, tickStep, x) && /*#__PURE__*/React__namespace.createElement("text", {
|
|
29125
29246
|
height: 20,
|
|
29126
29247
|
width: 50,
|
|
29127
29248
|
textAnchor: "middle",
|
|
@@ -29156,12 +29277,16 @@ const AxisTicks = props => {
|
|
|
29156
29277
|
}, yGridTicks.map(y => {
|
|
29157
29278
|
return /*#__PURE__*/React__namespace.createElement(YGridTick, {
|
|
29158
29279
|
y: y,
|
|
29159
|
-
key: `y-grid-tick-${y}
|
|
29280
|
+
key: `y-grid-tick-${y}`,
|
|
29281
|
+
gridStep: props.gridStep[0],
|
|
29282
|
+
tickStep: yTickStep
|
|
29160
29283
|
});
|
|
29161
29284
|
}), xGridTicks.map(x => {
|
|
29162
29285
|
return /*#__PURE__*/React__namespace.createElement(XGridTick, {
|
|
29163
29286
|
x: x,
|
|
29164
|
-
key: `x-grid-tick-${x}
|
|
29287
|
+
key: `x-grid-tick-${x}`,
|
|
29288
|
+
gridStep: props.gridStep[1],
|
|
29289
|
+
tickStep: xTickStep
|
|
29165
29290
|
});
|
|
29166
29291
|
}));
|
|
29167
29292
|
};
|
|
@@ -29187,10 +29312,13 @@ const Grid = props => {
|
|
|
29187
29312
|
return props.markings === "none" ? null : /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Coordinates.Cartesian, {
|
|
29188
29313
|
xAxis: axisOptions(props, 0),
|
|
29189
29314
|
yAxis: axisOptions(props, 1)
|
|
29190
|
-
}), /*#__PURE__*/React__namespace.createElement(
|
|
29315
|
+
}), props.markings === "graph" && /*#__PURE__*/React__namespace.createElement(AxisArrows, null),
|
|
29316
|
+
// Only render the axis ticks and arrows if the markings are set to a full "graph"
|
|
29317
|
+
props.markings === "graph" && /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(AxisTicks, {
|
|
29191
29318
|
range: props.range,
|
|
29192
|
-
tickStep: props.tickStep
|
|
29193
|
-
|
|
29319
|
+
tickStep: props.tickStep,
|
|
29320
|
+
gridStep: props.gridStep
|
|
29321
|
+
}), /*#__PURE__*/React__namespace.createElement(AxisArrows, null)));
|
|
29194
29322
|
};
|
|
29195
29323
|
|
|
29196
29324
|
// Displays a stylized open eye: lint warnings are visible
|
|
@@ -30161,15 +30289,20 @@ function initializeGraphState(params) {
|
|
|
30161
30289
|
graph,
|
|
30162
30290
|
step,
|
|
30163
30291
|
snapStep,
|
|
30164
|
-
range
|
|
30292
|
+
range,
|
|
30293
|
+
markings
|
|
30165
30294
|
} = params;
|
|
30295
|
+
const shared = {
|
|
30296
|
+
hasBeenInteractedWith: false,
|
|
30297
|
+
range,
|
|
30298
|
+
snapStep,
|
|
30299
|
+
markings
|
|
30300
|
+
};
|
|
30166
30301
|
switch (graph.type) {
|
|
30167
30302
|
case "segment":
|
|
30168
30303
|
return {
|
|
30304
|
+
...shared,
|
|
30169
30305
|
type: "segment",
|
|
30170
|
-
hasBeenInteractedWith: false,
|
|
30171
|
-
range,
|
|
30172
|
-
snapStep,
|
|
30173
30306
|
coords: getDefaultSegments({
|
|
30174
30307
|
graph,
|
|
30175
30308
|
step,
|
|
@@ -30180,10 +30313,8 @@ function initializeGraphState(params) {
|
|
|
30180
30313
|
case "linear-system":
|
|
30181
30314
|
case "ray":
|
|
30182
30315
|
return {
|
|
30316
|
+
...shared,
|
|
30183
30317
|
type: graph.type,
|
|
30184
|
-
hasBeenInteractedWith: false,
|
|
30185
|
-
range,
|
|
30186
|
-
snapStep,
|
|
30187
30318
|
// Linear and ray graphs have a single tuple of points, while a
|
|
30188
30319
|
// linear system has two tuples of points.
|
|
30189
30320
|
coords: getLineCoords({
|
|
@@ -30194,10 +30325,8 @@ function initializeGraphState(params) {
|
|
|
30194
30325
|
};
|
|
30195
30326
|
case "polygon":
|
|
30196
30327
|
return {
|
|
30328
|
+
...shared,
|
|
30197
30329
|
type: "polygon",
|
|
30198
|
-
hasBeenInteractedWith: false,
|
|
30199
|
-
range,
|
|
30200
|
-
snapStep,
|
|
30201
30330
|
showAngles: Boolean(graph.showAngles),
|
|
30202
30331
|
showSides: Boolean(graph.showSides),
|
|
30203
30332
|
coords: getPolygonCoords({
|
|
@@ -30208,10 +30337,8 @@ function initializeGraphState(params) {
|
|
|
30208
30337
|
};
|
|
30209
30338
|
case "point":
|
|
30210
30339
|
return {
|
|
30340
|
+
...shared,
|
|
30211
30341
|
type: graph.type,
|
|
30212
|
-
hasBeenInteractedWith: false,
|
|
30213
|
-
range,
|
|
30214
|
-
snapStep,
|
|
30215
30342
|
coords: getDefaultPoints({
|
|
30216
30343
|
graph,
|
|
30217
30344
|
step,
|
|
@@ -30464,10 +30591,11 @@ const MafsGraph = props => {
|
|
|
30464
30591
|
React.useEffect(() => {
|
|
30465
30592
|
dispatch(changeRange([[xMinRange, xMaxRange], [yMinRange, yMaxRange]]));
|
|
30466
30593
|
}, [dispatch, xMinRange, xMaxRange, yMinRange, yMaxRange]);
|
|
30467
|
-
return /*#__PURE__*/React__namespace.createElement(
|
|
30594
|
+
return /*#__PURE__*/React__namespace.createElement(GraphConfigContext.Provider, {
|
|
30468
30595
|
value: {
|
|
30469
|
-
state,
|
|
30470
|
-
|
|
30596
|
+
range: state.range,
|
|
30597
|
+
snapStep: state.snapStep,
|
|
30598
|
+
markings: props.markings
|
|
30471
30599
|
}
|
|
30472
30600
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30473
30601
|
style: {
|
|
@@ -42516,7 +42644,7 @@ const init = function (options) {
|
|
|
42516
42644
|
|
|
42517
42645
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
42518
42646
|
const libName = "@khanacademy/perseus";
|
|
42519
|
-
const libVersion = "21.
|
|
42647
|
+
const libVersion = "21.5.0";
|
|
42520
42648
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
42521
42649
|
|
|
42522
42650
|
const apiVersion = {
|
|
@@ -43354,6 +43482,7 @@ class ServerItemRenderer extends React__namespace.Component {
|
|
|
43354
43482
|
apiOptions: apiOptions,
|
|
43355
43483
|
questionCompleted: this.state.questionCompleted,
|
|
43356
43484
|
reviewMode: this.props.reviewMode,
|
|
43485
|
+
showSolutions: this.props.showSolutions,
|
|
43357
43486
|
ref: elem => {
|
|
43358
43487
|
if (elem != null) {
|
|
43359
43488
|
this.questionRenderer = elem;
|