@khanacademy/perseus 20.3.0 → 20.4.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 +9 -10
- package/dist/es/index.js +355 -144
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +9 -10
- package/dist/index.js +341 -135
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +9 -7
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +14 -0
- package/dist/widgets/interactive-graphs/{movable-point.d.ts → graphs/components/movable-point.d.ts} +2 -1
- package/dist/widgets/interactive-graphs/graphs/index.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/linear.d.ts +5 -0
- package/dist/widgets/interactive-graphs/graphs/segment.d.ts +1 -2
- package/dist/widgets/interactive-graphs/graphs/types.d.ts +9 -0
- package/dist/widgets/interactive-graphs/interactive-graph-action.d.ts +4 -4
- package/dist/widgets/interactive-graphs/interactive-graph-reducer.d.ts +2 -2
- package/dist/widgets/interactive-graphs/interactive-graph-state.d.ts +2 -11
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +3 -3
- package/dist/widgets/interactive-graphs/types.d.ts +12 -2
- package/package.json +1 -2
package/dist/es/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { OptionItem, SingleSelect, MultiSelect } from '@khanacademy/wonder-block
|
|
|
31
31
|
import caretDown from '@phosphor-icons/core/assets/regular/caret-down.svg';
|
|
32
32
|
import caretUp from '@phosphor-icons/core/assets/regular/caret-up.svg';
|
|
33
33
|
import debounce$2 from 'lodash.debounce';
|
|
34
|
-
import { Point as Point$2,
|
|
34
|
+
import { Point as Point$2, vec, useTransformContext, useMovable, Vector, Coordinates, Mafs } from 'mafs';
|
|
35
35
|
import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
|
|
36
36
|
import questionIcon from '@phosphor-icons/core/regular/question.svg';
|
|
37
37
|
import { LabelSmall, LabelMedium } from '@khanacademy/wonder-blocks-typography';
|
|
@@ -14388,7 +14388,7 @@ const DEFAULT_STATE$2 = {
|
|
|
14388
14388
|
visibleShape: null,
|
|
14389
14389
|
mouseTarget: null
|
|
14390
14390
|
};
|
|
14391
|
-
const MovableLine$
|
|
14391
|
+
const MovableLine$4 = function MovableLine(graphie, movable, options) {
|
|
14392
14392
|
assert$6(graphie != null);
|
|
14393
14393
|
assert$6(options != null);
|
|
14394
14394
|
|
|
@@ -14406,10 +14406,10 @@ const MovableLine$3 = function MovableLine(graphie, movable, options) {
|
|
|
14406
14406
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14407
14407
|
this.modify(_.extend({}, DEFAULT_STATE$2, options));
|
|
14408
14408
|
};
|
|
14409
|
-
_.extend(MovableLine$
|
|
14410
|
-
InteractiveUtil.createGettersFor(MovableLine$
|
|
14411
|
-
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$
|
|
14412
|
-
_.extend(MovableLine$
|
|
14409
|
+
_.extend(MovableLine$4, MovableLineOptions);
|
|
14410
|
+
InteractiveUtil.createGettersFor(MovableLine$4, _.extend({}, DEFAULT_PROPS$2, DEFAULT_STATE$2));
|
|
14411
|
+
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$4);
|
|
14412
|
+
_.extend(MovableLine$4.prototype, {
|
|
14413
14413
|
cloneState: function () {
|
|
14414
14414
|
return _.extend(this.movable.cloneState(), {
|
|
14415
14415
|
coords: this.coords()
|
|
@@ -14986,7 +14986,7 @@ const DEFAULT_STATE$1 = {
|
|
|
14986
14986
|
// TODO(benchristel): this is a memory leak. We add items to
|
|
14987
14987
|
// tooltipResetFunctions, but never remove them.
|
|
14988
14988
|
const tooltipResetFunctions = [];
|
|
14989
|
-
class MovablePoint$
|
|
14989
|
+
class MovablePoint$4 {
|
|
14990
14990
|
constructor(graphie, movable, options) {
|
|
14991
14991
|
this.graphie = void 0;
|
|
14992
14992
|
this.movable = void 0;
|
|
@@ -15503,15 +15503,15 @@ class MovablePoint$5 {
|
|
|
15503
15503
|
this.movable.toFront();
|
|
15504
15504
|
}
|
|
15505
15505
|
}
|
|
15506
|
-
MovablePoint$
|
|
15507
|
-
MovablePoint$
|
|
15508
|
-
MovablePoint$
|
|
15509
|
-
MovablePoint$
|
|
15510
|
-
MovablePoint$
|
|
15511
|
-
MovablePoint$
|
|
15512
|
-
MovablePoint$
|
|
15513
|
-
MovablePoint$
|
|
15514
|
-
MovablePoint$
|
|
15506
|
+
MovablePoint$4.add = MovablePointOptions.add;
|
|
15507
|
+
MovablePoint$4.modify = MovablePointOptions.modify;
|
|
15508
|
+
MovablePoint$4.draw = MovablePointOptions.draw;
|
|
15509
|
+
MovablePoint$4.remove = MovablePointOptions.remove;
|
|
15510
|
+
MovablePoint$4.onMoveStart = MovablePointOptions.onMoveStart;
|
|
15511
|
+
MovablePoint$4.constraints = MovablePointOptions.constraints;
|
|
15512
|
+
MovablePoint$4.onMove = MovablePointOptions.onMove;
|
|
15513
|
+
MovablePoint$4.onMoveEnd = MovablePointOptions.onMoveEnd;
|
|
15514
|
+
MovablePoint$4.onClick = MovablePointOptions.onClick;
|
|
15515
15515
|
function getKey(eventName, id) {
|
|
15516
15516
|
return eventName + ":" + id;
|
|
15517
15517
|
}
|
|
@@ -16105,15 +16105,15 @@ _.extend(MovablePolygon.prototype, {
|
|
|
16105
16105
|
});
|
|
16106
16106
|
|
|
16107
16107
|
const Interactive2 = {
|
|
16108
|
-
MovablePoint: MovablePoint$
|
|
16108
|
+
MovablePoint: MovablePoint$4,
|
|
16109
16109
|
addMovablePoint: function (graphie, options) {
|
|
16110
16110
|
const movable = new Movable(graphie, {});
|
|
16111
|
-
return new MovablePoint$
|
|
16111
|
+
return new MovablePoint$4(graphie, movable, options);
|
|
16112
16112
|
},
|
|
16113
|
-
MovableLine: MovableLine$
|
|
16113
|
+
MovableLine: MovableLine$4,
|
|
16114
16114
|
addMovableLine: function (graphie, options) {
|
|
16115
16115
|
const movable = new Movable(graphie, {});
|
|
16116
|
-
return new MovableLine$
|
|
16116
|
+
return new MovableLine$4(graphie, movable, options);
|
|
16117
16117
|
},
|
|
16118
16118
|
MovablePolygon: MovablePolygon,
|
|
16119
16119
|
addMovablePolygon: function (graphie, options) {
|
|
@@ -16149,7 +16149,7 @@ const Interactive2 = {
|
|
|
16149
16149
|
}
|
|
16150
16150
|
};
|
|
16151
16151
|
|
|
16152
|
-
const MovablePoint$
|
|
16152
|
+
const MovablePoint$3 = GraphieClasses.createClass({
|
|
16153
16153
|
displayName: "MovablePoint",
|
|
16154
16154
|
movableProps: ["children"],
|
|
16155
16155
|
_getProps: function () {
|
|
@@ -16206,8 +16206,8 @@ const MovablePoint$4 = GraphieClasses.createClass({
|
|
|
16206
16206
|
});
|
|
16207
16207
|
|
|
16208
16208
|
// Include helper methods, such as MovablePoint.constrain.snap()
|
|
16209
|
-
_.extend(MovablePoint$
|
|
16210
|
-
const MovableLine$
|
|
16209
|
+
_.extend(MovablePoint$3, Interactive2.MovablePoint);
|
|
16210
|
+
const MovableLine$3 = GraphieClasses.createClass({
|
|
16211
16211
|
displayName: "MovableLine",
|
|
16212
16212
|
movableProps: ["children"],
|
|
16213
16213
|
add: function (graphie) {
|
|
@@ -16235,7 +16235,7 @@ const MovableLine$2 = GraphieClasses.createClass({
|
|
|
16235
16235
|
});
|
|
16236
16236
|
|
|
16237
16237
|
// Include helper methods, such as MovableLine.constrain.snap()
|
|
16238
|
-
_.extend(MovableLine$
|
|
16238
|
+
_.extend(MovableLine$3, Interactive2.MovableLine);
|
|
16239
16239
|
const Label$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16240
16240
|
let coord = props.coord;
|
|
16241
16241
|
if (props.unscaled) {
|
|
@@ -16375,8 +16375,8 @@ var Movables = {
|
|
|
16375
16375
|
Circle: Circle,
|
|
16376
16376
|
Label: Label$1,
|
|
16377
16377
|
Line: Line$2,
|
|
16378
|
-
MovableLine: MovableLine$
|
|
16379
|
-
MovablePoint: MovablePoint$
|
|
16378
|
+
MovableLine: MovableLine$3,
|
|
16379
|
+
MovablePoint: MovablePoint$3,
|
|
16380
16380
|
Parabola: Parabola,
|
|
16381
16381
|
Path: Path,
|
|
16382
16382
|
Plot: Plot$2,
|
|
@@ -24856,6 +24856,12 @@ var Dropdown$1 = {
|
|
|
24856
24856
|
|
|
24857
24857
|
// transform = _.identity
|
|
24858
24858
|
|
|
24859
|
+
function mediaQueryIsMatched(mediaQuery) {
|
|
24860
|
+
if (typeof window.matchMedia !== "function") {
|
|
24861
|
+
return false;
|
|
24862
|
+
}
|
|
24863
|
+
return window.matchMedia(mediaQuery).matches;
|
|
24864
|
+
}
|
|
24859
24865
|
class Explanation extends React.Component {
|
|
24860
24866
|
constructor(..._args) {
|
|
24861
24867
|
super(..._args);
|
|
@@ -24889,7 +24895,7 @@ class Explanation extends React.Component {
|
|
|
24889
24895
|
render() {
|
|
24890
24896
|
const promptText = this.state.expanded ? this.props.hidePrompt : this.props.showPrompt;
|
|
24891
24897
|
const caretIcon = this.state.expanded ? caretUp : caretDown;
|
|
24892
|
-
const allowTransition =
|
|
24898
|
+
const allowTransition = mediaQueryIsMatched("(prefers-reduced-motion: no-preference)");
|
|
24893
24899
|
|
|
24894
24900
|
// Special styling is needed to fit the button in a block of text without throwing off the line spacing.
|
|
24895
24901
|
// While the button is not normally included in a block of text, it needs to be able to accommodate such a case.
|
|
@@ -24900,7 +24906,7 @@ class Explanation extends React.Component {
|
|
|
24900
24906
|
};
|
|
24901
24907
|
const contentStyling = [styles$p.content, this.state.expanded ? styles$p.contentExpanded : styles$p.contentCollapsed, allowTransition && (this.state.expanded ? styles$p.transitionExpanded : styles$p.transitionCollapsed)];
|
|
24902
24908
|
return /*#__PURE__*/React.createElement(UniqueIDProvider, {
|
|
24903
|
-
mockOnFirstRender:
|
|
24909
|
+
mockOnFirstRender: true,
|
|
24904
24910
|
scope: "explanation-widget"
|
|
24905
24911
|
}, ids => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
|
24906
24912
|
"aria-expanded": this.state.expanded,
|
|
@@ -26288,9 +26294,9 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
26288
26294
|
});
|
|
26289
26295
|
|
|
26290
26296
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
26291
|
-
const MovablePoint$
|
|
26297
|
+
const MovablePoint$2 = Graphie.MovablePoint;
|
|
26292
26298
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
26293
|
-
const MovableLine$
|
|
26299
|
+
const MovableLine$2 = Graphie.MovableLine;
|
|
26294
26300
|
function isFlipped(newCoord, oldCoord, line) {
|
|
26295
26301
|
const CCW = (a, b, c) => {
|
|
26296
26302
|
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
|
|
@@ -26345,7 +26351,7 @@ class FunctionGrapher extends React.Component {
|
|
|
26345
26351
|
const dashed = {
|
|
26346
26352
|
strokeDasharray: "- "
|
|
26347
26353
|
};
|
|
26348
|
-
return asymptote && /*#__PURE__*/React.createElement(MovableLine$
|
|
26354
|
+
return asymptote && /*#__PURE__*/React.createElement(MovableLine$2, {
|
|
26349
26355
|
onMove: (newCoord, oldCoord) => {
|
|
26350
26356
|
// Calculate and apply displacement
|
|
26351
26357
|
const delta = vector$1.subtract(newCoord, oldCoord);
|
|
@@ -26370,7 +26376,7 @@ class FunctionGrapher extends React.Component {
|
|
|
26370
26376
|
}],
|
|
26371
26377
|
normalStyle: dashed,
|
|
26372
26378
|
highlightStyle: dashed
|
|
26373
|
-
}, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$
|
|
26379
|
+
}, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$2, {
|
|
26374
26380
|
key: `asymptoteCoord-${i}`,
|
|
26375
26381
|
coord: coord,
|
|
26376
26382
|
static: true,
|
|
@@ -26385,7 +26391,7 @@ class FunctionGrapher extends React.Component {
|
|
|
26385
26391
|
}
|
|
26386
26392
|
render() {
|
|
26387
26393
|
const pointForCoord = (coord, i) => {
|
|
26388
|
-
return /*#__PURE__*/React.createElement(MovablePoint$
|
|
26394
|
+
return /*#__PURE__*/React.createElement(MovablePoint$2, {
|
|
26389
26395
|
key: i,
|
|
26390
26396
|
coord: coord,
|
|
26391
26397
|
static: this.props.static,
|
|
@@ -27219,9 +27225,9 @@ const Label = Graphie.Label;
|
|
|
27219
27225
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
27220
27226
|
const Line$1 = Graphie.Line;
|
|
27221
27227
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
27222
|
-
const MovablePoint$
|
|
27228
|
+
const MovablePoint$1 = Graphie.MovablePoint;
|
|
27223
27229
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
27224
|
-
const MovableLine = Graphie.MovableLine;
|
|
27230
|
+
const MovableLine$1 = Graphie.MovableLine;
|
|
27225
27231
|
// @ts-expect-error - TS2339 - Property 'Plot' does not exist on type 'typeof Graphie'.
|
|
27226
27232
|
const Plot = Graphie.Plot;
|
|
27227
27233
|
// @ts-expect-error - TS2339 - Property 'PlotParametric' does not exist on type 'typeof Graphie'.
|
|
@@ -27468,7 +27474,7 @@ class Interaction extends React.Component {
|
|
|
27468
27474
|
return [coordX, coordY];
|
|
27469
27475
|
}];
|
|
27470
27476
|
if (element.options.constraint === "snap") {
|
|
27471
|
-
constraints.push(MovablePoint$
|
|
27477
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27472
27478
|
} else if (element.options.constraint === "x") {
|
|
27473
27479
|
constraints.push(coord => {
|
|
27474
27480
|
return [
|
|
@@ -27490,7 +27496,7 @@ class Interaction extends React.Component {
|
|
|
27490
27496
|
// TODO(eater): foo_[xyz] are hacky non-props to
|
|
27491
27497
|
// get the component to update when constraints
|
|
27492
27498
|
// change
|
|
27493
|
-
return /*#__PURE__*/React.createElement(MovablePoint$
|
|
27499
|
+
return /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
27494
27500
|
key: element.key,
|
|
27495
27501
|
coord: [
|
|
27496
27502
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
@@ -27525,7 +27531,7 @@ class Interaction extends React.Component {
|
|
|
27525
27531
|
return [coordX, coordY];
|
|
27526
27532
|
}];
|
|
27527
27533
|
if (element.options.constraint === "snap") {
|
|
27528
|
-
constraints.push(MovablePoint$
|
|
27534
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27529
27535
|
} else if (element.options.constraint === "x") {
|
|
27530
27536
|
constraints.push(coord => {
|
|
27531
27537
|
return [
|
|
@@ -27553,7 +27559,7 @@ class Interaction extends React.Component {
|
|
|
27553
27559
|
this.state.variables["x_" + element.options.endSubscript],
|
|
27554
27560
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27555
27561
|
this.state.variables["y_" + element.options.endSubscript]];
|
|
27556
|
-
return /*#__PURE__*/React.createElement(MovableLine, {
|
|
27562
|
+
return /*#__PURE__*/React.createElement(MovableLine$1, {
|
|
27557
27563
|
key: element.key,
|
|
27558
27564
|
constraints: constraints
|
|
27559
27565
|
// eslint-disable-next-line react/jsx-no-bind
|
|
@@ -27566,14 +27572,14 @@ class Interaction extends React.Component {
|
|
|
27566
27572
|
foo_x: element.options.constraint,
|
|
27567
27573
|
foo_y: element.options.constraintFn,
|
|
27568
27574
|
foo_z: element.options.snap
|
|
27569
|
-
}, /*#__PURE__*/React.createElement(MovablePoint$
|
|
27575
|
+
}, /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
27570
27576
|
coord: start,
|
|
27571
27577
|
static: true,
|
|
27572
27578
|
normalStyle: {
|
|
27573
27579
|
stroke: "none",
|
|
27574
27580
|
fill: "none"
|
|
27575
27581
|
}
|
|
27576
|
-
}), /*#__PURE__*/React.createElement(MovablePoint$
|
|
27582
|
+
}), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
27577
27583
|
coord: end,
|
|
27578
27584
|
static: true,
|
|
27579
27585
|
normalStyle: {
|
|
@@ -28157,20 +28163,142 @@ function moveControlPoint(objectIndex, pointIndex, destination) {
|
|
|
28157
28163
|
destination
|
|
28158
28164
|
};
|
|
28159
28165
|
}
|
|
28160
|
-
const
|
|
28161
|
-
function moveSegment(
|
|
28166
|
+
const MOVE_LINE = "move-line";
|
|
28167
|
+
function moveSegment(lineIndex, delta) {
|
|
28162
28168
|
return {
|
|
28163
|
-
type:
|
|
28164
|
-
|
|
28169
|
+
type: MOVE_LINE,
|
|
28170
|
+
lineIndex,
|
|
28165
28171
|
delta
|
|
28166
28172
|
};
|
|
28167
28173
|
}
|
|
28168
28174
|
|
|
28169
|
-
const
|
|
28175
|
+
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
28176
|
+
const MovableLine = props => {
|
|
28177
|
+
const {
|
|
28178
|
+
start,
|
|
28179
|
+
end,
|
|
28180
|
+
onMove,
|
|
28181
|
+
extend,
|
|
28182
|
+
stroke = defaultStroke
|
|
28183
|
+
} = props;
|
|
28184
|
+
const midpoint = vec.midpoint(start, end);
|
|
28185
|
+
const {
|
|
28186
|
+
viewTransform,
|
|
28187
|
+
userTransform
|
|
28188
|
+
} = useTransformContext();
|
|
28189
|
+
const transformToPx = vec.matrixMult(viewTransform, userTransform);
|
|
28190
|
+
const startPtPx = vec.transform(start, transformToPx);
|
|
28191
|
+
const endPtPx = vec.transform(end, transformToPx);
|
|
28192
|
+
let startExtend = undefined;
|
|
28193
|
+
let endExtend = undefined;
|
|
28194
|
+
if (extend) {
|
|
28195
|
+
startExtend = extend.start ? getExtensionCoords(end, start, extend.range) : undefined;
|
|
28196
|
+
endExtend = extend.end ? getExtensionCoords(start, end, extend.range) : undefined;
|
|
28197
|
+
}
|
|
28198
|
+
const line = useRef(null);
|
|
28199
|
+
const {
|
|
28200
|
+
dragging
|
|
28201
|
+
} = useMovable({
|
|
28202
|
+
gestureTarget: line,
|
|
28203
|
+
point: midpoint,
|
|
28204
|
+
onMove: newPoint => {
|
|
28205
|
+
onMove(vec.sub(newPoint, midpoint));
|
|
28206
|
+
},
|
|
28207
|
+
constrain: p => p
|
|
28208
|
+
});
|
|
28209
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("g", {
|
|
28210
|
+
ref: line,
|
|
28211
|
+
tabIndex: 0,
|
|
28212
|
+
className: "movable-line",
|
|
28213
|
+
style: {
|
|
28214
|
+
cursor: dragging ? "grabbing" : "grab"
|
|
28215
|
+
}
|
|
28216
|
+
}, /*#__PURE__*/React.createElement(SVGLine, {
|
|
28217
|
+
start: startPtPx,
|
|
28218
|
+
end: endPtPx,
|
|
28219
|
+
style: {
|
|
28220
|
+
stroke: "transparent",
|
|
28221
|
+
strokeWidth: 44
|
|
28222
|
+
}
|
|
28223
|
+
}), /*#__PURE__*/React.createElement(SVGLine, {
|
|
28224
|
+
start: startPtPx,
|
|
28225
|
+
end: endPtPx,
|
|
28226
|
+
style: {
|
|
28227
|
+
stroke,
|
|
28228
|
+
strokeWidth: "var(--movable-line-stroke-weight)"
|
|
28229
|
+
},
|
|
28230
|
+
dragging: dragging
|
|
28231
|
+
})), startExtend && /*#__PURE__*/React.createElement(Vector, {
|
|
28232
|
+
tail: start,
|
|
28233
|
+
tip: startExtend,
|
|
28234
|
+
color: stroke
|
|
28235
|
+
}), endExtend && /*#__PURE__*/React.createElement(Vector, {
|
|
28236
|
+
tail: end,
|
|
28237
|
+
tip: endExtend,
|
|
28238
|
+
color: stroke
|
|
28239
|
+
}));
|
|
28240
|
+
};
|
|
28241
|
+
function SVGLine(props) {
|
|
28242
|
+
const {
|
|
28243
|
+
start,
|
|
28244
|
+
end,
|
|
28245
|
+
style,
|
|
28246
|
+
dragging
|
|
28247
|
+
} = props;
|
|
28248
|
+
return /*#__PURE__*/React.createElement("line", {
|
|
28249
|
+
x1: start[0],
|
|
28250
|
+
y1: start[1],
|
|
28251
|
+
x2: end[0],
|
|
28252
|
+
y2: end[1],
|
|
28253
|
+
style: style,
|
|
28254
|
+
className: dragging ? "movable-line-dragging" : undefined
|
|
28255
|
+
});
|
|
28256
|
+
}
|
|
28257
|
+
|
|
28258
|
+
/**
|
|
28259
|
+
* Given two points, find the tips that extends through the points to the edge of the range.
|
|
28260
|
+
* @param collinearPoint - The point that the line passes through. Needed to establish slope.
|
|
28261
|
+
* @param extendFrom - The point that the line extends from to the edge of the graph.
|
|
28262
|
+
*/
|
|
28263
|
+
const getExtensionCoords = (collinearPoint, extendFrom, range) => {
|
|
28264
|
+
// edges of the graph
|
|
28265
|
+
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28266
|
+
const [aX, aY] = collinearPoint;
|
|
28267
|
+
const [bX, bY] = extendFrom;
|
|
28268
|
+
const yDiff = bY - aY;
|
|
28269
|
+
const xDiff = bX - aX;
|
|
28270
|
+
const slope = yDiff / xDiff;
|
|
28271
|
+
const yAtXMin = slope * (xMin - aX) + aY;
|
|
28272
|
+
const yAtXMax = slope * (xMax - aX) + aY;
|
|
28273
|
+
const xAtYMin = (yMin - aY) / slope + aX;
|
|
28274
|
+
const xAtYMax = (yMax - aY) / slope + aX;
|
|
28275
|
+
|
|
28276
|
+
// clock analogy to describe quadrants
|
|
28277
|
+
switch (true) {
|
|
28278
|
+
// 12 o'clock to 2:59
|
|
28279
|
+
case yDiff > 0 && xDiff >= 0:
|
|
28280
|
+
return xAtYMax > xMax ? [xMax, yAtXMax] : [xAtYMax, yMax];
|
|
28281
|
+
// 3 o'clock to 5:59
|
|
28282
|
+
case yDiff <= 0 && xDiff > 0:
|
|
28283
|
+
// xAtYMin evaluates to -Infinity here, so we use absolute value
|
|
28284
|
+
return Math.abs(xAtYMin) > xMax ? [xMax, yAtXMax] : [xAtYMin, yMin];
|
|
28285
|
+
// 9 o'clock to 11:59
|
|
28286
|
+
case yDiff >= 0 && xDiff < 0:
|
|
28287
|
+
return xAtYMax < xMin ? [xMin, yAtXMin] : [xAtYMax, yMax];
|
|
28288
|
+
// 6 o'clock to 8:59
|
|
28289
|
+
case yDiff < 0 && xDiff <= 0:
|
|
28290
|
+
return xAtYMin < xMin ? [xMin, yAtXMin] : [xAtYMin, yMin];
|
|
28291
|
+
default:
|
|
28292
|
+
return [xMax, yAtXMax];
|
|
28293
|
+
}
|
|
28294
|
+
};
|
|
28295
|
+
|
|
28296
|
+
const StyledMovablePoint = props => {
|
|
28170
28297
|
const hitboxRef = useRef(null);
|
|
28171
28298
|
const {
|
|
28172
28299
|
point,
|
|
28173
|
-
onMove
|
|
28300
|
+
onMove,
|
|
28301
|
+
color = Color.blue
|
|
28174
28302
|
} = props;
|
|
28175
28303
|
const {
|
|
28176
28304
|
dragging
|
|
@@ -28194,11 +28322,11 @@ const MovablePoint$1 = props => {
|
|
|
28194
28322
|
cursor: dragging ? "grabbing" : "grab",
|
|
28195
28323
|
touchAction: "none",
|
|
28196
28324
|
outline: "none",
|
|
28197
|
-
"--movable-point-color":
|
|
28325
|
+
"--movable-point-color": color
|
|
28198
28326
|
}
|
|
28199
28327
|
}, /*#__PURE__*/React.createElement("circle", {
|
|
28200
28328
|
className: "movable-point-hitbox",
|
|
28201
|
-
r:
|
|
28329
|
+
r: 22,
|
|
28202
28330
|
cx: x,
|
|
28203
28331
|
cy: y
|
|
28204
28332
|
}), /*#__PURE__*/React.createElement("circle", {
|
|
@@ -28214,7 +28342,7 @@ const MovablePoint$1 = props => {
|
|
|
28214
28342
|
cx: x,
|
|
28215
28343
|
cy: y,
|
|
28216
28344
|
style: {
|
|
28217
|
-
fill:
|
|
28345
|
+
fill: color
|
|
28218
28346
|
}
|
|
28219
28347
|
}));
|
|
28220
28348
|
};
|
|
@@ -28224,16 +28352,16 @@ const SegmentGraph = props => {
|
|
|
28224
28352
|
dispatch
|
|
28225
28353
|
} = props;
|
|
28226
28354
|
const {
|
|
28227
|
-
segments,
|
|
28355
|
+
coords: segments,
|
|
28228
28356
|
snapStep,
|
|
28229
28357
|
range
|
|
28230
28358
|
} = props.graphState;
|
|
28231
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, segments.map((segment, i) => /*#__PURE__*/React.createElement(SegmentView, {
|
|
28359
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, segments == null ? void 0 : segments.map((segment, i) => /*#__PURE__*/React.createElement(SegmentView, {
|
|
28232
28360
|
key: i,
|
|
28233
|
-
|
|
28361
|
+
collinearPair: segment,
|
|
28234
28362
|
snaps: snapStep,
|
|
28235
28363
|
range: range,
|
|
28236
|
-
|
|
28364
|
+
onMoveLine: delta => {
|
|
28237
28365
|
dispatch(moveSegment(i, delta));
|
|
28238
28366
|
},
|
|
28239
28367
|
onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(i, endpointIndex, destination)),
|
|
@@ -28242,75 +28370,83 @@ const SegmentGraph = props => {
|
|
|
28242
28370
|
};
|
|
28243
28371
|
const SegmentView = props => {
|
|
28244
28372
|
const {
|
|
28245
|
-
onMoveSegment,
|
|
28246
|
-
|
|
28373
|
+
onMoveLine: onMoveSegment,
|
|
28374
|
+
collinearPair: [start, end]
|
|
28247
28375
|
} = props;
|
|
28248
|
-
|
|
28249
|
-
|
|
28250
|
-
|
|
28251
|
-
|
|
28252
|
-
}
|
|
28253
|
-
|
|
28254
|
-
point: midpoint,
|
|
28255
|
-
onMove: newPoint => {
|
|
28256
|
-
onMoveSegment(vec.sub(newPoint, midpoint));
|
|
28257
|
-
},
|
|
28258
|
-
constrain: p => p
|
|
28259
|
-
});
|
|
28260
|
-
const {
|
|
28261
|
-
viewTransform,
|
|
28262
|
-
userTransform
|
|
28263
|
-
} = useTransformContext();
|
|
28264
|
-
const transformToPx = vec.matrixMult(viewTransform, userTransform);
|
|
28265
|
-
const pt1Px = vec.transform(pt1, transformToPx);
|
|
28266
|
-
const pt2Px = vec.transform(pt2, transformToPx);
|
|
28267
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("g", {
|
|
28268
|
-
ref: segment,
|
|
28269
|
-
tabIndex: 0,
|
|
28270
|
-
className: "movable-segment",
|
|
28271
|
-
style: {
|
|
28272
|
-
cursor: isDraggingSegment ? "grabbing" : "grab"
|
|
28273
|
-
}
|
|
28274
|
-
}, /*#__PURE__*/React.createElement(SVGLine, {
|
|
28275
|
-
start: pt1Px,
|
|
28276
|
-
end: pt2Px,
|
|
28277
|
-
style: {
|
|
28278
|
-
stroke: "transparent",
|
|
28279
|
-
strokeWidth: 30
|
|
28280
|
-
}
|
|
28281
|
-
}), /*#__PURE__*/React.createElement(SVGLine, {
|
|
28282
|
-
start: pt1Px,
|
|
28283
|
-
end: pt2Px,
|
|
28284
|
-
style: {
|
|
28285
|
-
stroke: "var(--mafs-segment-stroke-color)",
|
|
28286
|
-
strokeWidth: "var(--mafs-segment-stroke-weight)"
|
|
28287
|
-
}
|
|
28288
|
-
})), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
28289
|
-
point: pt1,
|
|
28376
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MovableLine, {
|
|
28377
|
+
start: start,
|
|
28378
|
+
end: end,
|
|
28379
|
+
onMove: onMoveSegment
|
|
28380
|
+
}), /*#__PURE__*/React.createElement(StyledMovablePoint, {
|
|
28381
|
+
point: start,
|
|
28290
28382
|
onMove: newPoint => {
|
|
28291
28383
|
props.onMovePoint(0, newPoint);
|
|
28292
28384
|
}
|
|
28293
|
-
}), /*#__PURE__*/React.createElement(
|
|
28294
|
-
point:
|
|
28385
|
+
}), /*#__PURE__*/React.createElement(StyledMovablePoint, {
|
|
28386
|
+
point: end,
|
|
28295
28387
|
onMove: newPoint => {
|
|
28296
28388
|
props.onMovePoint(1, newPoint);
|
|
28297
28389
|
}
|
|
28298
28390
|
}));
|
|
28299
28391
|
};
|
|
28300
|
-
|
|
28392
|
+
|
|
28393
|
+
const LinearGraph = props => {
|
|
28301
28394
|
const {
|
|
28302
|
-
|
|
28303
|
-
end,
|
|
28304
|
-
style
|
|
28395
|
+
dispatch
|
|
28305
28396
|
} = props;
|
|
28306
|
-
|
|
28307
|
-
|
|
28308
|
-
|
|
28309
|
-
|
|
28310
|
-
|
|
28311
|
-
|
|
28312
|
-
|
|
28313
|
-
|
|
28397
|
+
const {
|
|
28398
|
+
coords: lines,
|
|
28399
|
+
snapStep,
|
|
28400
|
+
range,
|
|
28401
|
+
type
|
|
28402
|
+
} = props.graphState;
|
|
28403
|
+
const colors = ["var(--movable-line-stroke-color)", "var(--mafs-violet)"];
|
|
28404
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, lines == null ? void 0 : lines.map((line, i) => /*#__PURE__*/React.createElement(LineView, {
|
|
28405
|
+
key: i,
|
|
28406
|
+
collinearPair: line,
|
|
28407
|
+
snaps: snapStep,
|
|
28408
|
+
range: range,
|
|
28409
|
+
onMoveLine: delta => {
|
|
28410
|
+
dispatch(moveSegment(i, delta));
|
|
28411
|
+
},
|
|
28412
|
+
onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(i, endpointIndex, destination))
|
|
28413
|
+
// "linear" or "linear-system" + index
|
|
28414
|
+
,
|
|
28415
|
+
"data-testid": type + i,
|
|
28416
|
+
stroke: colors[i]
|
|
28417
|
+
})));
|
|
28418
|
+
};
|
|
28419
|
+
const LineView = props => {
|
|
28420
|
+
const {
|
|
28421
|
+
onMoveLine: onMoveSegment,
|
|
28422
|
+
collinearPair: [start, end],
|
|
28423
|
+
range,
|
|
28424
|
+
stroke
|
|
28425
|
+
} = props;
|
|
28426
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MovableLine, {
|
|
28427
|
+
start: start,
|
|
28428
|
+
end: end,
|
|
28429
|
+
onMove: onMoveSegment,
|
|
28430
|
+
extend: {
|
|
28431
|
+
start: true,
|
|
28432
|
+
end: true,
|
|
28433
|
+
range
|
|
28434
|
+
},
|
|
28435
|
+
stroke: stroke
|
|
28436
|
+
}), /*#__PURE__*/React.createElement(StyledMovablePoint, {
|
|
28437
|
+
point: start,
|
|
28438
|
+
onMove: newPoint => {
|
|
28439
|
+
props.onMovePoint(0, newPoint);
|
|
28440
|
+
},
|
|
28441
|
+
color: stroke
|
|
28442
|
+
}), /*#__PURE__*/React.createElement(StyledMovablePoint, {
|
|
28443
|
+
point: end,
|
|
28444
|
+
onMove: newPoint => {
|
|
28445
|
+
props.onMovePoint(1, newPoint);
|
|
28446
|
+
},
|
|
28447
|
+
color: stroke
|
|
28448
|
+
}));
|
|
28449
|
+
};
|
|
28314
28450
|
|
|
28315
28451
|
const renderLineLabel = (n, [min, max]) => n !== -1 && n !== min && n !== max;
|
|
28316
28452
|
const axisOptions = (props, index) => ({
|
|
@@ -28326,33 +28462,49 @@ const Grid = props => props.markings === "none" ? null : /*#__PURE__*/React.crea
|
|
|
28326
28462
|
|
|
28327
28463
|
function interactiveGraphReducer(state, action) {
|
|
28328
28464
|
switch (action.type) {
|
|
28329
|
-
case
|
|
28465
|
+
case MOVE_CONTROL_POINT:
|
|
28330
28466
|
{
|
|
28331
|
-
const
|
|
28332
|
-
|
|
28467
|
+
const newCoords = updateAtIndex({
|
|
28468
|
+
array: state.coords,
|
|
28469
|
+
index: action.objectIndex,
|
|
28470
|
+
update: tuple => setAtIndex({
|
|
28471
|
+
array: tuple,
|
|
28472
|
+
index: action.pointIndex,
|
|
28473
|
+
newValue: snap(state, bound$1(state, action.destination))
|
|
28474
|
+
})
|
|
28475
|
+
});
|
|
28476
|
+
if (!validSegments(newCoords)) {
|
|
28333
28477
|
return state;
|
|
28334
28478
|
}
|
|
28335
28479
|
return _extends({}, state, {
|
|
28336
28480
|
hasBeenInteractedWith: true,
|
|
28337
|
-
|
|
28481
|
+
coords: newCoords
|
|
28338
28482
|
});
|
|
28339
28483
|
}
|
|
28340
|
-
case
|
|
28484
|
+
case MOVE_LINE:
|
|
28341
28485
|
{
|
|
28342
|
-
|
|
28343
|
-
const
|
|
28344
|
-
|
|
28486
|
+
var _state$coords;
|
|
28487
|
+
const currentLine = (_state$coords = state.coords) == null ? void 0 : _state$coords[action.lineIndex];
|
|
28488
|
+
if (!currentLine) {
|
|
28489
|
+
throw new Error("No line to move");
|
|
28490
|
+
}
|
|
28491
|
+
const maxMoves = currentLine.map(point => maxMove(state, point));
|
|
28492
|
+
const minMoves = currentLine.map(point => minMove(state, point));
|
|
28345
28493
|
const maxXMove = Math.min(...maxMoves.map(move => move[0]));
|
|
28346
28494
|
const maxYMove = Math.min(...maxMoves.map(move => move[1]));
|
|
28347
28495
|
const minXMove = Math.max(...minMoves.map(move => move[0]));
|
|
28348
28496
|
const minYMove = Math.max(...minMoves.map(move => move[1]));
|
|
28349
28497
|
const dx = clamp(action.delta[0], minXMove, maxXMove);
|
|
28350
28498
|
const dy = clamp(action.delta[1], minYMove, maxYMove);
|
|
28351
|
-
const
|
|
28352
|
-
const
|
|
28499
|
+
const newValue = [snap(state, vec.add(currentLine[0], [dx, dy])), snap(state, vec.add(currentLine[1], [dx, dy]))];
|
|
28500
|
+
const newLine = setAtIndex({
|
|
28501
|
+
array: state.coords,
|
|
28502
|
+
index: action.lineIndex,
|
|
28503
|
+
newValue
|
|
28504
|
+
});
|
|
28353
28505
|
return _extends({}, state, {
|
|
28354
28506
|
hasBeenInteractedWith: true,
|
|
28355
|
-
|
|
28507
|
+
coords: newLine
|
|
28356
28508
|
});
|
|
28357
28509
|
}
|
|
28358
28510
|
default:
|
|
@@ -28398,12 +28550,28 @@ function clamp(value, min, max) {
|
|
|
28398
28550
|
function validSegments(segments) {
|
|
28399
28551
|
return segments.every(([start, end]) => !vector$1.equal(start, end));
|
|
28400
28552
|
}
|
|
28401
|
-
function updateAtIndex(
|
|
28402
|
-
|
|
28553
|
+
function updateAtIndex(args) {
|
|
28554
|
+
const {
|
|
28555
|
+
array = [],
|
|
28556
|
+
index,
|
|
28557
|
+
update
|
|
28558
|
+
} = args;
|
|
28559
|
+
const newValue = update(array[index]);
|
|
28560
|
+
return setAtIndex({
|
|
28561
|
+
array,
|
|
28562
|
+
index,
|
|
28563
|
+
newValue
|
|
28564
|
+
});
|
|
28403
28565
|
}
|
|
28404
|
-
function setAtIndex(
|
|
28405
|
-
const
|
|
28566
|
+
function setAtIndex(args) {
|
|
28567
|
+
const {
|
|
28568
|
+
array,
|
|
28569
|
+
index,
|
|
28570
|
+
newValue
|
|
28571
|
+
} = args;
|
|
28572
|
+
const copy = [...(array || [])];
|
|
28406
28573
|
copy[index] = newValue;
|
|
28574
|
+
// restoring readonly to array
|
|
28407
28575
|
return copy;
|
|
28408
28576
|
}
|
|
28409
28577
|
|
|
@@ -28441,12 +28609,24 @@ function initializeGraphState(params) {
|
|
|
28441
28609
|
hasBeenInteractedWith: false,
|
|
28442
28610
|
range,
|
|
28443
28611
|
snapStep,
|
|
28444
|
-
|
|
28612
|
+
coords: getDefaultSegments({
|
|
28445
28613
|
graph,
|
|
28446
28614
|
step,
|
|
28447
28615
|
range
|
|
28448
28616
|
})
|
|
28449
28617
|
};
|
|
28618
|
+
// Ray can also fall through into this case-- same type, same default coords
|
|
28619
|
+
case "linear":
|
|
28620
|
+
case "linear-system":
|
|
28621
|
+
return {
|
|
28622
|
+
type: graph.type,
|
|
28623
|
+
hasBeenInteractedWith: false,
|
|
28624
|
+
range,
|
|
28625
|
+
snapStep,
|
|
28626
|
+
// A linear graph has a single tuple of points, while a linear
|
|
28627
|
+
// system has two tuples of points.
|
|
28628
|
+
coords: getLineCoords(graph, range, step)
|
|
28629
|
+
};
|
|
28450
28630
|
}
|
|
28451
28631
|
throw new Error("Mafs not yet implemented for graph type: " + graph.type);
|
|
28452
28632
|
}
|
|
@@ -28475,6 +28655,38 @@ const getDefaultSegments = props => {
|
|
|
28475
28655
|
});
|
|
28476
28656
|
};
|
|
28477
28657
|
|
|
28658
|
+
// TS v4 doesn't narrow return types, while v5 does.
|
|
28659
|
+
// Instead of updating to v5, using generic type to relate input and output types.
|
|
28660
|
+
function getGradableGraph(state, initialGraph) {
|
|
28661
|
+
var _state$coords;
|
|
28662
|
+
if (!state.hasBeenInteractedWith) {
|
|
28663
|
+
return initialGraph;
|
|
28664
|
+
}
|
|
28665
|
+
switch (true) {
|
|
28666
|
+
// coords: Array of CollinearTuple
|
|
28667
|
+
case state.type === "linear-system" && initialGraph.type === "linear-system":
|
|
28668
|
+
case state.type === "segment" && initialGraph.type === "segment":
|
|
28669
|
+
return _extends({}, initialGraph, {
|
|
28670
|
+
coords: state.coords
|
|
28671
|
+
});
|
|
28672
|
+
// RAY has the same type as below; can fall through
|
|
28673
|
+
// coords: CollinearTuple
|
|
28674
|
+
case state.type === "linear" && initialGraph.type === "linear":
|
|
28675
|
+
return _extends({}, initialGraph, {
|
|
28676
|
+
coords: (_state$coords = state.coords) == null ? void 0 : _state$coords[0]
|
|
28677
|
+
});
|
|
28678
|
+
}
|
|
28679
|
+
throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
|
|
28680
|
+
}
|
|
28681
|
+
const defaultLinearCoords = [[[0.25, 0.75], [0.75, 0.75]], [[0.25, 0.25], [0.75, 0.25]]];
|
|
28682
|
+
const getLineCoords = (graph, range, step) => {
|
|
28683
|
+
var _graph$coords;
|
|
28684
|
+
return (
|
|
28685
|
+
// Return two lines for a linear system, one for a ray or linear
|
|
28686
|
+
((_graph$coords = graph.coords) != null ? _graph$coords : graph.type === "linear-system") ? defaultLinearCoords.map(collinear => normalizePoints(range, step, collinear)) : [normalizePoints(range, step, defaultLinearCoords[0])]
|
|
28687
|
+
);
|
|
28688
|
+
};
|
|
28689
|
+
|
|
28478
28690
|
// Displays a stylized open eye: lint warnings are visible
|
|
28479
28691
|
const VisibleIcon = () => /*#__PURE__*/React.createElement("svg", {
|
|
28480
28692
|
width: "24",
|
|
@@ -29172,27 +29384,25 @@ const renderGraph = props => {
|
|
|
29172
29384
|
state,
|
|
29173
29385
|
dispatch
|
|
29174
29386
|
} = props;
|
|
29175
|
-
|
|
29387
|
+
const {
|
|
29388
|
+
type
|
|
29389
|
+
} = state;
|
|
29390
|
+
switch (type) {
|
|
29176
29391
|
case "segment":
|
|
29177
29392
|
return /*#__PURE__*/React.createElement(SegmentGraph, {
|
|
29178
29393
|
graphState: state,
|
|
29179
29394
|
dispatch: dispatch
|
|
29180
29395
|
});
|
|
29181
|
-
|
|
29182
|
-
|
|
29183
|
-
|
|
29184
|
-
|
|
29185
|
-
|
|
29186
|
-
return initialGraph;
|
|
29187
|
-
}
|
|
29188
|
-
switch (initialGraph.type) {
|
|
29189
|
-
case "segment":
|
|
29190
|
-
return _extends({}, initialGraph, {
|
|
29191
|
-
coords: state.segments
|
|
29396
|
+
case "linear":
|
|
29397
|
+
case "linear-system":
|
|
29398
|
+
return /*#__PURE__*/React.createElement(LinearGraph, {
|
|
29399
|
+
graphState: state,
|
|
29400
|
+
dispatch: dispatch
|
|
29192
29401
|
});
|
|
29402
|
+
default:
|
|
29403
|
+
return new UnreachableCaseError(type);
|
|
29193
29404
|
}
|
|
29194
|
-
|
|
29195
|
-
}
|
|
29405
|
+
};
|
|
29196
29406
|
const MafsGraph = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
29197
29407
|
var _props$backgroundImag, _props$backgroundImag2, _props$backgroundImag3, _props$backgroundImag4;
|
|
29198
29408
|
const [width, height] = props.box;
|
|
@@ -41234,7 +41444,7 @@ const init = function init(options) {
|
|
|
41234
41444
|
|
|
41235
41445
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41236
41446
|
const libName = "@khanacademy/perseus";
|
|
41237
|
-
const libVersion = "20.
|
|
41447
|
+
const libVersion = "20.4.0";
|
|
41238
41448
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41239
41449
|
|
|
41240
41450
|
const apiVersion = {
|
|
@@ -42259,8 +42469,9 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
42259
42469
|
// TODO(FEI-4010): Remove `Perseus` prefix for all types here
|
|
42260
42470
|
// TODO(FEI-4011): Use types generated by https://github.com/jaredly/generate-perseus-flowtypes
|
|
42261
42471
|
|
|
42472
|
+
// Range is replaced within this file with Interval, but it is used elsewhere
|
|
42473
|
+
// and exported from the package, so we need to keep it around.
|
|
42262
42474
|
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
42263
|
-
|
|
42264
42475
|
const ItemExtras = [
|
|
42265
42476
|
// The user might benefit from using a Scientific Calculator. Provided on Khan Academy when true
|
|
42266
42477
|
"calculator",
|