@khanacademy/perseus 20.8.0 → 20.8.1
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 +315 -148
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +319 -141
- package/dist/index.js.map +1 -1
- package/dist/util/snowman-utils.d.ts +4 -5
- package/dist/widgets/interactive-graphs/graphs/components/angle.d.ts +13 -0
- package/dist/widgets/interactive-graphs/graphs/components/movable-point.d.ts +1 -1
- package/dist/widgets/interactive-graphs/graphs/use-transform.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/utils.d.ts +7 -0
- package/dist/widgets/interactive-graphs/legacy-grid.d.ts +6 -1
- package/dist/widgets/interactive-graphs/mafs-supported-graph-types.d.ts +3 -0
- package/package.json +2 -6
package/dist/index.js
CHANGED
|
@@ -12,9 +12,8 @@ var classNames = require('classnames');
|
|
|
12
12
|
var React = require('react');
|
|
13
13
|
var _ = require('underscore');
|
|
14
14
|
var Clickable = require('@khanacademy/wonder-blocks-clickable');
|
|
15
|
-
var Color = require('@khanacademy/wonder-blocks-color');
|
|
16
15
|
var wonderBlocksPopover = require('@khanacademy/wonder-blocks-popover');
|
|
17
|
-
var
|
|
16
|
+
var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
|
|
18
17
|
var aphrodite = require('aphrodite');
|
|
19
18
|
var $ = require('jquery');
|
|
20
19
|
var PropTypes = require('prop-types');
|
|
@@ -33,7 +32,6 @@ var caretDown = require('@phosphor-icons/core/assets/regular/caret-down.svg');
|
|
|
33
32
|
var caretUp = require('@phosphor-icons/core/assets/regular/caret-up.svg');
|
|
34
33
|
var debounce$1 = require('lodash.debounce');
|
|
35
34
|
var mafs = require('mafs');
|
|
36
|
-
var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
|
|
37
35
|
var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
|
|
38
36
|
var questionIcon = require('@phosphor-icons/core/regular/question.svg');
|
|
39
37
|
var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
|
|
@@ -73,8 +71,6 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
73
71
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
74
72
|
var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
|
|
75
73
|
var Clickable__default = /*#__PURE__*/_interopDefaultLegacy(Clickable);
|
|
76
|
-
var Color__default = /*#__PURE__*/_interopDefaultLegacy(Color);
|
|
77
|
-
var Spacing__default = /*#__PURE__*/_interopDefaultLegacy(Spacing);
|
|
78
74
|
var $__default = /*#__PURE__*/_interopDefaultLegacy($);
|
|
79
75
|
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
|
|
80
76
|
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
|
|
@@ -361,16 +357,16 @@ const MathInputIcon = _ref => {
|
|
|
361
357
|
focused,
|
|
362
358
|
active
|
|
363
359
|
} = _ref;
|
|
364
|
-
let
|
|
360
|
+
let fillColor;
|
|
365
361
|
switch (true) {
|
|
366
362
|
case focused || active:
|
|
367
|
-
|
|
363
|
+
fillColor = wonderBlocksTokens.color.white;
|
|
368
364
|
break;
|
|
369
365
|
case hovered:
|
|
370
|
-
|
|
366
|
+
fillColor = wonderBlocksTokens.color.blue;
|
|
371
367
|
break;
|
|
372
368
|
default:
|
|
373
|
-
|
|
369
|
+
fillColor = wonderBlocksTokens.color.offBlack;
|
|
374
370
|
break;
|
|
375
371
|
}
|
|
376
372
|
const dynamicClass = active || focused ? styles$D.iconActive : styles$D.iconInactive;
|
|
@@ -380,7 +376,7 @@ const MathInputIcon = _ref => {
|
|
|
380
376
|
xmlns: "http://www.w3.org/2000/svg",
|
|
381
377
|
width: "16",
|
|
382
378
|
height: "16",
|
|
383
|
-
fill:
|
|
379
|
+
fill: fillColor,
|
|
384
380
|
viewBox: "0 0 256 256"
|
|
385
381
|
}, /*#__PURE__*/React__namespace.createElement("path", {
|
|
386
382
|
d: "M112,72a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16h64A8,8,0,0,1,112,72Zm-8,104H80V152a8,8,0,0,0-16,0v24H40a8,8,0,0,0,0,16H64v24a8,8,0,0,0,16,0V192h24a8,8,0,0,0,0-16Zm48,0h64a8,8,0,0,0,0-16H152a8,8,0,0,0,0,16Zm64,16H152a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm-61.66-90.34a8,8,0,0,0,11.32,0L184,83.31l18.34,18.35a8,8,0,0,0,11.32-11.32L195.31,72l18.35-18.34a8,8,0,0,0-11.32-11.32L184,60.69,165.66,42.34a8,8,0,0,0-11.32,11.32L172.69,72,154.34,90.34A8,8,0,0,0,154.34,101.66Z"
|
|
@@ -417,7 +413,7 @@ const mapButtonSets = buttonSets => {
|
|
|
417
413
|
};
|
|
418
414
|
const inputFocused = {
|
|
419
415
|
borderWidth: 2,
|
|
420
|
-
borderColor:
|
|
416
|
+
borderColor: wonderBlocksTokens.color.blue,
|
|
421
417
|
margin: -1
|
|
422
418
|
};
|
|
423
419
|
const styles$D = aphrodite.StyleSheet.create({
|
|
@@ -425,35 +421,35 @@ const styles$D = aphrodite.StyleSheet.create({
|
|
|
425
421
|
display: "flex",
|
|
426
422
|
justifyContent: "center",
|
|
427
423
|
height: "100%",
|
|
428
|
-
padding:
|
|
424
|
+
padding: wonderBlocksTokens.spacing.xxxSmall_4,
|
|
429
425
|
borderRadius: 1
|
|
430
426
|
},
|
|
431
427
|
iconInactive: {
|
|
432
|
-
backgroundColor:
|
|
428
|
+
backgroundColor: wonderBlocksTokens.color.offBlack8
|
|
433
429
|
},
|
|
434
430
|
iconActive: {
|
|
435
|
-
backgroundColor:
|
|
431
|
+
backgroundColor: wonderBlocksTokens.color.offBlack64
|
|
436
432
|
},
|
|
437
433
|
outerWrapper: {
|
|
438
434
|
display: "inline-block",
|
|
439
435
|
borderStyle: "solid",
|
|
440
436
|
borderWidth: 1,
|
|
441
|
-
borderColor:
|
|
437
|
+
borderColor: wonderBlocksTokens.color.offBlack50,
|
|
442
438
|
borderRadius: 3,
|
|
443
|
-
background:
|
|
439
|
+
background: wonderBlocksTokens.color.white,
|
|
444
440
|
":hover": inputFocused
|
|
445
441
|
},
|
|
446
442
|
wrapperFocused: inputFocused,
|
|
447
443
|
wrapperError: {
|
|
448
|
-
borderColor:
|
|
449
|
-
background:
|
|
444
|
+
borderColor: wonderBlocksTokens.color.red,
|
|
445
|
+
background: wonderBlocksTokens.color.fadedRed8,
|
|
450
446
|
":hover": {
|
|
451
|
-
borderColor:
|
|
447
|
+
borderColor: wonderBlocksTokens.color.red
|
|
452
448
|
}
|
|
453
449
|
},
|
|
454
450
|
popoverContent: {
|
|
455
451
|
padding: 0,
|
|
456
|
-
paddingBottom:
|
|
452
|
+
paddingBottom: wonderBlocksTokens.spacing.xxSmall_6,
|
|
457
453
|
maxWidth: "initial"
|
|
458
454
|
}
|
|
459
455
|
});
|
|
@@ -21863,13 +21859,13 @@ const styles$A = aphrodite.StyleSheet.create({
|
|
|
21863
21859
|
width: 40
|
|
21864
21860
|
},
|
|
21865
21861
|
leftAlign: {
|
|
21866
|
-
paddingLeft:
|
|
21862
|
+
paddingLeft: wonderBlocksTokens.spacing.xxxSmall_4,
|
|
21867
21863
|
paddingRight: 0
|
|
21868
21864
|
},
|
|
21869
21865
|
rightAlign: {
|
|
21870
21866
|
textAlign: "right",
|
|
21871
21867
|
paddingLeft: 0,
|
|
21872
|
-
paddingRight:
|
|
21868
|
+
paddingRight: wonderBlocksTokens.spacing.xxxSmall_4
|
|
21873
21869
|
},
|
|
21874
21870
|
answerStateUnanswered: {
|
|
21875
21871
|
backgroundColor: "#eee",
|
|
@@ -22966,17 +22962,17 @@ function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, cor
|
|
|
22966
22962
|
let borderColor;
|
|
22967
22963
|
let color;
|
|
22968
22964
|
if (!showCorrectness && pressed) {
|
|
22969
|
-
borderColor =
|
|
22970
|
-
color =
|
|
22965
|
+
borderColor = wonderBlocksTokens.color.blue;
|
|
22966
|
+
color = wonderBlocksTokens.color.blue;
|
|
22971
22967
|
backgroundColor = "transparent";
|
|
22972
22968
|
} else if (checked) {
|
|
22973
|
-
const bg = showCorrectness && correct ?
|
|
22969
|
+
const bg = showCorrectness && correct ? wonderBlocksTokens.color.green : wonderBlocksTokens.color.blue;
|
|
22974
22970
|
color = white$1;
|
|
22975
22971
|
backgroundColor = bg;
|
|
22976
22972
|
borderColor = bg;
|
|
22977
22973
|
} else {
|
|
22978
|
-
borderColor =
|
|
22979
|
-
color =
|
|
22974
|
+
borderColor = wonderBlocksTokens.color.offBlack64;
|
|
22975
|
+
color = wonderBlocksTokens.color.offBlack64;
|
|
22980
22976
|
}
|
|
22981
22977
|
|
|
22982
22978
|
// define shape
|
|
@@ -23010,7 +23006,7 @@ const ChoiceIcon = function (props) {
|
|
|
23010
23006
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
23011
23007
|
className: aphrodite.css(styles$y.iconWrapper)
|
|
23012
23008
|
}, /*#__PURE__*/React__namespace.createElement(FocusRing, {
|
|
23013
|
-
color:
|
|
23009
|
+
color: wonderBlocksTokens.color.blue,
|
|
23014
23010
|
visible: focused || hovered,
|
|
23015
23011
|
multipleSelect: multipleSelect
|
|
23016
23012
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -23075,9 +23071,9 @@ const styles$w = aphrodite.StyleSheet.create({
|
|
|
23075
23071
|
color: gray68
|
|
23076
23072
|
},
|
|
23077
23073
|
circleIncorrectAnswered: {
|
|
23078
|
-
backgroundColor:
|
|
23079
|
-
borderColor:
|
|
23080
|
-
color:
|
|
23074
|
+
backgroundColor: wonderBlocksTokens.color.red,
|
|
23075
|
+
borderColor: wonderBlocksTokens.color.red,
|
|
23076
|
+
color: wonderBlocksTokens.color.white
|
|
23081
23077
|
}
|
|
23082
23078
|
});
|
|
23083
23079
|
|
|
@@ -23145,13 +23141,13 @@ const styles$v = aphrodite.StyleSheet.create({
|
|
|
23145
23141
|
textTransform: "uppercase"
|
|
23146
23142
|
},
|
|
23147
23143
|
correct: {
|
|
23148
|
-
color:
|
|
23144
|
+
color: wonderBlocksTokens.color.green
|
|
23149
23145
|
},
|
|
23150
23146
|
incorrectAnswered: {
|
|
23151
|
-
color:
|
|
23147
|
+
color: wonderBlocksTokens.color.red
|
|
23152
23148
|
},
|
|
23153
23149
|
incorrect: {
|
|
23154
|
-
color:
|
|
23150
|
+
color: wonderBlocksTokens.color.offBlack64
|
|
23155
23151
|
}
|
|
23156
23152
|
});
|
|
23157
23153
|
|
|
@@ -23225,7 +23221,7 @@ const Choice = function (props) {
|
|
|
23225
23221
|
// @ts-expect-error - TS2322 - Type '{ dispay: string; flexDirection: "column"; color: string; }' is not assignable to type 'Properties<string | number, string & {}>'.
|
|
23226
23222
|
dispay: "flex",
|
|
23227
23223
|
flexDirection: "column",
|
|
23228
|
-
color:
|
|
23224
|
+
color: wonderBlocksTokens.color.offBlack
|
|
23229
23225
|
},
|
|
23230
23226
|
className: descriptionClassName
|
|
23231
23227
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -23268,7 +23264,7 @@ const Choice = function (props) {
|
|
|
23268
23264
|
disabled: disabled || apiOptions.readOnly,
|
|
23269
23265
|
style: {
|
|
23270
23266
|
flex: 1,
|
|
23271
|
-
color:
|
|
23267
|
+
color: wonderBlocksTokens.color.offBlack,
|
|
23272
23268
|
userSelect: "text"
|
|
23273
23269
|
},
|
|
23274
23270
|
ref: forwardedRef,
|
|
@@ -23285,9 +23281,9 @@ const Choice = function (props) {
|
|
|
23285
23281
|
flexDirection: "row",
|
|
23286
23282
|
justifyContent: "center",
|
|
23287
23283
|
alignContent: "center",
|
|
23288
|
-
paddingTop:
|
|
23289
|
-
paddingBottom:
|
|
23290
|
-
paddingLeft:
|
|
23284
|
+
paddingTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
23285
|
+
paddingBottom: wonderBlocksTokens.spacing.xSmall_8,
|
|
23286
|
+
paddingLeft: wonderBlocksTokens.spacing.xSmall_8
|
|
23291
23287
|
}
|
|
23292
23288
|
}, /*#__PURE__*/React__namespace.createElement(ChoiceIcon, {
|
|
23293
23289
|
pos: pos,
|
|
@@ -23303,7 +23299,7 @@ const Choice = function (props) {
|
|
|
23303
23299
|
previouslyAnswered: previouslyAnswered
|
|
23304
23300
|
}), /*#__PURE__*/React__namespace.createElement("span", {
|
|
23305
23301
|
style: {
|
|
23306
|
-
paddingLeft:
|
|
23302
|
+
paddingLeft: wonderBlocksTokens.spacing.small_12,
|
|
23307
23303
|
textAlign: "left",
|
|
23308
23304
|
flex: 1,
|
|
23309
23305
|
paddingTop: 4
|
|
@@ -23326,7 +23322,7 @@ const Choice = function (props) {
|
|
|
23326
23322
|
content: i18n__namespace._("Cross out option"),
|
|
23327
23323
|
closeButtonVisible: true,
|
|
23328
23324
|
actions: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksLayout.Strut, {
|
|
23329
|
-
size:
|
|
23325
|
+
size: wonderBlocksTokens.spacing.medium_16
|
|
23330
23326
|
}), /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
23331
23327
|
kind: "primary",
|
|
23332
23328
|
"aria-label": i18n__namespace._("Cross out Choice %(letter)s", {
|
|
@@ -23374,7 +23370,7 @@ const Choice = function (props) {
|
|
|
23374
23370
|
return /*#__PURE__*/React__namespace.createElement(Icon, {
|
|
23375
23371
|
icon: ellipsisHorizontalIcon,
|
|
23376
23372
|
size: 3,
|
|
23377
|
-
color:
|
|
23373
|
+
color: wonderBlocksTokens.color.offBlack64
|
|
23378
23374
|
});
|
|
23379
23375
|
});
|
|
23380
23376
|
})), showRationale && /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -23392,7 +23388,7 @@ const styles$u = aphrodite.StyleSheet.create({
|
|
|
23392
23388
|
padding: intermediateCheckboxPadding,
|
|
23393
23389
|
paddingTop: 0,
|
|
23394
23390
|
marginLeft: 54,
|
|
23395
|
-
color:
|
|
23391
|
+
color: wonderBlocksTokens.color.offBlack64,
|
|
23396
23392
|
[mediaQueries.smOrSmaller]: {
|
|
23397
23393
|
padding: intermediateCheckboxPaddingPhone,
|
|
23398
23394
|
paddingTop: 0
|
|
@@ -24818,8 +24814,8 @@ class Definition extends React__namespace.Component {
|
|
|
24818
24814
|
} = _ref2;
|
|
24819
24815
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
24820
24816
|
style: {
|
|
24821
|
-
color:
|
|
24822
|
-
borderBottom: hovered || focused || pressed ? `2px solid ${
|
|
24817
|
+
color: wonderBlocksTokens.color.blue,
|
|
24818
|
+
borderBottom: hovered || focused || pressed ? `2px solid ${wonderBlocksTokens.color.blue}` : "none"
|
|
24823
24819
|
}
|
|
24824
24820
|
}, this.props.togglePrompt);
|
|
24825
24821
|
}));
|
|
@@ -24828,7 +24824,7 @@ class Definition extends React__namespace.Component {
|
|
|
24828
24824
|
}
|
|
24829
24825
|
const styles$q = {
|
|
24830
24826
|
tooltipBody: {
|
|
24831
|
-
color:
|
|
24827
|
+
color: wonderBlocksTokens.color.offBlack,
|
|
24832
24828
|
fontSize: 20,
|
|
24833
24829
|
fontWeight: 500,
|
|
24834
24830
|
lineHeight: "30px"
|
|
@@ -25126,7 +25122,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25126
25122
|
} = this.props;
|
|
25127
25123
|
const answerBarStyle = {
|
|
25128
25124
|
...styles$o.answerBar,
|
|
25129
|
-
backgroundColor: answerBarState === "CORRECT" ?
|
|
25125
|
+
backgroundColor: answerBarState === "CORRECT" ? wonderBlocksTokens.color.offWhite : "white",
|
|
25130
25126
|
// Center the "Correct!" message only when there's no next question
|
|
25131
25127
|
justifyContent: answerBarState === "CORRECT" && !onNextQuestion ? "center" : "space-between"
|
|
25132
25128
|
};
|
|
@@ -25156,7 +25152,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25156
25152
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25157
25153
|
style: {
|
|
25158
25154
|
fontSize: 28,
|
|
25159
|
-
color:
|
|
25155
|
+
color: wonderBlocksTokens.color.green
|
|
25160
25156
|
}
|
|
25161
25157
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon, _extends({}, iconStar, {
|
|
25162
25158
|
style: {
|
|
@@ -25186,7 +25182,7 @@ const styles$o = {
|
|
|
25186
25182
|
marginTop: phoneMargin,
|
|
25187
25183
|
paddingLeft: phoneMargin,
|
|
25188
25184
|
paddingRight: 10,
|
|
25189
|
-
borderTop: `1px solid ${
|
|
25185
|
+
borderTop: `1px solid ${wonderBlocksTokens.color.offBlack50}`
|
|
25190
25186
|
},
|
|
25191
25187
|
tryAgainIcon: {
|
|
25192
25188
|
fontSize: 28,
|
|
@@ -25494,7 +25490,7 @@ const styles$n = aphrodite.StyleSheet.create({
|
|
|
25494
25490
|
padding: 0,
|
|
25495
25491
|
border: "none",
|
|
25496
25492
|
marginTop: 20,
|
|
25497
|
-
color:
|
|
25493
|
+
color: wonderBlocksTokens.color.blue,
|
|
25498
25494
|
cursor: "pointer",
|
|
25499
25495
|
display: "block",
|
|
25500
25496
|
clear: "both"
|
|
@@ -25502,7 +25498,7 @@ const styles$n = aphrodite.StyleSheet.create({
|
|
|
25502
25498
|
explanationTitle: {
|
|
25503
25499
|
backgroundColor: "unset",
|
|
25504
25500
|
marginTop: 20,
|
|
25505
|
-
color:
|
|
25501
|
+
color: wonderBlocksTokens.color.blue,
|
|
25506
25502
|
marginBottom: 10,
|
|
25507
25503
|
cursor: "pointer",
|
|
25508
25504
|
fontSize: 14,
|
|
@@ -25718,7 +25714,7 @@ const styles$m = aphrodite.StyleSheet.create({
|
|
|
25718
25714
|
},
|
|
25719
25715
|
title: {
|
|
25720
25716
|
fontSize: 12,
|
|
25721
|
-
color:
|
|
25717
|
+
color: wonderBlocksTokens.color.offBlack64,
|
|
25722
25718
|
textTransform: "uppercase",
|
|
25723
25719
|
marginBottom: 11,
|
|
25724
25720
|
letterSpacing: 0.8
|
|
@@ -25752,7 +25748,7 @@ const styles$m = aphrodite.StyleSheet.create({
|
|
|
25752
25748
|
height: 10,
|
|
25753
25749
|
borderRadius: "100%",
|
|
25754
25750
|
borderWidth: 2,
|
|
25755
|
-
borderColor:
|
|
25751
|
+
borderColor: wonderBlocksTokens.color.blue,
|
|
25756
25752
|
borderStyle: "solid"
|
|
25757
25753
|
},
|
|
25758
25754
|
indicatorDotFocused: {
|
|
@@ -25760,7 +25756,7 @@ const styles$m = aphrodite.StyleSheet.create({
|
|
|
25760
25756
|
borderStyle: "double"
|
|
25761
25757
|
},
|
|
25762
25758
|
indicatorDotActive: {
|
|
25763
|
-
backgroundColor:
|
|
25759
|
+
backgroundColor: wonderBlocksTokens.color.blue,
|
|
25764
25760
|
width: "100%",
|
|
25765
25761
|
height: "100%"
|
|
25766
25762
|
},
|
|
@@ -28370,6 +28366,57 @@ const normalizeCoords = (coordsList, ranges) => coordsList.map(coords => coords.
|
|
|
28370
28366
|
return (coord + ranges[i][1]) / extent;
|
|
28371
28367
|
}));
|
|
28372
28368
|
|
|
28369
|
+
const useTransform = function () {
|
|
28370
|
+
const {
|
|
28371
|
+
viewTransform,
|
|
28372
|
+
userTransform
|
|
28373
|
+
} = mafs.useTransformContext();
|
|
28374
|
+
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
28375
|
+
for (var _len = arguments.length, points = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
28376
|
+
points[_key] = arguments[_key];
|
|
28377
|
+
}
|
|
28378
|
+
const transformedPoints = points.map(point => mafs.vec.transform(point, transformToPx));
|
|
28379
|
+
return transformedPoints;
|
|
28380
|
+
};
|
|
28381
|
+
|
|
28382
|
+
/**
|
|
28383
|
+
* Given two points, find the tips that extends through the points to the edge of the range.
|
|
28384
|
+
* @param collinearPoint - The point that the line passes through. Needed to establish slope.
|
|
28385
|
+
* @param extendFrom - The point that the line extends from to the edge of the graph.
|
|
28386
|
+
*/
|
|
28387
|
+
const getRayIntersectionCoords = (collinearPoint, extendFrom, range) => {
|
|
28388
|
+
// edges of the graph
|
|
28389
|
+
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28390
|
+
const [aX, aY] = collinearPoint;
|
|
28391
|
+
const [bX, bY] = extendFrom;
|
|
28392
|
+
const yDiff = bY - aY;
|
|
28393
|
+
const xDiff = bX - aX;
|
|
28394
|
+
const slope = yDiff / xDiff;
|
|
28395
|
+
const yAtXMin = slope * (xMin - aX) + aY;
|
|
28396
|
+
const yAtXMax = slope * (xMax - aX) + aY;
|
|
28397
|
+
const xAtYMin = (yMin - aY) / slope + aX;
|
|
28398
|
+
const xAtYMax = (yMax - aY) / slope + aX;
|
|
28399
|
+
|
|
28400
|
+
// clock analogy to describe quadrants
|
|
28401
|
+
switch (true) {
|
|
28402
|
+
// 12 o'clock to 2:59
|
|
28403
|
+
case yDiff > 0 && xDiff >= 0:
|
|
28404
|
+
return xAtYMax > xMax ? [xMax, yAtXMax] : [xAtYMax, yMax];
|
|
28405
|
+
// 3 o'clock to 5:59
|
|
28406
|
+
case yDiff <= 0 && xDiff > 0:
|
|
28407
|
+
// xAtYMin evaluates to -Infinity here, so we use absolute value
|
|
28408
|
+
return Math.abs(xAtYMin) > xMax ? [xMax, yAtXMax] : [xAtYMin, yMin];
|
|
28409
|
+
// 9 o'clock to 11:59
|
|
28410
|
+
case yDiff >= 0 && xDiff < 0:
|
|
28411
|
+
return xAtYMax < xMin ? [xMin, yAtXMin] : [xAtYMax, yMax];
|
|
28412
|
+
// 6 o'clock to 8:59
|
|
28413
|
+
case yDiff < 0 && xDiff <= 0:
|
|
28414
|
+
return xAtYMin < xMin ? [xMin, yAtXMin] : [xAtYMin, yMin];
|
|
28415
|
+
default:
|
|
28416
|
+
return [xMax, yAtXMax];
|
|
28417
|
+
}
|
|
28418
|
+
};
|
|
28419
|
+
|
|
28373
28420
|
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
28374
28421
|
const MovableLine = props => {
|
|
28375
28422
|
const {
|
|
@@ -28380,18 +28427,12 @@ const MovableLine = props => {
|
|
|
28380
28427
|
stroke = defaultStroke
|
|
28381
28428
|
} = props;
|
|
28382
28429
|
const midpoint = mafs.vec.midpoint(start, end);
|
|
28383
|
-
const
|
|
28384
|
-
viewTransform,
|
|
28385
|
-
userTransform
|
|
28386
|
-
} = mafs.useTransformContext();
|
|
28387
|
-
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
28388
|
-
const startPtPx = mafs.vec.transform(start, transformToPx);
|
|
28389
|
-
const endPtPx = mafs.vec.transform(end, transformToPx);
|
|
28430
|
+
const [startPtPx, endPtPx] = useTransform(start, end);
|
|
28390
28431
|
let startExtend = undefined;
|
|
28391
28432
|
let endExtend = undefined;
|
|
28392
28433
|
if (extend) {
|
|
28393
|
-
startExtend = extend.start ?
|
|
28394
|
-
endExtend = extend.end ?
|
|
28434
|
+
startExtend = extend.start ? getRayIntersectionCoords(end, start, extend.range) : undefined;
|
|
28435
|
+
endExtend = extend.end ? getRayIntersectionCoords(start, end, extend.range) : undefined;
|
|
28395
28436
|
}
|
|
28396
28437
|
const line = React.useRef(null);
|
|
28397
28438
|
const {
|
|
@@ -28453,50 +28494,12 @@ function SVGLine(props) {
|
|
|
28453
28494
|
});
|
|
28454
28495
|
}
|
|
28455
28496
|
|
|
28456
|
-
/**
|
|
28457
|
-
* Given two points, find the tips that extends through the points to the edge of the range.
|
|
28458
|
-
* @param collinearPoint - The point that the line passes through. Needed to establish slope.
|
|
28459
|
-
* @param extendFrom - The point that the line extends from to the edge of the graph.
|
|
28460
|
-
*/
|
|
28461
|
-
const getExtensionCoords = (collinearPoint, extendFrom, range) => {
|
|
28462
|
-
// edges of the graph
|
|
28463
|
-
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28464
|
-
const [aX, aY] = collinearPoint;
|
|
28465
|
-
const [bX, bY] = extendFrom;
|
|
28466
|
-
const yDiff = bY - aY;
|
|
28467
|
-
const xDiff = bX - aX;
|
|
28468
|
-
const slope = yDiff / xDiff;
|
|
28469
|
-
const yAtXMin = slope * (xMin - aX) + aY;
|
|
28470
|
-
const yAtXMax = slope * (xMax - aX) + aY;
|
|
28471
|
-
const xAtYMin = (yMin - aY) / slope + aX;
|
|
28472
|
-
const xAtYMax = (yMax - aY) / slope + aX;
|
|
28473
|
-
|
|
28474
|
-
// clock analogy to describe quadrants
|
|
28475
|
-
switch (true) {
|
|
28476
|
-
// 12 o'clock to 2:59
|
|
28477
|
-
case yDiff > 0 && xDiff >= 0:
|
|
28478
|
-
return xAtYMax > xMax ? [xMax, yAtXMax] : [xAtYMax, yMax];
|
|
28479
|
-
// 3 o'clock to 5:59
|
|
28480
|
-
case yDiff <= 0 && xDiff > 0:
|
|
28481
|
-
// xAtYMin evaluates to -Infinity here, so we use absolute value
|
|
28482
|
-
return Math.abs(xAtYMin) > xMax ? [xMax, yAtXMax] : [xAtYMin, yMin];
|
|
28483
|
-
// 9 o'clock to 11:59
|
|
28484
|
-
case yDiff >= 0 && xDiff < 0:
|
|
28485
|
-
return xAtYMax < xMin ? [xMin, yAtXMin] : [xAtYMax, yMax];
|
|
28486
|
-
// 6 o'clock to 8:59
|
|
28487
|
-
case yDiff < 0 && xDiff <= 0:
|
|
28488
|
-
return xAtYMin < xMin ? [xMin, yAtXMin] : [xAtYMin, yMin];
|
|
28489
|
-
default:
|
|
28490
|
-
return [xMax, yAtXMax];
|
|
28491
|
-
}
|
|
28492
|
-
};
|
|
28493
|
-
|
|
28494
28497
|
const StyledMovablePoint = props => {
|
|
28495
28498
|
const hitboxRef = React.useRef(null);
|
|
28496
28499
|
const {
|
|
28497
28500
|
point,
|
|
28498
28501
|
onMove,
|
|
28499
|
-
color =
|
|
28502
|
+
color = wonderBlocksTokens.color.blue
|
|
28500
28503
|
} = props;
|
|
28501
28504
|
const {
|
|
28502
28505
|
dragging
|
|
@@ -28506,12 +28509,7 @@ const StyledMovablePoint = props => {
|
|
|
28506
28509
|
onMove,
|
|
28507
28510
|
constrain: p => p
|
|
28508
28511
|
});
|
|
28509
|
-
const
|
|
28510
|
-
viewTransform,
|
|
28511
|
-
userTransform
|
|
28512
|
-
} = mafs.useTransformContext();
|
|
28513
|
-
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
28514
|
-
const [x, y] = mafs.vec.transform(point, transformToPx);
|
|
28512
|
+
const [[x, y]] = useTransform(point);
|
|
28515
28513
|
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
28516
28514
|
ref: hitboxRef,
|
|
28517
28515
|
className: "movable-point",
|
|
@@ -28678,6 +28676,161 @@ const RayGraph = props => {
|
|
|
28678
28676
|
}));
|
|
28679
28677
|
};
|
|
28680
28678
|
|
|
28679
|
+
const Angle = _ref => {
|
|
28680
|
+
let {
|
|
28681
|
+
centerPoint,
|
|
28682
|
+
endPoints,
|
|
28683
|
+
range,
|
|
28684
|
+
polygonPoints,
|
|
28685
|
+
showAngles
|
|
28686
|
+
} = _ref;
|
|
28687
|
+
const [centerX, centerY] = centerPoint;
|
|
28688
|
+
const areClockwise = clockwise$1([centerPoint, ...endPoints]);
|
|
28689
|
+
const [[startX, startY], [endX, endY]] = areClockwise ? endPoints : endPoints.reverse();
|
|
28690
|
+
const radius = 0.3;
|
|
28691
|
+
const a = mafs.vec.dist(centerPoint, endPoints[0]);
|
|
28692
|
+
const b = mafs.vec.dist(centerPoint, endPoints[1]);
|
|
28693
|
+
const c = mafs.vec.dist(endPoints[0], endPoints[1]);
|
|
28694
|
+
|
|
28695
|
+
// Law of cosines
|
|
28696
|
+
const angle = Math.acos((a ** 2 + b ** 2 - c ** 2) / (2 * a * b));
|
|
28697
|
+
const y1 = centerY + (startY - centerY) / a * radius;
|
|
28698
|
+
const x2 = centerX + (endX - centerX) / b * radius;
|
|
28699
|
+
const x1 = centerX + (startX - centerX) / a * radius;
|
|
28700
|
+
const y2 = centerY + (endY - centerY) / b * radius;
|
|
28701
|
+
|
|
28702
|
+
// Fourth point that would create a rhomboid
|
|
28703
|
+
// Used to calculate the inside of the angle and to create square
|
|
28704
|
+
const [x3, y3] = mafs.vec.add(centerPoint, mafs.vec.add(mafs.vec.sub([x1, y1], centerPoint), mafs.vec.sub([x2, y2], centerPoint)));
|
|
28705
|
+
if (!showAngles) {
|
|
28706
|
+
return isRightAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleArc, {
|
|
28707
|
+
start: [x1, y1],
|
|
28708
|
+
vertex: [x2, y2],
|
|
28709
|
+
end: [x3, y3]
|
|
28710
|
+
}) : null;
|
|
28711
|
+
}
|
|
28712
|
+
|
|
28713
|
+
// Midpoint betwen ends of arc
|
|
28714
|
+
const isInside = shouldDrawArcInside([x3, y3], centerPoint, range, polygonPoints);
|
|
28715
|
+
const largeArcFlag = isInside ? 1 : 0;
|
|
28716
|
+
const sweepFlag = isInside ? 1 : 0;
|
|
28717
|
+
const arc = `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;
|
|
28718
|
+
let angleInDegrees = angle * (180 / Math.PI);
|
|
28719
|
+
// If we have triggered "largArcFlag", the angle should be greater than 180
|
|
28720
|
+
if (isInside) {
|
|
28721
|
+
angleInDegrees = 360 - angleInDegrees;
|
|
28722
|
+
}
|
|
28723
|
+
const angleLabelNumber = parseFloat(angleInDegrees.toFixed(1));
|
|
28724
|
+
const angleLabel = Number.isInteger(angleLabelNumber) ? angleLabelNumber : "≈ " + angleLabelNumber;
|
|
28725
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("filter", {
|
|
28726
|
+
id: "background",
|
|
28727
|
+
x: "-5%",
|
|
28728
|
+
width: "110%",
|
|
28729
|
+
y: "0%",
|
|
28730
|
+
height: "100%"
|
|
28731
|
+
}, /*#__PURE__*/React__namespace.createElement("feFlood", {
|
|
28732
|
+
floodColor: "#FFF",
|
|
28733
|
+
floodOpacity: "0.5"
|
|
28734
|
+
}), /*#__PURE__*/React__namespace.createElement("feComposite", {
|
|
28735
|
+
operator: "over",
|
|
28736
|
+
in: "SourceGraphic"
|
|
28737
|
+
}))), !isInside && isRightAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleArc, {
|
|
28738
|
+
start: [x1, y1],
|
|
28739
|
+
vertex: [x2, y2],
|
|
28740
|
+
end: [x3, y3]
|
|
28741
|
+
}) : /*#__PURE__*/React__namespace.createElement("g", {
|
|
28742
|
+
style: {
|
|
28743
|
+
transform: `var(--mafs-view-transform) var(--mafs-user-transform)`
|
|
28744
|
+
}
|
|
28745
|
+
}, /*#__PURE__*/React__namespace.createElement("path", {
|
|
28746
|
+
d: arc,
|
|
28747
|
+
strokeWidth: 0.02,
|
|
28748
|
+
fill: "none"
|
|
28749
|
+
})), /*#__PURE__*/React__namespace.createElement(mafs.Text, {
|
|
28750
|
+
x: x3,
|
|
28751
|
+
y: y3,
|
|
28752
|
+
size: 15,
|
|
28753
|
+
svgTextProps: {
|
|
28754
|
+
filter: "url(#background)",
|
|
28755
|
+
fontWeight: "bold"
|
|
28756
|
+
}
|
|
28757
|
+
// Shift position if text is too close to movable point
|
|
28758
|
+
,
|
|
28759
|
+
attach: y3 - centerY > 0 ? "s" : "n",
|
|
28760
|
+
attachDistance: Math.abs(y3 - centerY) < 0.2 || mafs.vec.dist([x3, y3], centerPoint) < 0.3 ? 20 : 10
|
|
28761
|
+
}, angleLabel, "\xB0"));
|
|
28762
|
+
};
|
|
28763
|
+
const RightAngleArc = _ref2 => {
|
|
28764
|
+
let {
|
|
28765
|
+
start: [x1, y1],
|
|
28766
|
+
vertex: [x2, y2],
|
|
28767
|
+
end: [x3, y3]
|
|
28768
|
+
} = _ref2;
|
|
28769
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
28770
|
+
style: {
|
|
28771
|
+
transform: `var(--mafs-view-transform) var(--mafs-user-transform)`
|
|
28772
|
+
}
|
|
28773
|
+
}, /*#__PURE__*/React__namespace.createElement("path", {
|
|
28774
|
+
d: `M ${x1} ${y1} L ${x3} ${y3} M ${x3} ${y3} L ${x2} ${y2}`,
|
|
28775
|
+
strokeWidth: 0.02,
|
|
28776
|
+
fill: "none"
|
|
28777
|
+
}));
|
|
28778
|
+
};
|
|
28779
|
+
const isRightAngle = angle => Math.abs(angle - Math.PI / 2) < 0.01;
|
|
28780
|
+
const shouldDrawArcInside = (midPoint, vertex, range, polygonPoints) => {
|
|
28781
|
+
const rangeIntersectionPoint = getRayIntersectionCoords(vertex, midPoint, range);
|
|
28782
|
+
const lines = getLines(polygonPoints);
|
|
28783
|
+
let lineIntersections = 0;
|
|
28784
|
+
lines.forEach(line => linesIntersect([vertex, rangeIntersectionPoint], line) && lineIntersections++);
|
|
28785
|
+
|
|
28786
|
+
// The intersection check will sometimes return false if it intersects with
|
|
28787
|
+
// another vertex, so in the case we get 0 intersections, we check for points.
|
|
28788
|
+
if (lineIntersections === 0) {
|
|
28789
|
+
// find point in array
|
|
28790
|
+
const midpointIndex = polygonPoints.findIndex(_ref3 => {
|
|
28791
|
+
let [x, y] = _ref3;
|
|
28792
|
+
return x === midPoint[0] && y === midPoint[1];
|
|
28793
|
+
});
|
|
28794
|
+
// get array sans point and adjacent points
|
|
28795
|
+
const [prev, next] = [(midpointIndex - 1 + polygonPoints.length) % polygonPoints.length, (midpointIndex + 1) % polygonPoints.length];
|
|
28796
|
+
const [[lineAx, lineAy], [lineBx, lineBy]] = [midPoint, rangeIntersectionPoint];
|
|
28797
|
+
for (let i = 0; i < polygonPoints.length; i++) {
|
|
28798
|
+
if ([prev, midpointIndex, next].includes(i)) {
|
|
28799
|
+
continue;
|
|
28800
|
+
}
|
|
28801
|
+
const [x, y] = polygonPoints[i];
|
|
28802
|
+
const intersectsPoint = (y - lineAy) * (lineBx - lineAx) === (lineBy - lineAy) * (x - lineAx);
|
|
28803
|
+
if (intersectsPoint) {
|
|
28804
|
+
return false;
|
|
28805
|
+
}
|
|
28806
|
+
}
|
|
28807
|
+
return true;
|
|
28808
|
+
}
|
|
28809
|
+
|
|
28810
|
+
// If the number of intersections is even, the angle is inside the polygon
|
|
28811
|
+
return isEven(lineIntersections);
|
|
28812
|
+
};
|
|
28813
|
+
const getLines = points => points.map((point, i) => {
|
|
28814
|
+
const next = points[(i + 1) % points.length];
|
|
28815
|
+
return [point, next];
|
|
28816
|
+
});
|
|
28817
|
+
|
|
28818
|
+
// https://stackoverflow.com/a/24392281/7347484
|
|
28819
|
+
// The "intersects" function in geometry doesn't seem to work for this use case
|
|
28820
|
+
const linesIntersect = (_ref4, _ref5) => {
|
|
28821
|
+
let [[a, b], [c, d]] = _ref4;
|
|
28822
|
+
let [[p, q], [r, s]] = _ref5;
|
|
28823
|
+
const determinant = (c - a) * (s - q) - (r - p) * (d - b);
|
|
28824
|
+
if (determinant === 0) {
|
|
28825
|
+
return false;
|
|
28826
|
+
} else {
|
|
28827
|
+
const lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / determinant;
|
|
28828
|
+
const gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / determinant;
|
|
28829
|
+
return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1;
|
|
28830
|
+
}
|
|
28831
|
+
};
|
|
28832
|
+
const isEven = n => n % 2 === 0;
|
|
28833
|
+
|
|
28681
28834
|
const PolygonGraph = props => {
|
|
28682
28835
|
const [focused, setFocused] = React__namespace.useState(false);
|
|
28683
28836
|
const [hovered, setHovered] = React__namespace.useState(false);
|
|
@@ -28686,7 +28839,9 @@ const PolygonGraph = props => {
|
|
|
28686
28839
|
} = props;
|
|
28687
28840
|
const {
|
|
28688
28841
|
coords,
|
|
28689
|
-
type
|
|
28842
|
+
type,
|
|
28843
|
+
showAngles,
|
|
28844
|
+
range
|
|
28690
28845
|
} = props.graphState;
|
|
28691
28846
|
const points = coords ?? [[0, 0]];
|
|
28692
28847
|
const pointsSum = points.reduce((acc, point) => mafs.vec.add(acc, point), [0, 0]);
|
|
@@ -28710,6 +28865,21 @@ const PolygonGraph = props => {
|
|
|
28710
28865
|
svgPolygonProps: {
|
|
28711
28866
|
strokeWidth: active ? "var(--movable-line-stroke-weight-active)" : "var(--movable-line-stroke-weight)"
|
|
28712
28867
|
}
|
|
28868
|
+
}), points.map((point, i) => {
|
|
28869
|
+
const pt1 = points.at(i - 1);
|
|
28870
|
+
const pt2 = points[(i + 1) % points.length];
|
|
28871
|
+
if (!pt1 || !pt2) {
|
|
28872
|
+
return null;
|
|
28873
|
+
}
|
|
28874
|
+
return /*#__PURE__*/React__namespace.createElement(Angle, {
|
|
28875
|
+
key: "angle-" + i,
|
|
28876
|
+
centerPoint: point,
|
|
28877
|
+
endPoints: [pt1, pt2],
|
|
28878
|
+
active: active,
|
|
28879
|
+
range: range,
|
|
28880
|
+
polygonPoints: points,
|
|
28881
|
+
showAngles: !!showAngles
|
|
28882
|
+
});
|
|
28713
28883
|
}), /*#__PURE__*/React__namespace.createElement(mafs.Polygon, {
|
|
28714
28884
|
points: [...points],
|
|
28715
28885
|
color: "transparent",
|
|
@@ -28727,7 +28897,7 @@ const PolygonGraph = props => {
|
|
|
28727
28897
|
className: "movable-polygon"
|
|
28728
28898
|
}
|
|
28729
28899
|
}), points.map((point, i) => /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
|
|
28730
|
-
key: i,
|
|
28900
|
+
key: "point-" + i,
|
|
28731
28901
|
point: point,
|
|
28732
28902
|
onMove: destination => dispatch(moveControlPoint(i, destination)),
|
|
28733
28903
|
"data-testid": type + i
|
|
@@ -29409,7 +29579,11 @@ var components = /*#__PURE__*/Object.freeze({
|
|
|
29409
29579
|
* If a graphie URL is provided in `backgroundImage`, will return the rendered graphie background.
|
|
29410
29580
|
* Otherwise, returns `null`.
|
|
29411
29581
|
*/
|
|
29412
|
-
const
|
|
29582
|
+
const LegacyGrid = _ref => {
|
|
29583
|
+
let {
|
|
29584
|
+
box,
|
|
29585
|
+
backgroundImage
|
|
29586
|
+
} = _ref;
|
|
29413
29587
|
const {
|
|
29414
29588
|
url,
|
|
29415
29589
|
width,
|
|
@@ -29423,10 +29597,10 @@ const getLegacyGrid = (box, backgroundImage) => {
|
|
|
29423
29597
|
bottom: 0,
|
|
29424
29598
|
left: 0
|
|
29425
29599
|
}
|
|
29426
|
-
}, /*#__PURE__*/React__namespace.createElement(context$1.Consumer, null,
|
|
29600
|
+
}, /*#__PURE__*/React__namespace.createElement(context$1.Consumer, null, _ref2 => {
|
|
29427
29601
|
let {
|
|
29428
29602
|
setAssetStatus
|
|
29429
|
-
} =
|
|
29603
|
+
} = _ref2;
|
|
29430
29604
|
return /*#__PURE__*/React__namespace.createElement(SvgImage, {
|
|
29431
29605
|
src: url,
|
|
29432
29606
|
width: width,
|
|
@@ -29698,10 +29872,10 @@ function initializeGraphState(params) {
|
|
|
29698
29872
|
};
|
|
29699
29873
|
case "polygon":
|
|
29700
29874
|
return {
|
|
29701
|
-
type: "polygon",
|
|
29702
29875
|
hasBeenInteractedWith: false,
|
|
29703
29876
|
range,
|
|
29704
29877
|
snapStep,
|
|
29878
|
+
...graph,
|
|
29705
29879
|
coords: getPolygonCoords({
|
|
29706
29880
|
graph,
|
|
29707
29881
|
range,
|
|
@@ -29771,9 +29945,10 @@ const getDefaultSegments = _ref => {
|
|
|
29771
29945
|
return [5];
|
|
29772
29946
|
}
|
|
29773
29947
|
};
|
|
29948
|
+
const defaultRange = [[-10, 10], [-10, 10]];
|
|
29774
29949
|
return ys(graph.numSegments).map(y => {
|
|
29775
29950
|
let endpoints = [[-5, y], [5, y]];
|
|
29776
|
-
endpoints = normalizeCoords(endpoints,
|
|
29951
|
+
endpoints = normalizeCoords(endpoints, defaultRange);
|
|
29777
29952
|
endpoints = normalizePoints(range, step, endpoints);
|
|
29778
29953
|
return endpoints;
|
|
29779
29954
|
});
|
|
@@ -29856,7 +30031,6 @@ const renderGraph = props => {
|
|
|
29856
30031
|
};
|
|
29857
30032
|
const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
29858
30033
|
const [width, height] = props.box;
|
|
29859
|
-
const legacyGrid = getLegacyGrid([width, height], props.backgroundImage);
|
|
29860
30034
|
const [state, dispatch] = React__namespace.useReducer(interactiveGraphReducer, props, initializeGraphState);
|
|
29861
30035
|
React__namespace.useImperativeHandle(ref, () => ({
|
|
29862
30036
|
getUserInput: () => getGradableGraph(state, props.graph)
|
|
@@ -29867,13 +30041,17 @@ const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
|
29867
30041
|
height,
|
|
29868
30042
|
position: "relative"
|
|
29869
30043
|
}
|
|
29870
|
-
},
|
|
30044
|
+
}, /*#__PURE__*/React__namespace.createElement(LegacyGrid, {
|
|
30045
|
+
box: props.box,
|
|
30046
|
+
backgroundImage: props.backgroundImage
|
|
30047
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29871
30048
|
style: {
|
|
29872
30049
|
position: "absolute",
|
|
29873
30050
|
bottom: 0,
|
|
29874
30051
|
left: 0
|
|
29875
30052
|
}
|
|
29876
30053
|
}, /*#__PURE__*/React__namespace.createElement(mafs.Mafs, {
|
|
30054
|
+
preserveAspectRatio: false,
|
|
29877
30055
|
viewBox: {
|
|
29878
30056
|
x: props.range[0],
|
|
29879
30057
|
y: props.range[1],
|
|
@@ -29883,7 +30061,7 @@ const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
|
29883
30061
|
zoom: false,
|
|
29884
30062
|
width: width,
|
|
29885
30063
|
height: height
|
|
29886
|
-
},
|
|
30064
|
+
}, /*#__PURE__*/React__namespace.createElement(Grid, props), props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLayer, {
|
|
29887
30065
|
lockedFigures: props.lockedFigures
|
|
29888
30066
|
}), renderGraph({
|
|
29889
30067
|
state,
|
|
@@ -32777,7 +32955,7 @@ const styles$g = aphrodite.StyleSheet.create({
|
|
|
32777
32955
|
});
|
|
32778
32956
|
|
|
32779
32957
|
const BringToFront = {
|
|
32780
|
-
boxShadow: `0 8px 8px ${
|
|
32958
|
+
boxShadow: `0 8px 8px ${wonderBlocksTokens.color.offBlack64}`,
|
|
32781
32959
|
zIndex: 1000
|
|
32782
32960
|
};
|
|
32783
32961
|
const AnswerPill = props => {
|
|
@@ -32833,7 +33011,7 @@ const styles$f = aphrodite.StyleSheet.create({
|
|
|
32833
33011
|
backgroundColor: "#00880b"
|
|
32834
33012
|
},
|
|
32835
33013
|
incorrect: {
|
|
32836
|
-
backgroundColor:
|
|
33014
|
+
backgroundColor: wonderBlocksTokens.color.offBlack64
|
|
32837
33015
|
},
|
|
32838
33016
|
pill: {
|
|
32839
33017
|
// Reset the Pill's default height in order to account
|
|
@@ -32877,7 +33055,7 @@ class Marker extends React__namespace.Component {
|
|
|
32877
33055
|
// default dot
|
|
32878
33056
|
let args = {
|
|
32879
33057
|
size: MARKER_SIZE,
|
|
32880
|
-
color:
|
|
33058
|
+
color: wonderBlocksTokens.color.white,
|
|
32881
33059
|
icon: iconNull
|
|
32882
33060
|
};
|
|
32883
33061
|
if (showCorrectness) {
|
|
@@ -32938,7 +33116,7 @@ class Marker extends React__namespace.Component {
|
|
|
32938
33116
|
const styles$e = aphrodite.StyleSheet.create({
|
|
32939
33117
|
marker: {
|
|
32940
33118
|
position: "absolute",
|
|
32941
|
-
backgroundColor:
|
|
33119
|
+
backgroundColor: wonderBlocksTokens.color.white,
|
|
32942
33120
|
borderRadius: MARKER_SIZE,
|
|
32943
33121
|
// Center marker position based on its maximum size.
|
|
32944
33122
|
width: MARKER_SIZE,
|
|
@@ -32946,7 +33124,7 @@ const styles$e = aphrodite.StyleSheet.create({
|
|
|
32946
33124
|
marginLeft: MARKER_SIZE / -2,
|
|
32947
33125
|
marginTop: MARKER_SIZE / -2,
|
|
32948
33126
|
// Add a shadow to the marker to make it stand out from the image.
|
|
32949
|
-
boxShadow: `0 8px 8px ${
|
|
33127
|
+
boxShadow: `0 8px 8px ${wonderBlocksTokens.color.offBlack8}`
|
|
32950
33128
|
},
|
|
32951
33129
|
// The base and unfilled marker style.
|
|
32952
33130
|
markerIcon: {
|
|
@@ -32956,7 +33134,7 @@ const styles$e = aphrodite.StyleSheet.create({
|
|
|
32956
33134
|
boxSizing: "border-box",
|
|
32957
33135
|
width: MARKER_SIZE,
|
|
32958
33136
|
height: MARKER_SIZE,
|
|
32959
|
-
border: `2px solid ${
|
|
33137
|
+
border: `2px solid ${wonderBlocksTokens.color.offBlack64}`,
|
|
32960
33138
|
borderRadius: MARKER_SIZE
|
|
32961
33139
|
},
|
|
32962
33140
|
// The animation that presents the marker to the learner
|
|
@@ -32964,11 +33142,11 @@ const styles$e = aphrodite.StyleSheet.create({
|
|
|
32964
33142
|
animationName: {
|
|
32965
33143
|
"0%": {
|
|
32966
33144
|
transform: "scale(1)",
|
|
32967
|
-
backgroundColor:
|
|
33145
|
+
backgroundColor: wonderBlocksTokens.color.blue
|
|
32968
33146
|
},
|
|
32969
33147
|
"100%": {
|
|
32970
33148
|
transform: "scale(1.3)",
|
|
32971
|
-
backgroundColor:
|
|
33149
|
+
backgroundColor: wonderBlocksTokens.color.blue
|
|
32972
33150
|
}
|
|
32973
33151
|
},
|
|
32974
33152
|
animationDirection: "alternate",
|
|
@@ -32985,35 +33163,35 @@ const styles$e = aphrodite.StyleSheet.create({
|
|
|
32985
33163
|
animationIterationCount: "2"
|
|
32986
33164
|
},
|
|
32987
33165
|
markerActive: {
|
|
32988
|
-
outline: `2px solid ${
|
|
33166
|
+
outline: `2px solid ${wonderBlocksTokens.color.blue}`,
|
|
32989
33167
|
outlineOffset: 2
|
|
32990
33168
|
},
|
|
32991
33169
|
// The learner is making an initial selection
|
|
32992
33170
|
markerSelected: {
|
|
32993
|
-
boxShadow: `0 8px 8px ${
|
|
32994
|
-
border: `solid 4px ${
|
|
32995
|
-
backgroundColor:
|
|
33171
|
+
boxShadow: `0 8px 8px ${wonderBlocksTokens.color.offBlack8}`,
|
|
33172
|
+
border: `solid 4px ${wonderBlocksTokens.color.white}`,
|
|
33173
|
+
backgroundColor: wonderBlocksTokens.color.blue,
|
|
32996
33174
|
borderRadius: MARKER_SIZE,
|
|
32997
33175
|
transform: "rotate(180deg)"
|
|
32998
33176
|
},
|
|
32999
33177
|
// The learner has made a selection
|
|
33000
33178
|
markerFilled: {
|
|
33001
33179
|
backgroundColor: "#ECF3FE",
|
|
33002
|
-
border: `4px solid ${
|
|
33180
|
+
border: `4px solid ${wonderBlocksTokens.color.blue}`
|
|
33003
33181
|
},
|
|
33004
33182
|
markerGraded: {
|
|
33005
33183
|
width: MARKER_SIZE,
|
|
33006
33184
|
height: MARKER_SIZE,
|
|
33007
33185
|
justifyContent: "center",
|
|
33008
33186
|
alignItems: "center",
|
|
33009
|
-
border: `2px solid ${
|
|
33187
|
+
border: `2px solid ${wonderBlocksTokens.color.white}`
|
|
33010
33188
|
},
|
|
33011
33189
|
markerCorrect: {
|
|
33012
33190
|
background: "#00880b" // WB green darkened by 18%
|
|
33013
33191
|
},
|
|
33014
33192
|
|
|
33015
33193
|
markerIncorrect: {
|
|
33016
|
-
background:
|
|
33194
|
+
background: wonderBlocksTokens.color.offBlack64
|
|
33017
33195
|
}
|
|
33018
33196
|
});
|
|
33019
33197
|
|
|
@@ -33444,6 +33622,7 @@ class LabelImage extends React__namespace.Component {
|
|
|
33444
33622
|
const answerChoicesActive = index === activeMarkerIndex;
|
|
33445
33623
|
const showAnswerChoice = marker.selected && !answerChoicesActive && !this.state.hideAnswers;
|
|
33446
33624
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
33625
|
+
key: index,
|
|
33447
33626
|
style: {
|
|
33448
33627
|
position: "absolute",
|
|
33449
33628
|
left: `${marker.x}%`,
|
|
@@ -38048,7 +38227,7 @@ const styles$8 = aphrodite.StyleSheet.create({
|
|
|
38048
38227
|
// and the "Add highlight" action fails.
|
|
38049
38228
|
userSelect: "none",
|
|
38050
38229
|
fontFamily: `"Lato", sans-serif`,
|
|
38051
|
-
padding: `10px ${
|
|
38230
|
+
padding: `10px ${wonderBlocksTokens.spacing.medium_16}px`,
|
|
38052
38231
|
cursor: "pointer"
|
|
38053
38232
|
}
|
|
38054
38233
|
});
|
|
@@ -41894,7 +42073,7 @@ const init = function (options) {
|
|
|
41894
42073
|
|
|
41895
42074
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41896
42075
|
const libName = "@khanacademy/perseus";
|
|
41897
|
-
const libVersion = "20.8.
|
|
42076
|
+
const libVersion = "20.8.1";
|
|
41898
42077
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41899
42078
|
|
|
41900
42079
|
const apiVersion = {
|
|
@@ -44777,15 +44956,14 @@ function getWidgetRegex() {
|
|
|
44777
44956
|
}
|
|
44778
44957
|
|
|
44779
44958
|
/**
|
|
44780
|
-
* Add a widget placeholder using the
|
|
44781
|
-
* ex. addWidget(
|
|
44959
|
+
* Add a widget placeholder using the widget ID.
|
|
44960
|
+
* ex. addWidget("radio 1") => "[[☃ radio 1]]"
|
|
44782
44961
|
*
|
|
44783
|
-
* @param {
|
|
44784
|
-
* @param {number} instance
|
|
44962
|
+
* @param {string} id
|
|
44785
44963
|
* @returns {string}
|
|
44786
44964
|
*/
|
|
44787
|
-
function addWidget(
|
|
44788
|
-
return `[[☃ ${
|
|
44965
|
+
function addWidget(id) {
|
|
44966
|
+
return `[[☃ ${id}]]`;
|
|
44789
44967
|
}
|
|
44790
44968
|
|
|
44791
44969
|
/**
|