@khanacademy/perseus 22.6.0 → 23.0.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 +5 -9
- package/dist/es/index.js +118 -27
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +5 -9
- package/dist/index.js +120 -26
- package/dist/index.js.map +1 -1
- package/dist/perseus-api.d.ts +1 -6
- package/dist/perseus-types.d.ts +1 -2
- package/dist/server-item-renderer.d.ts +1 -2
- package/dist/types.d.ts +1 -8
- package/dist/widgets/definition.d.ts +0 -1
- package/dist/widgets/explanation.d.ts +0 -1
- package/dist/widgets/expression.d.ts +8 -26
- package/dist/widgets/interactive-graph.d.ts +2 -1
- package/dist/widgets/interactive-graphs/graphs/index.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/quadratic.d.ts +9 -0
- package/dist/widgets/interactive-graphs/mafs-supported-graph-types.d.ts +1 -1
- package/dist/widgets/interactive-graphs/types.d.ts +5 -1
- package/dist/widgets/label-image.d.ts +2 -4
- package/dist/widgets/matcher.d.ts +0 -2
- package/dist/widgets/sorter.d.ts +0 -2
- package/package.json +4 -4
package/dist/index.css
CHANGED
|
@@ -4488,6 +4488,9 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4488
4488
|
format("woff");
|
|
4489
4489
|
}
|
|
4490
4490
|
|
|
4491
|
+
.MafsView pattern g {
|
|
4492
|
+
stroke: rgba(33, 36, 44, 0.32);
|
|
4493
|
+
}
|
|
4491
4494
|
.axis-tick-labels {
|
|
4492
4495
|
font-size: 14px;
|
|
4493
4496
|
font-family: "Mafs-MJXTEX";
|
|
@@ -4496,6 +4499,8 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4496
4499
|
* drag interactions on the graph. */
|
|
4497
4500
|
user-select: none;
|
|
4498
4501
|
pointer-events: none;
|
|
4502
|
+
/* Prevent labels from covering up interaction points. */
|
|
4503
|
+
z-index: -1;
|
|
4499
4504
|
}
|
|
4500
4505
|
|
|
4501
4506
|
.y-axis-tick-labels {
|
|
@@ -4520,15 +4525,6 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4520
4525
|
transform: translateY(calc(-100% + 0.25em));
|
|
4521
4526
|
}
|
|
4522
4527
|
|
|
4523
|
-
.x-axis-tick-labels span,
|
|
4524
|
-
.y-axis-tick-labels span {
|
|
4525
|
-
&::before {
|
|
4526
|
-
content: attr(data-content);
|
|
4527
|
-
position: absolute;
|
|
4528
|
-
transform: translate(-100%);
|
|
4529
|
-
}
|
|
4530
|
-
}
|
|
4531
|
-
|
|
4532
4528
|
.y-axis-tick-labels span {
|
|
4533
4529
|
display: inline-block;
|
|
4534
4530
|
height: var(--y-axis-label-height, 20px);
|
package/dist/index.js
CHANGED
|
@@ -1245,8 +1245,6 @@ const ApiOptions = {
|
|
|
1245
1245
|
// drawing area (scratchpad) should be allowed/disallowed.
|
|
1246
1246
|
// Previously handled by `Khan.scratchpad.enable/disable`
|
|
1247
1247
|
setDrawingAreaAvailable: PropTypes__default["default"].func,
|
|
1248
|
-
// Whether to use the Draft.js editor or the legacy textarea
|
|
1249
|
-
useDraftEditor: PropTypes__default["default"].bool,
|
|
1250
1248
|
// The color used for the hint progress indicator (eg. 1 / 3)
|
|
1251
1249
|
hintProgressColor: PropTypes__default["default"].string,
|
|
1252
1250
|
// Whether this Renderer is allowed to auto-scroll the rest of the
|
|
@@ -1256,8 +1254,6 @@ const ApiOptions = {
|
|
|
1256
1254
|
//
|
|
1257
1255
|
// Defaults to `false`.
|
|
1258
1256
|
canScrollPage: PropTypes__default["default"].bool,
|
|
1259
|
-
// Whether or not we are rendering content inside of a modal.
|
|
1260
|
-
inModal: PropTypes__default["default"].bool,
|
|
1261
1257
|
// Whether to enable the cross-out feature on multiple-choice radio
|
|
1262
1258
|
// widgets. This allows users to note which answers they believe to
|
|
1263
1259
|
// be incorrect, to find the answer by process of elimination.
|
|
@@ -1293,9 +1289,7 @@ const ApiOptions = {
|
|
|
1293
1289
|
}
|
|
1294
1290
|
},
|
|
1295
1291
|
setDrawingAreaAvailable: function () {},
|
|
1296
|
-
useDraftEditor: false,
|
|
1297
1292
|
canScrollPage: false,
|
|
1298
|
-
inModal: false,
|
|
1299
1293
|
crossOutEnabled: false,
|
|
1300
1294
|
editorChangeDelay: 0
|
|
1301
1295
|
}
|
|
@@ -25197,8 +25191,6 @@ var CSProgram$1 = {
|
|
|
25197
25191
|
hidden: true
|
|
25198
25192
|
};
|
|
25199
25193
|
|
|
25200
|
-
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
25201
|
-
|
|
25202
25194
|
class Definition extends React__namespace.Component {
|
|
25203
25195
|
static contextType = PerseusI18nContext;
|
|
25204
25196
|
static defaultProps = {
|
|
@@ -25410,8 +25402,6 @@ var Dropdown$1 = {
|
|
|
25410
25402
|
|
|
25411
25403
|
/* eslint-disable react/sort-comp */
|
|
25412
25404
|
|
|
25413
|
-
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
25414
|
-
|
|
25415
25405
|
// transform = _.identity
|
|
25416
25406
|
|
|
25417
25407
|
function mediaQueryIsMatched(mediaQuery) {
|
|
@@ -28868,7 +28858,6 @@ function AxisLabels() {
|
|
|
28868
28858
|
|
|
28869
28859
|
// Range is replaced within this file with Interval, but it is used elsewhere
|
|
28870
28860
|
// and exported from the package, so we need to keep it around.
|
|
28871
|
-
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
28872
28861
|
const ItemExtras = [
|
|
28873
28862
|
// The user might benefit from using a Scientific Calculator. Provided on Khan Academy when true
|
|
28874
28863
|
"calculator",
|
|
@@ -30048,9 +30037,14 @@ function initializeGraphState(params) {
|
|
|
30048
30037
|
center: [0, 0],
|
|
30049
30038
|
radiusPoint: [1, 0]
|
|
30050
30039
|
};
|
|
30040
|
+
case "quadratic":
|
|
30041
|
+
return {
|
|
30042
|
+
...shared,
|
|
30043
|
+
type: graph.type,
|
|
30044
|
+
coords: getQuadraticCoords(graph, range, step)
|
|
30045
|
+
};
|
|
30051
30046
|
case "angle":
|
|
30052
30047
|
case "sinusoid":
|
|
30053
|
-
case "quadratic":
|
|
30054
30048
|
throw new Error("Mafs not yet implemented for graph type: " + graph.type);
|
|
30055
30049
|
default:
|
|
30056
30050
|
throw new wonderStuffCore.UnreachableCaseError(graph);
|
|
@@ -30148,6 +30142,12 @@ function getGradableGraph(state, initialGraph) {
|
|
|
30148
30142
|
radius: getRadius(state)
|
|
30149
30143
|
};
|
|
30150
30144
|
}
|
|
30145
|
+
if (state.type === "quadratic" && initialGraph.type === "quadratic") {
|
|
30146
|
+
return {
|
|
30147
|
+
...initialGraph,
|
|
30148
|
+
coords: state.coords
|
|
30149
|
+
};
|
|
30150
|
+
}
|
|
30151
30151
|
throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
|
|
30152
30152
|
}
|
|
30153
30153
|
const getDefaultSegments = _ref2 => {
|
|
@@ -30227,6 +30227,11 @@ const getPolygonCoords = _ref4 => {
|
|
|
30227
30227
|
coords = normalizePoints(range, step, coords, /* noSnap */!snapToGrid);
|
|
30228
30228
|
return coords;
|
|
30229
30229
|
};
|
|
30230
|
+
const getQuadraticCoords = (graph, range, step) => {
|
|
30231
|
+
let coords = [[0.25, 0.75], [0.5, 0.25], [0.75, 0.75]];
|
|
30232
|
+
coords = normalizePoints(range, step, coords, true);
|
|
30233
|
+
return coords;
|
|
30234
|
+
};
|
|
30230
30235
|
|
|
30231
30236
|
/**
|
|
30232
30237
|
* determine radius of a circle graph
|
|
@@ -30336,6 +30341,82 @@ function crossProduct(as, bs) {
|
|
|
30336
30341
|
return result;
|
|
30337
30342
|
}
|
|
30338
30343
|
|
|
30344
|
+
function QuadraticGraph(props) {
|
|
30345
|
+
const {
|
|
30346
|
+
dispatch,
|
|
30347
|
+
graphState
|
|
30348
|
+
} = props;
|
|
30349
|
+
const {
|
|
30350
|
+
coords
|
|
30351
|
+
} = graphState;
|
|
30352
|
+
|
|
30353
|
+
// The coefficients are used to calculate the quadratic equation, plot the graph, and to indicate
|
|
30354
|
+
// to content creators the currently selected "correct answer". ex: y = 0.200x^2 + 0.000x + 0.000
|
|
30355
|
+
// While we should technically never have invalid coordinates, we want to ensure that we have a fallback
|
|
30356
|
+
const coeffRef = React__namespace.useRef([0, 0, 0]);
|
|
30357
|
+
const coeffs = getQuadraticCoefficients(coords);
|
|
30358
|
+
if (coeffs !== undefined) {
|
|
30359
|
+
coeffRef.current = coeffs;
|
|
30360
|
+
}
|
|
30361
|
+
|
|
30362
|
+
// Destructure the coefficients for calculating the quadratic equation
|
|
30363
|
+
const [a, b, c] = coeffRef.current;
|
|
30364
|
+
|
|
30365
|
+
// Calculate the y value based on the current x value
|
|
30366
|
+
const y = x => (a * x + b) * x + c;
|
|
30367
|
+
const handleOnMove = (destination, elementId) => {
|
|
30368
|
+
// If the destination is invalid, we want do not want to move the point
|
|
30369
|
+
const validDestination = isValidDestination(destination, elementId, coords);
|
|
30370
|
+
if (validDestination === false) {
|
|
30371
|
+
return;
|
|
30372
|
+
}
|
|
30373
|
+
dispatch(movePoint(elementId, destination));
|
|
30374
|
+
};
|
|
30375
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Plot.OfX, {
|
|
30376
|
+
y: y,
|
|
30377
|
+
color: wonderBlocksTokens.color.blue
|
|
30378
|
+
}), coords.map((coord, i) => /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
|
|
30379
|
+
key: "point-" + i,
|
|
30380
|
+
point: coord,
|
|
30381
|
+
onMove: destination => handleOnMove(destination, i)
|
|
30382
|
+
})));
|
|
30383
|
+
}
|
|
30384
|
+
|
|
30385
|
+
// Ensure that we are only snapping to coordinates that result in a valid quadratic equation
|
|
30386
|
+
const isValidDestination = (destination, elementId, coords) => {
|
|
30387
|
+
// Set up the new coords and check if the quadratic coefficients are valid
|
|
30388
|
+
const newCoords = [...coords];
|
|
30389
|
+
newCoords[elementId] = destination;
|
|
30390
|
+
const QuadraticCoefficients = getQuadraticCoefficients(newCoords);
|
|
30391
|
+
|
|
30392
|
+
// If the new destination results in an invalid quadratic equation, we don't want to move the point
|
|
30393
|
+
if (QuadraticCoefficients === undefined) {
|
|
30394
|
+
return false;
|
|
30395
|
+
}
|
|
30396
|
+
return true;
|
|
30397
|
+
};
|
|
30398
|
+
|
|
30399
|
+
// Get the quadratic coefficients from the 3 control points
|
|
30400
|
+
// These equations were originally set up in 2013 and may require some
|
|
30401
|
+
// additional comments to help clarify the quadratic formula manipulations
|
|
30402
|
+
// Origin: https://phabricator.khanacademy.org/D2413
|
|
30403
|
+
const getQuadraticCoefficients = coords => {
|
|
30404
|
+
const p1 = coords[0];
|
|
30405
|
+
const p2 = coords[1];
|
|
30406
|
+
const p3 = coords[2];
|
|
30407
|
+
|
|
30408
|
+
// If the denominator is 0, we are going to return undefined as we are
|
|
30409
|
+
// unable to calculate the quadratic coefficients when they hit infinity
|
|
30410
|
+
const denom = (p1[0] - p2[0]) * (p1[0] - p3[0]) * (p2[0] - p3[0]);
|
|
30411
|
+
if (denom === 0) {
|
|
30412
|
+
return;
|
|
30413
|
+
}
|
|
30414
|
+
const a = (p3[0] * (p2[1] - p1[1]) + p2[0] * (p1[1] - p3[1]) + p1[0] * (p3[1] - p2[1])) / denom;
|
|
30415
|
+
const b = (p3[0] * p3[0] * (p1[1] - p2[1]) + p2[0] * p2[0] * (p3[1] - p1[1]) + p1[0] * p1[0] * (p2[1] - p3[1])) / denom;
|
|
30416
|
+
const c = (p2[0] * p3[0] * (p2[0] - p3[0]) * p1[1] + p3[0] * p1[0] * (p3[0] - p1[0]) * p2[1] + p1[0] * p2[0] * (p1[0] - p2[0]) * p3[1]) / denom;
|
|
30417
|
+
return [a, b, c];
|
|
30418
|
+
};
|
|
30419
|
+
|
|
30339
30420
|
// Universal padding for the axis ticks to ensure that the labels
|
|
30340
30421
|
// have enough space to render without overlapping the tick lines
|
|
30341
30422
|
const tickPadding = 5;
|
|
@@ -30496,9 +30577,6 @@ const AxisTickLabel = _ref => {
|
|
|
30496
30577
|
const pointOnAxis = axis === "x" ? [label, 0] : [0, label];
|
|
30497
30578
|
const pixelPoint = pointToPixel(pointOnAxis, graphConfig);
|
|
30498
30579
|
|
|
30499
|
-
// Remove the negative sign from the label string as it is handled in the data-content attribute
|
|
30500
|
-
const labelString = Math.abs(label).toString();
|
|
30501
|
-
|
|
30502
30580
|
// Determine the relevant edge of the graph based on the axis type
|
|
30503
30581
|
const graphEdge = axis === "x" ? graphConfig.width : graphConfig.height;
|
|
30504
30582
|
|
|
@@ -30514,15 +30592,9 @@ const AxisTickLabel = _ref => {
|
|
|
30514
30592
|
gridStep: gridStep[vectorIndex],
|
|
30515
30593
|
tickStep: tickStep[vectorIndex]
|
|
30516
30594
|
});
|
|
30517
|
-
|
|
30518
|
-
// Determine whether or not to render a negative symbol for the tick label
|
|
30519
|
-
// as the negative sign is handled in the data-content attribute in order to
|
|
30520
|
-
// maintain the correct spacing between the labels
|
|
30521
|
-
const dataContent = label < 0 && shouldShowLabel ? "−" : null;
|
|
30522
30595
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
30523
|
-
className: `${axis}-axis-tick-label
|
|
30524
|
-
|
|
30525
|
-
}, shouldShowLabel && labelString);
|
|
30596
|
+
className: `${axis}-axis-tick-label`
|
|
30597
|
+
}, shouldShowLabel && label);
|
|
30526
30598
|
};
|
|
30527
30599
|
|
|
30528
30600
|
// Determine whether or not to show the tick label text
|
|
@@ -31477,6 +31549,7 @@ function doMoveControlPoint(state, action) {
|
|
|
31477
31549
|
throw new Error("FIXME implement circle reducer");
|
|
31478
31550
|
case "point":
|
|
31479
31551
|
case "polygon":
|
|
31552
|
+
case "quadratic":
|
|
31480
31553
|
throw new Error(`Don't use moveControlPoint for ${state.type} graphs. Use movePoint instead!`);
|
|
31481
31554
|
default:
|
|
31482
31555
|
throw new wonderStuffCore.UnreachableCaseError(state);
|
|
@@ -31549,8 +31622,24 @@ function doMoveAll(state, action) {
|
|
|
31549
31622
|
}
|
|
31550
31623
|
function doMovePoint(state, action) {
|
|
31551
31624
|
switch (state.type) {
|
|
31552
|
-
case "point":
|
|
31553
31625
|
case "polygon":
|
|
31626
|
+
case "point":
|
|
31627
|
+
{
|
|
31628
|
+
return {
|
|
31629
|
+
...state,
|
|
31630
|
+
hasBeenInteractedWith: true,
|
|
31631
|
+
coords: setAtIndex({
|
|
31632
|
+
array: state.coords,
|
|
31633
|
+
index: action.index,
|
|
31634
|
+
newValue: snap(state.snapStep, bound$1({
|
|
31635
|
+
snapStep: state.snapStep,
|
|
31636
|
+
range: state.range,
|
|
31637
|
+
point: action.destination
|
|
31638
|
+
}))
|
|
31639
|
+
})
|
|
31640
|
+
};
|
|
31641
|
+
}
|
|
31642
|
+
case "quadratic":
|
|
31554
31643
|
{
|
|
31555
31644
|
return {
|
|
31556
31645
|
...state,
|
|
@@ -31567,7 +31656,7 @@ function doMovePoint(state, action) {
|
|
|
31567
31656
|
};
|
|
31568
31657
|
}
|
|
31569
31658
|
default:
|
|
31570
|
-
throw new Error("The movePoint action is only for point and polygon graphs");
|
|
31659
|
+
throw new Error("The movePoint action is only for point, quadratic, and polygon graphs");
|
|
31571
31660
|
}
|
|
31572
31661
|
}
|
|
31573
31662
|
function doMoveCenter(state, action) {
|
|
@@ -31789,6 +31878,11 @@ const renderGraph = props => {
|
|
|
31789
31878
|
graphState: state,
|
|
31790
31879
|
dispatch: dispatch
|
|
31791
31880
|
});
|
|
31881
|
+
case "quadratic":
|
|
31882
|
+
return /*#__PURE__*/React__namespace.createElement(QuadraticGraph, {
|
|
31883
|
+
graphState: state,
|
|
31884
|
+
dispatch: dispatch
|
|
31885
|
+
});
|
|
31792
31886
|
default:
|
|
31793
31887
|
return new wonderStuffCore.UnreachableCaseError(type);
|
|
31794
31888
|
}
|
|
@@ -44002,7 +44096,7 @@ const init = function (options) {
|
|
|
44002
44096
|
|
|
44003
44097
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
44004
44098
|
const libName = "@khanacademy/perseus";
|
|
44005
|
-
const libVersion = "
|
|
44099
|
+
const libVersion = "23.0.0";
|
|
44006
44100
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
44007
44101
|
|
|
44008
44102
|
const apiVersion = {
|