@khanacademy/perseus 19.1.9 → 19.2.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/components/image-loader.d.ts +2 -2
- package/dist/components/math-input.d.ts +1 -1
- package/dist/es/index.js +489 -499
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +475 -498
- package/dist/index.js.map +1 -1
- package/dist/interactive2/arrowhead.d.ts +9 -0
- package/dist/interactive2/get-clip-point.d.ts +2 -0
- package/dist/interactive2/wrapped-drawing.d.ts +29 -0
- package/dist/interactive2/wrapped-ellipse.d.ts +8 -1
- package/dist/interactive2/wrapped-line.d.ts +10 -1
- package/dist/interactive2/wrapped-path.d.ts +7 -1
- package/dist/logging/log.d.ts +1 -1
- package/dist/perseus-types.d.ts +9 -4
- package/dist/util/sizing-utils.d.ts +1 -1
- package/dist/widgets/expression.d.ts +2 -2
- package/dist/widgets/graded-group.d.ts +1 -1
- package/dist/widgets/python-program.d.ts +33 -0
- package/package.json +4 -4
- package/dist/interactive2/wrapped-defaults.d.ts +0 -5
package/dist/es/index.js
CHANGED
|
@@ -244,7 +244,7 @@ class MathInput extends React.Component {
|
|
|
244
244
|
className = className + " " + this.props.className;
|
|
245
245
|
}
|
|
246
246
|
return /*#__PURE__*/React.createElement(View, {
|
|
247
|
-
style: [styles$
|
|
247
|
+
style: [styles$C.outerWrapper, this.state.focused && styles$C.wrapperFocused, this.props.hasError && styles$C.wrapperError]
|
|
248
248
|
}, /*#__PURE__*/React.createElement("div", {
|
|
249
249
|
style: {
|
|
250
250
|
display: "flex",
|
|
@@ -277,7 +277,7 @@ class MathInput extends React.Component {
|
|
|
277
277
|
var _this$props$keypadBut, _this$props;
|
|
278
278
|
return /*#__PURE__*/React.createElement(PopoverContentCore, {
|
|
279
279
|
closeButtonVisible: true,
|
|
280
|
-
style: styles$
|
|
280
|
+
style: styles$C.popoverContent
|
|
281
281
|
}, /*#__PURE__*/React.createElement(DesktopKeypad, _extends({
|
|
282
282
|
onAnalyticsEvent: this.props.analytics.onAnalyticsEvent,
|
|
283
283
|
extraKeys: this.props.extraKeys,
|
|
@@ -321,9 +321,9 @@ const MathInputIcon = ({
|
|
|
321
321
|
color = Color.offBlack;
|
|
322
322
|
break;
|
|
323
323
|
}
|
|
324
|
-
const dynamicClass = active || focused ? styles$
|
|
324
|
+
const dynamicClass = active || focused ? styles$C.iconActive : styles$C.iconInactive;
|
|
325
325
|
return /*#__PURE__*/React.createElement(View, {
|
|
326
|
-
style: [styles$
|
|
326
|
+
style: [styles$C.iconContainer, dynamicClass]
|
|
327
327
|
}, /*#__PURE__*/React.createElement("svg", {
|
|
328
328
|
xmlns: "http://www.w3.org/2000/svg",
|
|
329
329
|
width: "16",
|
|
@@ -368,7 +368,7 @@ const inputFocused = {
|
|
|
368
368
|
borderColor: Color.blue,
|
|
369
369
|
margin: -1
|
|
370
370
|
};
|
|
371
|
-
const styles$
|
|
371
|
+
const styles$C = StyleSheet.create({
|
|
372
372
|
iconContainer: {
|
|
373
373
|
display: "flex",
|
|
374
374
|
justifyContent: "center",
|
|
@@ -2394,6 +2394,7 @@ ExpressionWithDependencies.getOneCorrectAnswerFromRubric = Expression.getOneCorr
|
|
|
2394
2394
|
var Expression$1 = {
|
|
2395
2395
|
name: "expression",
|
|
2396
2396
|
displayName: "Expression / Equation",
|
|
2397
|
+
accessible: true,
|
|
2397
2398
|
defaultAlignment: "inline-block",
|
|
2398
2399
|
widget: ExpressionWithDependencies,
|
|
2399
2400
|
transform: widgetOptions => {
|
|
@@ -10202,89 +10203,49 @@ const GraphUtils = {
|
|
|
10202
10203
|
}
|
|
10203
10204
|
})($, window, document);
|
|
10204
10205
|
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
/**
|
|
10214
|
-
* Does a pluck on keys inside objects in an object
|
|
10215
|
-
*
|
|
10216
|
-
* Ex:
|
|
10217
|
-
* tools = {
|
|
10218
|
-
* translation: {
|
|
10219
|
-
* enabled: true
|
|
10220
|
-
* },
|
|
10221
|
-
* rotation: {
|
|
10222
|
-
* enabled: false
|
|
10223
|
-
* }
|
|
10224
|
-
* };
|
|
10225
|
-
* pluckObject(tools, "enabled") returns {
|
|
10226
|
-
* translation: true
|
|
10227
|
-
* rotation: false
|
|
10228
|
-
* }
|
|
10229
|
-
*/
|
|
10230
|
-
const pluck = function pluck(table, subKey) {
|
|
10231
|
-
return _.object(_.map(table, function (value, key) {
|
|
10232
|
-
return [key, value[subKey]];
|
|
10233
|
-
}));
|
|
10234
|
-
};
|
|
10235
|
-
|
|
10236
|
-
/**
|
|
10237
|
-
* Maps an object to an object
|
|
10238
|
-
*
|
|
10239
|
-
* > mapObject({a: '1', b: '2'}, (value, key) => {
|
|
10240
|
-
* return value + 1;
|
|
10241
|
-
* });
|
|
10242
|
-
* {a: 2, b: 3}
|
|
10243
|
-
*/
|
|
10244
|
-
const mapObject$2 = function mapObject(obj, lambda) {
|
|
10245
|
-
const result = {};
|
|
10246
|
-
_.each(_.keys(obj), function (key) {
|
|
10247
|
-
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'K'.
|
|
10248
|
-
result[key] = lambda(obj[key], key);
|
|
10249
|
-
});
|
|
10250
|
-
return result;
|
|
10251
|
-
};
|
|
10206
|
+
// Given `coord` and `angle`, find the point where a line extended
|
|
10207
|
+
// from `coord` in the direction of `angle` would be clipped by the
|
|
10208
|
+
// edge of the graphie canvas.
|
|
10209
|
+
const getClipPoint = function getClipPoint(graph, coord, angle) {
|
|
10210
|
+
// Actually put the arrowheads 4px from the edge so they have
|
|
10211
|
+
// a bit of room
|
|
10212
|
+
const xExtent = graph.range[0][1] - graph.range[0][0];
|
|
10213
|
+
const yExtent = graph.range[1][1] - graph.range[1][0];
|
|
10252
10214
|
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
const
|
|
10262
|
-
|
|
10263
|
-
_.each(arr, function (elem) {
|
|
10264
|
-
result[elem] = lambda(elem);
|
|
10265
|
-
});
|
|
10266
|
-
return result;
|
|
10267
|
-
};
|
|
10268
|
-
var objective_ = {
|
|
10269
|
-
pluck: pluck,
|
|
10270
|
-
mapObject: mapObject$2,
|
|
10271
|
-
mapObjectFromArray: mapObjectFromArray$1
|
|
10215
|
+
// shoot a point off into the distance ...
|
|
10216
|
+
const distance = xExtent + yExtent;
|
|
10217
|
+
// we need to scale the point according to the scale of the axes
|
|
10218
|
+
const angleVec = graph.unscaleVector(vector$1.cartFromPolarDeg(1, angle));
|
|
10219
|
+
const distVec = vector$1.scale(vector$1.normalize(angleVec), distance);
|
|
10220
|
+
const farCoord = vector$1.add(coord, distVec);
|
|
10221
|
+
const scaledAngle = vector$1.polarDegFromCart(angleVec)[1];
|
|
10222
|
+
// ... and then bring it back
|
|
10223
|
+
const clipPoint = graph.constrainToBoundsOnAngle(farCoord, 4, scaledAngle * Math.PI / 180);
|
|
10224
|
+
return clipPoint;
|
|
10272
10225
|
};
|
|
10273
10226
|
|
|
10274
10227
|
/* eslint-disable @babel/no-invalid-this */
|
|
10275
10228
|
|
|
10276
10229
|
/*
|
|
10277
|
-
*
|
|
10230
|
+
* attr() and animate() simply pass the
|
|
10278
10231
|
* arguments to the underlying Raphael object.
|
|
10279
10232
|
*/
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10233
|
+
|
|
10234
|
+
class WrappedDrawing {
|
|
10235
|
+
constructor(graphie, initialPoint) {
|
|
10236
|
+
this.graphie = void 0;
|
|
10237
|
+
this.wrapper = void 0;
|
|
10238
|
+
this.visibleShape = void 0;
|
|
10239
|
+
this.initialPoint = void 0;
|
|
10240
|
+
this.graphie = graphie;
|
|
10241
|
+
this.initialPoint = initialPoint;
|
|
10242
|
+
}
|
|
10243
|
+
transform(transformation) {
|
|
10283
10244
|
const prefixedTransform = InteractiveUtil.getPrefixedTransform();
|
|
10284
10245
|
// @ts-expect-error - TS2538 - Type 'null' cannot be used as an index type. | TS2538 - Type 'undefined' cannot be used as an index type.
|
|
10285
10246
|
this.wrapper.style[prefixedTransform] = transformation;
|
|
10286
|
-
}
|
|
10287
|
-
toFront
|
|
10247
|
+
}
|
|
10248
|
+
toFront() {
|
|
10288
10249
|
const parentNode = this.wrapper.parentNode;
|
|
10289
10250
|
// TODO(emily): Sometimes, we call `.remove()` but then hold a
|
|
10290
10251
|
// reference to this object, and sometimes call `.toFront` on it.
|
|
@@ -10293,152 +10254,214 @@ const WrappedDefaults = _.extend({
|
|
|
10293
10254
|
if (parentNode) {
|
|
10294
10255
|
parentNode.appendChild(this.wrapper);
|
|
10295
10256
|
}
|
|
10296
|
-
}
|
|
10297
|
-
toBack
|
|
10257
|
+
}
|
|
10258
|
+
toBack() {
|
|
10298
10259
|
const parentNode = this.wrapper.parentNode;
|
|
10299
|
-
if (parentNode.firstChild !== this.wrapper) {
|
|
10260
|
+
if (parentNode != null && parentNode.firstChild !== this.wrapper) {
|
|
10300
10261
|
parentNode.insertBefore(this.wrapper, parentNode.firstChild);
|
|
10301
10262
|
}
|
|
10302
|
-
}
|
|
10303
|
-
remove
|
|
10263
|
+
}
|
|
10264
|
+
remove() {
|
|
10304
10265
|
this.visibleShape.remove();
|
|
10305
10266
|
$(this.wrapper).remove();
|
|
10306
|
-
}
|
|
10307
|
-
getMouseTarget
|
|
10267
|
+
}
|
|
10268
|
+
getMouseTarget() {
|
|
10308
10269
|
return this.visibleShape[0];
|
|
10309
|
-
}
|
|
10310
|
-
moveTo
|
|
10270
|
+
}
|
|
10271
|
+
moveTo(point) {
|
|
10311
10272
|
const delta = vector$1.subtract(this.graphie.scalePoint(point), this.graphie.scalePoint(this.initialPoint));
|
|
10312
10273
|
const do3dTransform = InteractiveUtil.getCanUse3dTransform();
|
|
10313
10274
|
const transformation = "translateX(" + delta[0] + "px) " + "translateY(" + delta[1] + "px)" + (do3dTransform ? " translateZ(0)" : "");
|
|
10314
10275
|
this.transform(transformation);
|
|
10315
|
-
}
|
|
10316
|
-
hide
|
|
10276
|
+
}
|
|
10277
|
+
hide() {
|
|
10317
10278
|
this.visibleShape.hide();
|
|
10318
|
-
}
|
|
10319
|
-
show
|
|
10279
|
+
}
|
|
10280
|
+
show() {
|
|
10320
10281
|
this.visibleShape.show();
|
|
10321
10282
|
}
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
}
|
|
10283
|
+
attr(...args) {
|
|
10284
|
+
this.visibleShape.attr(...args);
|
|
10285
|
+
}
|
|
10286
|
+
animate(...args) {
|
|
10287
|
+
this.visibleShape.animate(...args);
|
|
10288
|
+
}
|
|
10289
|
+
}
|
|
10328
10290
|
|
|
10329
10291
|
const DEFAULT_OPTIONS$2 = {
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10292
|
+
center: null,
|
|
10293
|
+
// gets ignored in `graphie.fixedPath` if `null`
|
|
10294
|
+
createPath: null,
|
|
10295
|
+
// gets defaulted in `graphie.fixedPath` if `null`
|
|
10296
|
+
mouselayer: false
|
|
10334
10297
|
};
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
//
|
|
10347
|
-
|
|
10298
|
+
class WrappedPath extends WrappedDrawing {
|
|
10299
|
+
constructor(graphie, points, options) {
|
|
10300
|
+
const initialPoint = graphie.scalePoint(_.head(points));
|
|
10301
|
+
super(graphie, initialPoint);
|
|
10302
|
+
this.wrapper = void 0;
|
|
10303
|
+
this.visibleShape = void 0;
|
|
10304
|
+
options = _.extend({}, DEFAULT_OPTIONS$2, options);
|
|
10305
|
+
const fixedPath = graphie.fixedPath(points, options.center, options.createPath);
|
|
10306
|
+
this.wrapper = fixedPath.wrapper;
|
|
10307
|
+
this.visibleShape = fixedPath.visibleShape;
|
|
10308
|
+
|
|
10309
|
+
// Add to appropriate graphie layer
|
|
10310
|
+
if (options.mouselayer) {
|
|
10311
|
+
// Disable browser handling of all panning and zooming gestures on the
|
|
10312
|
+
// movable wrapper so that when moved the browser does not scroll page
|
|
10313
|
+
this.wrapper.style.touchAction = "none";
|
|
10314
|
+
this.graphie.addToMouseLayerWrapper(this.wrapper);
|
|
10315
|
+
} else {
|
|
10316
|
+
this.graphie.addToVisibleLayerWrapper(this.wrapper);
|
|
10317
|
+
}
|
|
10348
10318
|
}
|
|
10319
|
+
}
|
|
10349
10320
|
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
//
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10321
|
+
class Arrowhead extends WrappedPath {
|
|
10322
|
+
constructor(graphie, style) {
|
|
10323
|
+
// Points that define the arrowhead
|
|
10324
|
+
const center = [0.75, 0];
|
|
10325
|
+
const points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]].map(point => {
|
|
10326
|
+
// Scale points by `Arrowhead.scale` around `center`
|
|
10327
|
+
const pv = vector$1.subtract(point, center);
|
|
10328
|
+
const pvScaled = vector$1.scale(pv, Arrowhead.scale);
|
|
10329
|
+
return vector$1.add(center, pvScaled);
|
|
10330
|
+
});
|
|
10331
|
+
const unscaledPoints = points.map(graphie.unscalePoint);
|
|
10332
|
+
super(graphie, unscaledPoints, {
|
|
10333
|
+
center: graphie.unscalePoint(center),
|
|
10334
|
+
createPath: createCubicPath
|
|
10335
|
+
});
|
|
10336
|
+
this.center = void 0;
|
|
10337
|
+
this.center = center;
|
|
10338
|
+
this.attr(_.extend({
|
|
10339
|
+
"stroke-linejoin": "round",
|
|
10340
|
+
"stroke-linecap": "round",
|
|
10341
|
+
"stroke-dasharray": ""
|
|
10342
|
+
}, style));
|
|
10362
10343
|
}
|
|
10363
|
-
|
|
10364
|
-
const
|
|
10365
|
-
|
|
10366
|
-
const wrapper = this.wrapper;
|
|
10367
|
-
wrapper.style.filter = filter;
|
|
10368
|
-
|
|
10369
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10370
|
-
this.moveTo = function (point) {
|
|
10371
|
-
const delta = vector$1.subtract(this.graphie.scalePoint(point), this.graphie.scalePoint(this.initialPoint));
|
|
10372
|
-
const do3dTransform = InteractiveUtil.getCanUse3dTransform();
|
|
10373
|
-
const transform = "translateX(" + Math.round(delta[0]) + "px) " + "translateY(" + Math.round(delta[1]) + "px)" + (do3dTransform ? " translateZ(0)" : "");
|
|
10374
|
-
this.transform(transform);
|
|
10375
|
-
};
|
|
10344
|
+
toCoordAtAngle(coord, angle) {
|
|
10345
|
+
const clipPoint = this.graphie.scalePoint(getClipPoint(this.graphie, coord, angle));
|
|
10346
|
+
this.transform("translateX(" + (clipPoint[0] + Arrowhead.scale * this.center[0]) + "px) " + "translateY(" + (clipPoint[1] + Arrowhead.scale * this.center[1]) + "px) " + "translateZ(0) " + "rotate(" + (360 - KhanMath.bound(angle)) + "deg)");
|
|
10376
10347
|
}
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10348
|
+
}
|
|
10349
|
+
|
|
10350
|
+
// We can't just pass in a path to `graph.fixedPath` as we need to modify
|
|
10351
|
+
// the points in some way, so instead we provide a function for creating
|
|
10352
|
+
// the path once the points have been transformed
|
|
10353
|
+
Arrowhead.scale = 1.4;
|
|
10354
|
+
const createCubicPath = function createCubicPath(points) {
|
|
10355
|
+
let path = "M" + points[0][0] + " " + points[0][1];
|
|
10356
|
+
for (let i = 1; i < points.length; i += 3) {
|
|
10357
|
+
path += "C" + points[i][0] + " " + points[i][1] + " " + points[i + 1][0] + " " + points[i + 1][1] + " " + points[i + 2][0] + " " + points[i + 2][1];
|
|
10382
10358
|
}
|
|
10359
|
+
return path;
|
|
10383
10360
|
};
|
|
10384
|
-
_.extend(WrappedEllipse.prototype, WrappedDefaults);
|
|
10385
10361
|
|
|
10386
10362
|
const DEFAULT_OPTIONS$1 = {
|
|
10387
|
-
|
|
10388
|
-
mouselayer: false
|
|
10363
|
+
maxScale: 1,
|
|
10364
|
+
mouselayer: false,
|
|
10365
|
+
shadow: false,
|
|
10366
|
+
disableMouseEventsOnWrapper: false
|
|
10389
10367
|
};
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10368
|
+
class WrappedEllipse extends WrappedDrawing {
|
|
10369
|
+
constructor(graphie, center, radii, options) {
|
|
10370
|
+
super(graphie, center);
|
|
10371
|
+
this.initialPoint = void 0;
|
|
10372
|
+
this.wrapper = void 0;
|
|
10373
|
+
this.visibleShape = void 0;
|
|
10374
|
+
options = _.extend({}, DEFAULT_OPTIONS$1, options);
|
|
10375
|
+
|
|
10376
|
+
// Add `wrapper`, `visibleShape`, and remaining properties.
|
|
10377
|
+
const fixedEllipse = graphie.fixedEllipse(center, radii, options.maxScale, options.padding);
|
|
10378
|
+
this.visibleShape = fixedEllipse.visibleShape;
|
|
10379
|
+
this.wrapper = fixedEllipse.wrapper;
|
|
10380
|
+
this.graphie = graphie;
|
|
10381
|
+
this.initialPoint = center;
|
|
10382
|
+
if (options.interactiveKindForTesting) {
|
|
10383
|
+
this.wrapper.setAttribute("data-interactive-kind-for-testing", options.interactiveKindForTesting);
|
|
10384
|
+
}
|
|
10398
10385
|
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10386
|
+
// Add to appropriate graphie layer
|
|
10387
|
+
if (options.mouselayer) {
|
|
10388
|
+
// Disable browser handling of all panning and zooming gestures on the
|
|
10389
|
+
// movable wrapper so that when moved the browser does not scroll page
|
|
10390
|
+
this.wrapper.style.touchAction = "none";
|
|
10391
|
+
this.graphie.addToMouseLayerWrapper(this.wrapper);
|
|
10392
|
+
} else {
|
|
10393
|
+
this.graphie.addToVisibleLayerWrapper(this.wrapper);
|
|
10394
|
+
}
|
|
10395
|
+
if (options.shadow) {
|
|
10396
|
+
const filter = "drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.5))";
|
|
10397
|
+
const wrapper = this.wrapper;
|
|
10398
|
+
wrapper.style.filter = filter;
|
|
10399
|
+
this.moveTo = function (point) {
|
|
10400
|
+
const delta = vector$1.subtract(this.graphie.scalePoint(point), this.graphie.scalePoint(this.initialPoint));
|
|
10401
|
+
const do3dTransform = InteractiveUtil.getCanUse3dTransform();
|
|
10402
|
+
const transform = "translateX(" + Math.round(delta[0]) + "px) " + "translateY(" + Math.round(delta[1]) + "px)" + (do3dTransform ? " translateZ(0)" : "");
|
|
10403
|
+
this.transform(transform);
|
|
10404
|
+
};
|
|
10405
|
+
}
|
|
10406
|
+
if (options.disableMouseEventsOnWrapper) {
|
|
10407
|
+
this.wrapper.style.pointerEvents = "none";
|
|
10408
|
+
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10409
|
+
this.visibleShape.node.style.pointerEvents = "auto";
|
|
10410
|
+
}
|
|
10406
10411
|
}
|
|
10412
|
+
}
|
|
10407
10413
|
|
|
10408
|
-
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10424
|
-
|
|
10414
|
+
const DEFAULT_OPTIONS = {
|
|
10415
|
+
thickness: 2,
|
|
10416
|
+
mouselayer: false
|
|
10417
|
+
};
|
|
10418
|
+
class WrappedLine extends WrappedDrawing {
|
|
10419
|
+
constructor(graphie, start, end, options) {
|
|
10420
|
+
// Always make the line as large as possible and horizontal; this
|
|
10421
|
+
// simplifies a lot of the transforms, e.g., we can rotate by exactly the
|
|
10422
|
+
// angle of the argument points in `moveTo`.
|
|
10423
|
+
const initialStart = [graphie.range[0][0], 0];
|
|
10424
|
+
const initialEnd = [graphie.range[0][1], 0];
|
|
10425
|
+
const initialPoint = graphie.scalePoint(initialStart);
|
|
10426
|
+
super(graphie, initialPoint);
|
|
10427
|
+
this.initialLength = void 0;
|
|
10428
|
+
this.wrapper = void 0;
|
|
10429
|
+
this.visibleShape = void 0;
|
|
10430
|
+
options = _.extend({}, DEFAULT_OPTIONS, options);
|
|
10431
|
+
const fixedLine = graphie.fixedLine(initialStart, initialEnd, options.thickness);
|
|
10432
|
+
this.wrapper = fixedLine.wrapper;
|
|
10433
|
+
this.visibleShape = fixedLine.visibleShape;
|
|
10434
|
+
if (options.interactiveKindForTesting) {
|
|
10435
|
+
this.wrapper.setAttribute("data-interactive-kind-for-testing", options.interactiveKindForTesting);
|
|
10436
|
+
}
|
|
10437
|
+
this.visibleShape.attr(options.normalStyle);
|
|
10438
|
+
|
|
10439
|
+
// Save properties for computing transformations
|
|
10440
|
+
this.initialPoint = initialPoint;
|
|
10441
|
+
this.initialLength = point.distanceToPoint(graphie.scalePoint(initialStart), graphie.scalePoint(initialEnd));
|
|
10442
|
+
|
|
10443
|
+
// Add to appropriate graphie layer
|
|
10444
|
+
if (options.mouselayer) {
|
|
10445
|
+
// Disable browser handling of all panning and zooming gestures on the
|
|
10446
|
+
// movable wrapper so that when moved the browser does not scroll page
|
|
10447
|
+
this.wrapper.style.touchAction = "none";
|
|
10448
|
+
this.graphie.addToMouseLayerWrapper(this.wrapper);
|
|
10449
|
+
} else {
|
|
10450
|
+
this.graphie.addToVisibleLayerWrapper(this.wrapper);
|
|
10451
|
+
}
|
|
10425
10452
|
|
|
10426
|
-
//
|
|
10427
|
-
this.
|
|
10428
|
-
} else {
|
|
10429
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10430
|
-
this.graphie.addToVisibleLayerWrapper(this.wrapper);
|
|
10453
|
+
// Move line to initial points
|
|
10454
|
+
this.moveTo(start, end);
|
|
10431
10455
|
}
|
|
10432
|
-
|
|
10433
|
-
// Move to argument points
|
|
10434
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10435
|
-
this.moveTo(start, end);
|
|
10436
|
-
};
|
|
10437
|
-
_.extend(WrappedLine.prototype, WrappedDefaults, {
|
|
10438
|
-
getMouseTarget: function () {
|
|
10456
|
+
getMouseTarget() {
|
|
10439
10457
|
return this.wrapper;
|
|
10440
|
-
}
|
|
10441
|
-
|
|
10458
|
+
}
|
|
10459
|
+
|
|
10460
|
+
// TODO(benchristel): we need to suppress a type error here because moveTo
|
|
10461
|
+
// takes 2 parameters here, but only 1 parameter in the superclass's
|
|
10462
|
+
// definition. Rename this method after confirming it's safe to do so
|
|
10463
|
+
// @ts-expect-error - TS2416: Property 'moveTo' in type 'WrappedLine' is not assignable to the same property in base type 'WrappedDefaults'.
|
|
10464
|
+
moveTo(start, end) {
|
|
10442
10465
|
const scaledStart = this.graphie.scalePoint(start);
|
|
10443
10466
|
const scaledEnd = this.graphie.scalePoint(end);
|
|
10444
10467
|
|
|
@@ -10454,45 +10477,7 @@ _.extend(WrappedLine.prototype, WrappedDefaults, {
|
|
|
10454
10477
|
const transformation = "translateX(" + delta[0] + "px) " + "translateY(" + delta[1] + "px) " + (do3dTransform ? " translateZ(0)" : "") + "rotate(" + angle + "deg) " + "scaleX(" + scale + ") scaleY(1)";
|
|
10455
10478
|
this.transform(transformation);
|
|
10456
10479
|
}
|
|
10457
|
-
}
|
|
10458
|
-
|
|
10459
|
-
const DEFAULT_OPTIONS = {
|
|
10460
|
-
center: null,
|
|
10461
|
-
// gets ignored in `graphie.fixedPath` if `null`
|
|
10462
|
-
createPath: null,
|
|
10463
|
-
// gets defaulted in `graphie.fixedPath` if `null`
|
|
10464
|
-
mouselayer: false
|
|
10465
|
-
};
|
|
10466
|
-
const WrappedPath = function WrappedPath(graphie, points, options) {
|
|
10467
|
-
options = _.extend({}, DEFAULT_OPTIONS, options);
|
|
10468
|
-
|
|
10469
|
-
// Add `wrapper` and `visibleShape`
|
|
10470
|
-
_.extend(
|
|
10471
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10472
|
-
this, graphie.fixedPath(points, options.center, options.createPath));
|
|
10473
|
-
|
|
10474
|
-
// Add remaining properties
|
|
10475
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10476
|
-
_.extend(this, {
|
|
10477
|
-
graphie: graphie,
|
|
10478
|
-
initialPoint: graphie.scalePoint(_.head(points))
|
|
10479
|
-
});
|
|
10480
|
-
|
|
10481
|
-
// Add to appropriate graphie layer
|
|
10482
|
-
if (options.mouselayer) {
|
|
10483
|
-
// Disable browser handling of all panning and zooming gestures on the
|
|
10484
|
-
// movable wrapper so that when moved the browser does not scroll page
|
|
10485
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10486
|
-
this.wrapper.style.touchAction = "none";
|
|
10487
|
-
|
|
10488
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10489
|
-
this.graphie.addToMouseLayerWrapper(this.wrapper);
|
|
10490
|
-
} else {
|
|
10491
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
10492
|
-
this.graphie.addToVisibleLayerWrapper(this.wrapper);
|
|
10493
|
-
}
|
|
10494
|
-
};
|
|
10495
|
-
_.extend(WrappedPath.prototype, WrappedDefaults);
|
|
10480
|
+
}
|
|
10496
10481
|
|
|
10497
10482
|
/**
|
|
10498
10483
|
* A collection of geomtry-related utility functions
|
|
@@ -10717,9 +10702,6 @@ firstPoints, secondPoints) {
|
|
|
10717
10702
|
}
|
|
10718
10703
|
|
|
10719
10704
|
/* eslint-disable @babel/no-invalid-this */
|
|
10720
|
-
const {
|
|
10721
|
-
getCanUse3dTransform
|
|
10722
|
-
} = InteractiveUtil;
|
|
10723
10705
|
function scaledDistanceFromAngle(angle) {
|
|
10724
10706
|
const a = 3.51470560176242 * 20;
|
|
10725
10707
|
const b = 0.5687298702748785 * 20;
|
|
@@ -11603,52 +11585,15 @@ _.extend(GraphUtils.Graphie.prototype, {
|
|
|
11603
11585
|
_.each(elements, function (element) {
|
|
11604
11586
|
element.moveTo(start, end);
|
|
11605
11587
|
});
|
|
11606
|
-
const createArrow = function createArrow(graph, style) {
|
|
11607
|
-
const center = [0.75, 0];
|
|
11608
|
-
let points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]];
|
|
11609
|
-
const scale = 1.4;
|
|
11610
|
-
points = _.map(points, function (point) {
|
|
11611
|
-
const pv = vector$1.subtract(point, center);
|
|
11612
|
-
const pvScaled = vector$1.scale(pv, scale);
|
|
11613
|
-
return vector$1.add(center, pvScaled);
|
|
11614
|
-
});
|
|
11615
|
-
const createCubicPath = function createCubicPath(points) {
|
|
11616
|
-
let path = "M" + points[0][0] + " " + points[0][1];
|
|
11617
|
-
for (let i = 1; i < points.length; i += 3) {
|
|
11618
|
-
path += "C" + points[i][0] + " " + points[i][1] + " " + points[i + 1][0] + " " + points[i + 1][1] + " " + points[i + 2][0] + " " + points[i + 2][1];
|
|
11619
|
-
}
|
|
11620
|
-
return path;
|
|
11621
|
-
};
|
|
11622
|
-
const unscaledPoints = _.map(points, graph.unscalePoint);
|
|
11623
|
-
const options = {
|
|
11624
|
-
center: graph.unscalePoint(center),
|
|
11625
|
-
createPath: createCubicPath
|
|
11626
|
-
};
|
|
11627
|
-
const arrowHead = new WrappedPath(graph, unscaledPoints, options);
|
|
11628
|
-
arrowHead.attr(_.extend({
|
|
11629
|
-
"stroke-linejoin": "round",
|
|
11630
|
-
"stroke-linecap": "round",
|
|
11631
|
-
"stroke-dasharray": ""
|
|
11632
|
-
}, style));
|
|
11633
|
-
|
|
11634
|
-
// Add custom function for transforming arrowheads that
|
|
11635
|
-
// accounts for center, scaling, etc.
|
|
11636
|
-
arrowHead.toCoordAtAngle = function (coord, angle) {
|
|
11637
|
-
const clipPoint = graph.scalePoint(getClipPoint(graph, coord, angle));
|
|
11638
|
-
const do3dTransform = getCanUse3dTransform();
|
|
11639
|
-
arrowHead.transform("translateX(" + (clipPoint[0] + scale * center[0]) + "px) " + "translateY(" + (clipPoint[1] + scale * center[1]) + "px) " + (do3dTransform ? "translateZ(0) " : "") + "rotate(" + (360 - KhanMath.bound(angle)) + "deg)");
|
|
11640
|
-
};
|
|
11641
|
-
return arrowHead;
|
|
11642
|
-
};
|
|
11643
11588
|
|
|
11644
11589
|
// Add arrows
|
|
11645
11590
|
if (this._arrows == null) {
|
|
11646
11591
|
this._arrows = [];
|
|
11647
11592
|
if (this.extendLine) {
|
|
11648
|
-
this._arrows.push(
|
|
11649
|
-
this._arrows.push(
|
|
11593
|
+
this._arrows.push(new Arrowhead(graph, this.normalStyle));
|
|
11594
|
+
this._arrows.push(new Arrowhead(graph, this.normalStyle));
|
|
11650
11595
|
} else if (this.extendRay) {
|
|
11651
|
-
this._arrows.push(
|
|
11596
|
+
this._arrows.push(new Arrowhead(graph, this.normalStyle));
|
|
11652
11597
|
}
|
|
11653
11598
|
}
|
|
11654
11599
|
const coordForArrow = [this.coordA, this.coordZ];
|
|
@@ -14067,78 +14012,6 @@ const getScaledAngle = function getScaledAngle(line) {
|
|
|
14067
14012
|
return vector$1.polarDegFromCart(vector$1.subtract(scaledZ, scaledA))[1];
|
|
14068
14013
|
};
|
|
14069
14014
|
|
|
14070
|
-
// Given `coord` and `angle`, find the point where a line extended
|
|
14071
|
-
// from `coord` in the direction of `angle` would be clipped by the
|
|
14072
|
-
// edge of the graphie canvas. Then draw an arrowhead at that point
|
|
14073
|
-
// pointing in the direction of `angle`.
|
|
14074
|
-
const getClipPoint = function getClipPoint(graph, coord, angle) {
|
|
14075
|
-
// Actually put the arrowheads 4px from the edge so they have
|
|
14076
|
-
// a bit of room
|
|
14077
|
-
const xExtent = graph.range[0][1] - graph.range[0][0];
|
|
14078
|
-
const yExtent = graph.range[1][1] - graph.range[1][0];
|
|
14079
|
-
|
|
14080
|
-
// shoot a point off into the distance ...
|
|
14081
|
-
const distance = xExtent + yExtent;
|
|
14082
|
-
// we need to scale the point according to the scale of the axes
|
|
14083
|
-
const angleVec = graph.unscaleVector(vector$1.cartFromPolarDeg(1, angle));
|
|
14084
|
-
const distVec = vector$1.scale(vector$1.normalize(angleVec), distance);
|
|
14085
|
-
const farCoord = vector$1.add(coord, distVec);
|
|
14086
|
-
const scaledAngle = vector$1.polarDegFromCart(angleVec)[1];
|
|
14087
|
-
// ... and then bring it back
|
|
14088
|
-
const clipPoint = graph.constrainToBoundsOnAngle(farCoord, 4, scaledAngle * Math.PI / 180);
|
|
14089
|
-
return clipPoint;
|
|
14090
|
-
};
|
|
14091
|
-
|
|
14092
|
-
// Given `coord` and `angle`, find the point where a line extended
|
|
14093
|
-
// from `coord` in the direction of `angle` would be clipped by the
|
|
14094
|
-
// edge of the graphie canvas. Then draw an arrowhead at that point
|
|
14095
|
-
// pointing in the direction of `angle`.
|
|
14096
|
-
const createArrow = function createArrow(graph, style) {
|
|
14097
|
-
// Points that define the arrowhead
|
|
14098
|
-
const center = [0.75, 0];
|
|
14099
|
-
let points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]];
|
|
14100
|
-
|
|
14101
|
-
// Scale points by 1.4 around (0.75, 0)
|
|
14102
|
-
const scale = 1.4;
|
|
14103
|
-
points = _.map(points, function (point) {
|
|
14104
|
-
const pv = vector$1.subtract(point, center);
|
|
14105
|
-
const pvScaled = vector$1.scale(pv, scale);
|
|
14106
|
-
return vector$1.add(center, pvScaled);
|
|
14107
|
-
});
|
|
14108
|
-
|
|
14109
|
-
// We can't just pass in a path to `graph.fixedPath` as we need to modify
|
|
14110
|
-
// the points in some way, so instead we provide a function for creating
|
|
14111
|
-
// the path once the points have been transformed
|
|
14112
|
-
const createCubicPath = function createCubicPath(points) {
|
|
14113
|
-
let path = "M" + points[0][0] + " " + points[0][1];
|
|
14114
|
-
for (let i = 1; i < points.length; i += 3) {
|
|
14115
|
-
path += "C" + points[i][0] + " " + points[i][1] + " " + points[i + 1][0] + " " + points[i + 1][1] + " " + points[i + 2][0] + " " + points[i + 2][1];
|
|
14116
|
-
}
|
|
14117
|
-
return path;
|
|
14118
|
-
};
|
|
14119
|
-
|
|
14120
|
-
// Create arrowhead
|
|
14121
|
-
const unscaledPoints = _.map(points, graph.unscalePoint);
|
|
14122
|
-
const options = {
|
|
14123
|
-
center: graph.unscalePoint(center),
|
|
14124
|
-
createPath: createCubicPath
|
|
14125
|
-
};
|
|
14126
|
-
const arrowHead = new WrappedPath(graph, unscaledPoints, options);
|
|
14127
|
-
arrowHead.attr(_.extend({
|
|
14128
|
-
"stroke-linejoin": "round",
|
|
14129
|
-
"stroke-linecap": "round",
|
|
14130
|
-
"stroke-dasharray": ""
|
|
14131
|
-
}, style));
|
|
14132
|
-
|
|
14133
|
-
// Add custom function for transforming arrowheads that accounts for
|
|
14134
|
-
// center, scaling, etc.
|
|
14135
|
-
arrowHead.toCoordAtAngle = function (coord, angle) {
|
|
14136
|
-
const clipPoint = graph.scalePoint(getClipPoint(graph, coord, angle));
|
|
14137
|
-
arrowHead.transform("translateX(" + (clipPoint[0] + scale * center[0]) + "px) " + "translateY(" + (clipPoint[1] + scale * center[1]) + "px) " + "translateZ(0) " + "rotate(" + (360 - KhanMath.bound(angle)) + "deg)");
|
|
14138
|
-
};
|
|
14139
|
-
return arrowHead;
|
|
14140
|
-
};
|
|
14141
|
-
|
|
14142
14015
|
/**
|
|
14143
14016
|
* MovableLine option functions
|
|
14144
14017
|
*/
|
|
@@ -14225,16 +14098,16 @@ const draw$3 = {
|
|
|
14225
14098
|
// @ts-expect-error - TS2551 - Property '_arrows' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. Did you mean 'arrows'?
|
|
14226
14099
|
this._arrows.push(
|
|
14227
14100
|
// @ts-expect-error - TS2339 - Property 'graphie' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. | TS2339 - Property 'normalStyle' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'.
|
|
14228
|
-
|
|
14101
|
+
new Arrowhead(this.graphie, this.normalStyle()));
|
|
14229
14102
|
// @ts-expect-error - TS2551 - Property '_arrows' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. Did you mean 'arrows'?
|
|
14230
14103
|
this._arrows.push(
|
|
14231
14104
|
// @ts-expect-error - TS2339 - Property 'graphie' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. | TS2339 - Property 'normalStyle' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'.
|
|
14232
|
-
|
|
14105
|
+
new Arrowhead(this.graphie, this.normalStyle()));
|
|
14233
14106
|
} else if (state.extendRay) {
|
|
14234
14107
|
// @ts-expect-error - TS2551 - Property '_arrows' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. Did you mean 'arrows'?
|
|
14235
14108
|
this._arrows.push(
|
|
14236
14109
|
// @ts-expect-error - TS2339 - Property 'graphie' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'. | TS2339 - Property 'normalStyle' does not exist on type '{ readonly basic: (state: any) => void; readonly arrows: (state: any) => void; readonly highlight: (state: any, prevState: any) => void; }'.
|
|
14237
|
-
|
|
14110
|
+
new Arrowhead(this.graphie, this.normalStyle()));
|
|
14238
14111
|
}
|
|
14239
14112
|
}
|
|
14240
14113
|
|
|
@@ -14380,6 +14253,75 @@ var MovableLineOptions = {
|
|
|
14380
14253
|
}
|
|
14381
14254
|
};
|
|
14382
14255
|
|
|
14256
|
+
/**
|
|
14257
|
+
* A work-in-progress of _ methods for objects.
|
|
14258
|
+
* That is, they take an object as a parameter,
|
|
14259
|
+
* and return an object instead of an array.
|
|
14260
|
+
*
|
|
14261
|
+
* TODO(aria): Move this out of interactive2
|
|
14262
|
+
*/
|
|
14263
|
+
|
|
14264
|
+
/**
|
|
14265
|
+
* Does a pluck on keys inside objects in an object
|
|
14266
|
+
*
|
|
14267
|
+
* Ex:
|
|
14268
|
+
* tools = {
|
|
14269
|
+
* translation: {
|
|
14270
|
+
* enabled: true
|
|
14271
|
+
* },
|
|
14272
|
+
* rotation: {
|
|
14273
|
+
* enabled: false
|
|
14274
|
+
* }
|
|
14275
|
+
* };
|
|
14276
|
+
* pluckObject(tools, "enabled") returns {
|
|
14277
|
+
* translation: true
|
|
14278
|
+
* rotation: false
|
|
14279
|
+
* }
|
|
14280
|
+
*/
|
|
14281
|
+
const pluck = function pluck(table, subKey) {
|
|
14282
|
+
return _.object(_.map(table, function (value, key) {
|
|
14283
|
+
return [key, value[subKey]];
|
|
14284
|
+
}));
|
|
14285
|
+
};
|
|
14286
|
+
|
|
14287
|
+
/**
|
|
14288
|
+
* Maps an object to an object
|
|
14289
|
+
*
|
|
14290
|
+
* > mapObject({a: '1', b: '2'}, (value, key) => {
|
|
14291
|
+
* return value + 1;
|
|
14292
|
+
* });
|
|
14293
|
+
* {a: 2, b: 3}
|
|
14294
|
+
*/
|
|
14295
|
+
const mapObject$2 = function mapObject(obj, lambda) {
|
|
14296
|
+
const result = {};
|
|
14297
|
+
_.each(_.keys(obj), function (key) {
|
|
14298
|
+
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'K'.
|
|
14299
|
+
result[key] = lambda(obj[key], key);
|
|
14300
|
+
});
|
|
14301
|
+
return result;
|
|
14302
|
+
};
|
|
14303
|
+
|
|
14304
|
+
/**
|
|
14305
|
+
* Maps an array to an object
|
|
14306
|
+
*
|
|
14307
|
+
* > mapObjectFromArray(['a', 'b'], function(elem) {
|
|
14308
|
+
* return elem + elem;
|
|
14309
|
+
* });
|
|
14310
|
+
* {a: 'aa', b: 'bb'}
|
|
14311
|
+
*/
|
|
14312
|
+
const mapObjectFromArray$1 = function mapObjectFromArray(arr, lambda) {
|
|
14313
|
+
const result = {};
|
|
14314
|
+
_.each(arr, function (elem) {
|
|
14315
|
+
result[elem] = lambda(elem);
|
|
14316
|
+
});
|
|
14317
|
+
return result;
|
|
14318
|
+
};
|
|
14319
|
+
var objective_ = {
|
|
14320
|
+
pluck: pluck,
|
|
14321
|
+
mapObject: mapObject$2,
|
|
14322
|
+
mapObjectFromArray: mapObjectFromArray$1
|
|
14323
|
+
};
|
|
14324
|
+
|
|
14383
14325
|
/**
|
|
14384
14326
|
* MovableLine
|
|
14385
14327
|
*/
|
|
@@ -17907,33 +17849,33 @@ class Lint extends React.Component {
|
|
|
17907
17849
|
let warningText;
|
|
17908
17850
|
let warningTextStyle;
|
|
17909
17851
|
if (this.props.severity === Severity.Error) {
|
|
17910
|
-
severityStyle = styles$
|
|
17852
|
+
severityStyle = styles$B.indicatorError;
|
|
17911
17853
|
warningText = "Error";
|
|
17912
|
-
warningTextStyle = styles$
|
|
17854
|
+
warningTextStyle = styles$B.publishBlockingError;
|
|
17913
17855
|
} else if (this.props.severity === Severity.Warning) {
|
|
17914
|
-
severityStyle = styles$
|
|
17856
|
+
severityStyle = styles$B.indicatorWarning;
|
|
17915
17857
|
warningText = "Warning";
|
|
17916
|
-
warningTextStyle = styles$
|
|
17858
|
+
warningTextStyle = styles$B.warning;
|
|
17917
17859
|
} else {
|
|
17918
|
-
severityStyle = styles$
|
|
17860
|
+
severityStyle = styles$B.indicatorGuideline;
|
|
17919
17861
|
warningText = "Recommendation";
|
|
17920
|
-
warningTextStyle = styles$
|
|
17862
|
+
warningTextStyle = styles$B.warning;
|
|
17921
17863
|
}
|
|
17922
17864
|
return /*#__PURE__*/React.createElement("a", {
|
|
17923
17865
|
href: `https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,
|
|
17924
17866
|
target: "lint-help-window",
|
|
17925
17867
|
className: css(style)
|
|
17926
17868
|
}, /*#__PURE__*/React.createElement("span", {
|
|
17927
|
-
className: css(styles$
|
|
17869
|
+
className: css(styles$B.indicator, severityStyle)
|
|
17928
17870
|
}, this.props.severity === 1 && /*#__PURE__*/React.createElement(InlineIcon, exclamationIcon)), /*#__PURE__*/React.createElement("div", {
|
|
17929
|
-
className: css(styles$
|
|
17871
|
+
className: css(styles$B.tooltip, tooltipAbove && styles$B.tooltipAbove)
|
|
17930
17872
|
}, this.props.message.split("\n\n").map((m, i) => /*#__PURE__*/React.createElement("p", {
|
|
17931
17873
|
key: i,
|
|
17932
|
-
className: css(styles$
|
|
17874
|
+
className: css(styles$B.tooltipParagraph)
|
|
17933
17875
|
}, /*#__PURE__*/React.createElement("span", {
|
|
17934
17876
|
className: css(warningTextStyle)
|
|
17935
17877
|
}, warningText, ":", " "), m)), /*#__PURE__*/React.createElement("div", {
|
|
17936
|
-
className: css(styles$
|
|
17878
|
+
className: css(styles$B.tail, tooltipAbove && styles$B.tailAbove)
|
|
17937
17879
|
})));
|
|
17938
17880
|
};
|
|
17939
17881
|
}
|
|
@@ -17971,20 +17913,20 @@ class Lint extends React.Component {
|
|
|
17971
17913
|
}
|
|
17972
17914
|
if (blockHighlight) {
|
|
17973
17915
|
return /*#__PURE__*/React.createElement("span", {
|
|
17974
|
-
className: css(styles$
|
|
17975
|
-
}, this.renderLink(styles$
|
|
17916
|
+
className: css(styles$B.lintContainer, styles$B.lintContainerBlock)
|
|
17917
|
+
}, this.renderLink(styles$B.radioWidgetHoverTarget), /*#__PURE__*/React.createElement("span", null, children));
|
|
17976
17918
|
}
|
|
17977
17919
|
if (inline) {
|
|
17978
17920
|
return /*#__PURE__*/React.createElement("span", {
|
|
17979
|
-
className: css(styles$
|
|
17980
|
-
}, this.renderLink(styles$
|
|
17921
|
+
className: css(styles$B.lintContainer)
|
|
17922
|
+
}, this.renderLink(styles$B.inlineHoverTarget), /*#__PURE__*/React.createElement("span", null, children));
|
|
17981
17923
|
}
|
|
17982
17924
|
return /*#__PURE__*/React.createElement("div", {
|
|
17983
|
-
className: css(styles$
|
|
17984
|
-
}, this.renderLink(styles$
|
|
17925
|
+
className: css(styles$B.lintContainer)
|
|
17926
|
+
}, this.renderLink(styles$B.hoverTarget), /*#__PURE__*/React.createElement("div", null, children));
|
|
17985
17927
|
}
|
|
17986
17928
|
}
|
|
17987
|
-
const styles$
|
|
17929
|
+
const styles$B = StyleSheet.create({
|
|
17988
17930
|
// This is the class of the outermost element.
|
|
17989
17931
|
// We use relative positioning so that the lint indicator can be
|
|
17990
17932
|
// positioned absolutely relative to the position of the linty container.
|
|
@@ -19887,7 +19829,7 @@ class Renderer extends React.Component {
|
|
|
19887
19829
|
paddingLeft: margin,
|
|
19888
19830
|
paddingRight: margin
|
|
19889
19831
|
};
|
|
19890
|
-
const mobileInnerStyle = _extends({}, innerStyle, styles$
|
|
19832
|
+
const mobileInnerStyle = _extends({}, innerStyle, styles$A.mobileZoomableParentFix);
|
|
19891
19833
|
return /*#__PURE__*/React.createElement("div", {
|
|
19892
19834
|
key: state.key,
|
|
19893
19835
|
className: "perseus-block-math",
|
|
@@ -20008,7 +19950,7 @@ class Renderer extends React.Component {
|
|
|
20008
19950
|
paddingLeft: 0,
|
|
20009
19951
|
paddingRight: 0
|
|
20010
19952
|
};
|
|
20011
|
-
const mobileInnerStyle = _extends({}, innerStyle, styles$
|
|
19953
|
+
const mobileInnerStyle = _extends({}, innerStyle, styles$A.mobileZoomableParentFix);
|
|
20012
19954
|
const wrappedOutput = /*#__PURE__*/React.createElement("div", {
|
|
20013
19955
|
style: _extends({}, mobileInnerStyle, {
|
|
20014
19956
|
overflowX: "auto"
|
|
@@ -20655,7 +20597,7 @@ Renderer.defaultProps = {
|
|
|
20655
20597
|
onSerializedStateUpdated: () => {},
|
|
20656
20598
|
linterContext: PerseusLinter.linterContextDefault
|
|
20657
20599
|
};
|
|
20658
|
-
const styles$
|
|
20600
|
+
const styles$A = {
|
|
20659
20601
|
mobileZoomableParentFix: {
|
|
20660
20602
|
// NOTE(abdul): There is an issue where transform animations will
|
|
20661
20603
|
// cause the Zoomable component to disappear when running on the
|
|
@@ -21672,10 +21614,10 @@ class InputNumber extends React.Component {
|
|
|
21672
21614
|
// Note: This is _very_ similar to what `numeric-input.jsx` does. If
|
|
21673
21615
|
// you modify this, double-check if you also need to modify that
|
|
21674
21616
|
// component.
|
|
21675
|
-
const inputStyles = [styles$
|
|
21617
|
+
const inputStyles = [styles$z.default, this.props.size === "small" ? styles$z.small : null, this.props.rightAlign ? styles$z.rightAlign : styles$z.leftAlign];
|
|
21676
21618
|
// Unanswered
|
|
21677
21619
|
if (rubric && !this.props.currentValue) {
|
|
21678
|
-
inputStyles.push(styles$
|
|
21620
|
+
inputStyles.push(styles$z.answerStateUnanswered);
|
|
21679
21621
|
}
|
|
21680
21622
|
return /*#__PURE__*/React.createElement(InputWithExamples
|
|
21681
21623
|
// eslint-disable-next-line react/no-string-refs
|
|
@@ -21760,7 +21702,7 @@ InputNumber.defaultProps = {
|
|
|
21760
21702
|
apiOptions: ApiOptions.defaults,
|
|
21761
21703
|
linterContext: linterContextDefault
|
|
21762
21704
|
};
|
|
21763
|
-
const styles$
|
|
21705
|
+
const styles$z = StyleSheet.create({
|
|
21764
21706
|
default: {
|
|
21765
21707
|
width: 80,
|
|
21766
21708
|
height: "auto"
|
|
@@ -22761,7 +22703,7 @@ const FocusRing = function FocusRing(props) {
|
|
|
22761
22703
|
};
|
|
22762
22704
|
return /*#__PURE__*/React.createElement("span", {
|
|
22763
22705
|
"data-test-id": "focus-ring",
|
|
22764
|
-
className: css(styles$
|
|
22706
|
+
className: css(styles$y.ring),
|
|
22765
22707
|
style: style
|
|
22766
22708
|
}, children);
|
|
22767
22709
|
};
|
|
@@ -22770,7 +22712,7 @@ FocusRing.defaultProps = {
|
|
|
22770
22712
|
color: kaGreen$1,
|
|
22771
22713
|
multipleSelect: false
|
|
22772
22714
|
};
|
|
22773
|
-
const styles$
|
|
22715
|
+
const styles$y = StyleSheet.create({
|
|
22774
22716
|
ring: {
|
|
22775
22717
|
margin: "auto",
|
|
22776
22718
|
display: "inline-block",
|
|
@@ -22807,7 +22749,7 @@ function getChoiceLetter(pos) {
|
|
|
22807
22749
|
}
|
|
22808
22750
|
|
|
22809
22751
|
const CHOICE_ICON_SIZE = 24;
|
|
22810
|
-
const styles$
|
|
22752
|
+
const styles$x = StyleSheet.create({
|
|
22811
22753
|
iconWrapper: {
|
|
22812
22754
|
display: "inline-block",
|
|
22813
22755
|
position: "relative"
|
|
@@ -22830,7 +22772,7 @@ const CrossOutLine = function CrossOutLine(props) {
|
|
|
22830
22772
|
width: CROSS_OUT_LINE_SIZE,
|
|
22831
22773
|
height: CROSS_OUT_LINE_SIZE,
|
|
22832
22774
|
viewBox: `0 0 ${CROSS_OUT_LINE_SIZE} ${CROSS_OUT_LINE_SIZE}`,
|
|
22833
|
-
className: css(styles$
|
|
22775
|
+
className: css(styles$w.crossOutLine),
|
|
22834
22776
|
"data-test-id": "choice-icon__cross-out-line"
|
|
22835
22777
|
}, /*#__PURE__*/React.createElement("line", {
|
|
22836
22778
|
// The line stretches from the bottom-left to top-right.
|
|
@@ -22845,7 +22787,7 @@ const CrossOutLine = function CrossOutLine(props) {
|
|
|
22845
22787
|
strokeLinecap: "round"
|
|
22846
22788
|
}));
|
|
22847
22789
|
};
|
|
22848
|
-
const styles$
|
|
22790
|
+
const styles$w = StyleSheet.create({
|
|
22849
22791
|
crossOutLine: {
|
|
22850
22792
|
// Center the icon within the container.
|
|
22851
22793
|
position: "absolute",
|
|
@@ -22926,7 +22868,7 @@ const ChoiceIcon = function ChoiceIcon(props) {
|
|
|
22926
22868
|
} = props;
|
|
22927
22869
|
const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct);
|
|
22928
22870
|
return /*#__PURE__*/React.createElement("div", {
|
|
22929
|
-
className: css(styles$
|
|
22871
|
+
className: css(styles$x.iconWrapper)
|
|
22930
22872
|
}, /*#__PURE__*/React.createElement(FocusRing, {
|
|
22931
22873
|
color: Color.blue,
|
|
22932
22874
|
visible: focused || hovered,
|
|
@@ -22935,13 +22877,13 @@ const ChoiceIcon = function ChoiceIcon(props) {
|
|
|
22935
22877
|
// @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
|
|
22936
22878
|
style: dynamicStyles,
|
|
22937
22879
|
"data-test-id": "choice-icon__library-choice-icon",
|
|
22938
|
-
className: css(styles$
|
|
22880
|
+
className: css(styles$v.circle, showCorrectness && correct && styles$v.circleCorrect, showCorrectness && !correct && styles$v.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$v.circleIncorrectAnswered)
|
|
22939
22881
|
// used in BaseRadio editMode to check
|
|
22940
22882
|
// if we actually clicked on the radio icon
|
|
22941
22883
|
,
|
|
22942
22884
|
"data-is-radio-icon": true
|
|
22943
22885
|
}, /*#__PURE__*/React.createElement("div", {
|
|
22944
|
-
className: css(styles$
|
|
22886
|
+
className: css(styles$v.innerWrapper)
|
|
22945
22887
|
}, /*#__PURE__*/React.createElement(ChoiceInner, {
|
|
22946
22888
|
pos: pos,
|
|
22947
22889
|
showCorrectness: showCorrectness,
|
|
@@ -22950,7 +22892,7 @@ const ChoiceIcon = function ChoiceIcon(props) {
|
|
|
22950
22892
|
color: dynamicStyles.borderColor
|
|
22951
22893
|
}));
|
|
22952
22894
|
};
|
|
22953
|
-
const styles$
|
|
22895
|
+
const styles$v = StyleSheet.create({
|
|
22954
22896
|
innerWrapper: {
|
|
22955
22897
|
width: CHOICE_ICON_SIZE,
|
|
22956
22898
|
height: CHOICE_ICON_SIZE,
|
|
@@ -23042,19 +22984,19 @@ const OptionStatus = function OptionStatus(props) {
|
|
|
23042
22984
|
}
|
|
23043
22985
|
let textStyle;
|
|
23044
22986
|
if (correct) {
|
|
23045
|
-
textStyle = styles$
|
|
22987
|
+
textStyle = styles$u.correct;
|
|
23046
22988
|
} else {
|
|
23047
22989
|
if (checked || previouslyAnswered) {
|
|
23048
|
-
textStyle = styles$
|
|
22990
|
+
textStyle = styles$u.incorrectAnswered;
|
|
23049
22991
|
} else {
|
|
23050
|
-
textStyle = styles$
|
|
22992
|
+
textStyle = styles$u.incorrect;
|
|
23051
22993
|
}
|
|
23052
22994
|
}
|
|
23053
22995
|
return /*#__PURE__*/React.createElement("div", {
|
|
23054
|
-
className: css(styles$
|
|
22996
|
+
className: css(styles$u.text, textStyle)
|
|
23055
22997
|
}, renderText(checked, correct, crossedOut));
|
|
23056
22998
|
};
|
|
23057
|
-
const styles$
|
|
22999
|
+
const styles$u = StyleSheet.create({
|
|
23058
23000
|
text: {
|
|
23059
23001
|
alignItems: "center",
|
|
23060
23002
|
display: "flex",
|
|
@@ -23129,8 +23071,8 @@ const Choice = function Choice(props) {
|
|
|
23129
23071
|
crossedOut: updatedCrossedOut
|
|
23130
23072
|
});
|
|
23131
23073
|
}
|
|
23132
|
-
const descriptionClassName = classNames("description", css(styles$
|
|
23133
|
-
const rationaleClassName = classNames("perseus-radio-rationale-content", css(styles$
|
|
23074
|
+
const descriptionClassName = classNames("description", css(styles$t.description));
|
|
23075
|
+
const rationaleClassName = classNames("perseus-radio-rationale-content", css(styles$t.rationale));
|
|
23134
23076
|
|
|
23135
23077
|
// We want to show the choices as dimmed out when the choices are disabled.
|
|
23136
23078
|
// However, we don't want to do this when we're in review mode in the
|
|
@@ -23294,7 +23236,7 @@ const Choice = function Choice(props) {
|
|
|
23294
23236
|
"data-test-id": `perseus-radio-rationale-content-${pos}`
|
|
23295
23237
|
}, rationale));
|
|
23296
23238
|
};
|
|
23297
|
-
const styles$
|
|
23239
|
+
const styles$t = StyleSheet.create({
|
|
23298
23240
|
description: {
|
|
23299
23241
|
display: "inline-block",
|
|
23300
23242
|
width: "100%"
|
|
@@ -23486,10 +23428,10 @@ const BaseRadio = function BaseRadio(props) {
|
|
|
23486
23428
|
const isMobile = apiOptions.isMobile;
|
|
23487
23429
|
const firstChoiceHighlighted = choices[0].highlighted;
|
|
23488
23430
|
const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
|
|
23489
|
-
const className = classNames("perseus-widget-radio", !editMode && "perseus-rendered-radio", css(styles$
|
|
23490
|
-
const instructionsClassName = classNames("instructions", css(styles$
|
|
23431
|
+
const className = classNames("perseus-widget-radio", !editMode && "perseus-rendered-radio", css(styles$s.radio, styles$s.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$s.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$s.radioContainerLastHighlighted));
|
|
23432
|
+
const instructionsClassName = classNames("instructions", css(styles$s.instructions, isMobile && styles$s.instructionsMobile));
|
|
23491
23433
|
const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect);
|
|
23492
|
-
const responsiveClassName = css(styles$
|
|
23434
|
+
const responsiveClassName = css(styles$s.responsiveFieldset);
|
|
23493
23435
|
const fieldset = /*#__PURE__*/React.createElement("fieldset", {
|
|
23494
23436
|
className: `perseus-widget-radio-fieldset ${responsiveClassName}`
|
|
23495
23437
|
}, /*#__PURE__*/React.createElement("legend", {
|
|
@@ -23540,7 +23482,7 @@ const BaseRadio = function BaseRadio(props) {
|
|
|
23540
23482
|
const aphroditeClassName = checked => {
|
|
23541
23483
|
// Whether or not to show correctness borders
|
|
23542
23484
|
// for this choice and the next choice.
|
|
23543
|
-
return css(sharedStyles.aboveScratchpad, styles$
|
|
23485
|
+
return css(sharedStyles.aboveScratchpad, styles$s.item, styles$s.responsiveItem, checked && styles$s.selectedItem, checked && choice.highlighted && styles$s.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$s.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$s.nextHighlighted);
|
|
23544
23486
|
};
|
|
23545
23487
|
|
|
23546
23488
|
// HACK(abdulrahman): Preloads the selection-state
|
|
@@ -23614,14 +23556,14 @@ const BaseRadio = function BaseRadio(props) {
|
|
|
23614
23556
|
// Allow for horizontal scrolling if content is too wide, which may be
|
|
23615
23557
|
// an issue especially on phones.
|
|
23616
23558
|
return /*#__PURE__*/React.createElement("div", {
|
|
23617
|
-
className: css(styles$
|
|
23559
|
+
className: css(styles$s.responsiveContainer)
|
|
23618
23560
|
}, fieldset);
|
|
23619
23561
|
};
|
|
23620
23562
|
BaseRadio.defaultProps = {
|
|
23621
23563
|
editMode: false,
|
|
23622
23564
|
multipleSelect: false
|
|
23623
23565
|
};
|
|
23624
|
-
const styles$
|
|
23566
|
+
const styles$s = StyleSheet.create({
|
|
23625
23567
|
instructions: {
|
|
23626
23568
|
display: "block",
|
|
23627
23569
|
color: gray17,
|
|
@@ -24269,9 +24211,9 @@ class Categorizer extends React.Component {
|
|
|
24269
24211
|
indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
|
|
24270
24212
|
}
|
|
24271
24213
|
const table = /*#__PURE__*/React.createElement("table", {
|
|
24272
|
-
className: "categorizer-table " + css(styles$
|
|
24214
|
+
className: "categorizer-table " + css(styles$r.mobileTable)
|
|
24273
24215
|
}, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
|
|
24274
|
-
className: css(styles$
|
|
24216
|
+
className: css(styles$r.emptyHeaderCell)
|
|
24275
24217
|
}), this.props.categories.map((category, i) => {
|
|
24276
24218
|
// Array index is the correct key here, as that's
|
|
24277
24219
|
// how category grading actually works -- no way
|
|
@@ -24279,7 +24221,7 @@ class Categorizer extends React.Component {
|
|
|
24279
24221
|
// middle. (If we later add that, this should be
|
|
24280
24222
|
// fixed.)
|
|
24281
24223
|
return /*#__PURE__*/React.createElement("th", {
|
|
24282
|
-
className: css(styles$
|
|
24224
|
+
className: css(styles$r.header),
|
|
24283
24225
|
key: i
|
|
24284
24226
|
}, /*#__PURE__*/React.createElement(Renderer, {
|
|
24285
24227
|
content: category,
|
|
@@ -24299,7 +24241,7 @@ class Categorizer extends React.Component {
|
|
|
24299
24241
|
})), self.props.categories.map((catName, catNum) => {
|
|
24300
24242
|
const selected = self.props.values[itemNum] === catNum;
|
|
24301
24243
|
return /*#__PURE__*/React.createElement("td", {
|
|
24302
|
-
className: "category " + css(styles$
|
|
24244
|
+
className: "category " + css(styles$r.cell),
|
|
24303
24245
|
key: catNum
|
|
24304
24246
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24305
24247
|
className: ClassNames.INTERACTIVE,
|
|
@@ -24318,7 +24260,7 @@ class Categorizer extends React.Component {
|
|
|
24318
24260
|
onChange: this.onChange.bind(this, itemNum, catNum),
|
|
24319
24261
|
onClick: e => e.stopPropagation()
|
|
24320
24262
|
}), !isMobile && /*#__PURE__*/React.createElement("span", {
|
|
24321
|
-
className: css(styles$
|
|
24263
|
+
className: css(styles$r.radioSpan, selected && styles$r.checkedRadioSpan, this.props.static && selected && styles$r.staticCheckedRadioSpan)
|
|
24322
24264
|
}, selected ? /*#__PURE__*/React.createElement(InlineIcon, iconCircle) : /*#__PURE__*/React.createElement(InlineIcon, iconCircleThin))));
|
|
24323
24265
|
}));
|
|
24324
24266
|
/* eslint-enable max-len */
|
|
@@ -24330,7 +24272,7 @@ class Categorizer extends React.Component {
|
|
|
24330
24272
|
"categorizer-container": true,
|
|
24331
24273
|
"static-mode": this.props.static
|
|
24332
24274
|
});
|
|
24333
|
-
const inlineStyles = this.props.apiOptions.isMobile ? [styles$
|
|
24275
|
+
const inlineStyles = this.props.apiOptions.isMobile ? [styles$r.fullBleedContainer] : [];
|
|
24334
24276
|
return /*#__PURE__*/React.createElement("div", {
|
|
24335
24277
|
className: extraClassNames + " " + css(...inlineStyles)
|
|
24336
24278
|
}, table);
|
|
@@ -24375,7 +24317,7 @@ const pageMargin = 16;
|
|
|
24375
24317
|
|
|
24376
24318
|
// Stylesheets aren't directly testable
|
|
24377
24319
|
/* c8 ignore next */
|
|
24378
|
-
const styles$
|
|
24320
|
+
const styles$r = StyleSheet.create({
|
|
24379
24321
|
mobileTable: {
|
|
24380
24322
|
[mediaQueries.smOrSmaller]: {
|
|
24381
24323
|
minWidth: "auto"
|
|
@@ -24482,7 +24424,7 @@ const toAbsoluteUrl = url => parseUrl(url).href;
|
|
|
24482
24424
|
const {
|
|
24483
24425
|
updateQueryString: updateQueryString$1
|
|
24484
24426
|
} = Util;
|
|
24485
|
-
function getUrlFromProgramID(programID) {
|
|
24427
|
+
function getUrlFromProgramID$1(programID) {
|
|
24486
24428
|
const {
|
|
24487
24429
|
InitialRequestUrl
|
|
24488
24430
|
} = getDependencies();
|
|
@@ -24567,7 +24509,7 @@ class CSProgram extends React.Component {
|
|
|
24567
24509
|
return /*#__PURE__*/React.createElement("div", null);
|
|
24568
24510
|
}
|
|
24569
24511
|
let styleContainer = false;
|
|
24570
|
-
let url = getUrlFromProgramID(this.props.programID);
|
|
24512
|
+
let url = getUrlFromProgramID$1(this.props.programID);
|
|
24571
24513
|
let className;
|
|
24572
24514
|
const style = {
|
|
24573
24515
|
height: this.props.height,
|
|
@@ -24611,7 +24553,7 @@ class CSProgram extends React.Component {
|
|
|
24611
24553
|
// creator "went wild".
|
|
24612
24554
|
// http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
|
|
24613
24555
|
return /*#__PURE__*/React.createElement("div", {
|
|
24614
|
-
className: css(styles$
|
|
24556
|
+
className: css(styles$q.widthOverride, styleContainer && styles$q.container)
|
|
24615
24557
|
}, /*#__PURE__*/React.createElement("iframe", {
|
|
24616
24558
|
sandbox: sandboxOptions,
|
|
24617
24559
|
src: url,
|
|
@@ -24640,7 +24582,7 @@ CSProgram.defaultProps = {
|
|
|
24640
24582
|
// optional message
|
|
24641
24583
|
message: null
|
|
24642
24584
|
};
|
|
24643
|
-
const styles$
|
|
24585
|
+
const styles$q = StyleSheet.create({
|
|
24644
24586
|
// Override the inherited width from the perseus paragraph class
|
|
24645
24587
|
// 820 is minimum width for 420px editor and 400px canvas
|
|
24646
24588
|
widthOverride: {
|
|
@@ -24685,7 +24627,7 @@ class Definition extends React.Component {
|
|
|
24685
24627
|
}) => /*#__PURE__*/React.createElement(Popover, {
|
|
24686
24628
|
content: /*#__PURE__*/React.createElement(PopoverContentCore, {
|
|
24687
24629
|
color: "white",
|
|
24688
|
-
style: styles$
|
|
24630
|
+
style: styles$p.tooltipBody,
|
|
24689
24631
|
closeButtonVisible: true
|
|
24690
24632
|
}, /*#__PURE__*/React.createElement(Renderer, {
|
|
24691
24633
|
apiOptions: this.props.apiOptions,
|
|
@@ -24716,7 +24658,7 @@ Definition.defaultProps = {
|
|
|
24716
24658
|
togglePrompt: "define me",
|
|
24717
24659
|
definition: "definition goes here"
|
|
24718
24660
|
};
|
|
24719
|
-
const styles$
|
|
24661
|
+
const styles$p = {
|
|
24720
24662
|
tooltipBody: {
|
|
24721
24663
|
color: Color.offBlack,
|
|
24722
24664
|
fontSize: 20,
|
|
@@ -24922,15 +24864,15 @@ class Explanation extends React.Component {
|
|
|
24922
24864
|
const onClick = this._onClick;
|
|
24923
24865
|
if (isMobile) {
|
|
24924
24866
|
linkContainer = /*#__PURE__*/React.createElement("div", {
|
|
24925
|
-
className: css(styles$
|
|
24867
|
+
className: css(styles$o.linkContainer)
|
|
24926
24868
|
}, /*#__PURE__*/React.createElement("a", {
|
|
24927
|
-
className: css(styles$
|
|
24869
|
+
className: css(styles$o.mobileExplanationLink),
|
|
24928
24870
|
href: href,
|
|
24929
24871
|
onClick: onClick,
|
|
24930
24872
|
role: "button",
|
|
24931
24873
|
"aria-expanded": this.state.expanded
|
|
24932
24874
|
}, linkAnchor), this.state.expanded && /*#__PURE__*/React.createElement("svg", {
|
|
24933
|
-
className: css(styles$
|
|
24875
|
+
className: css(styles$o.disclosureArrow)
|
|
24934
24876
|
}, /*#__PURE__*/React.createElement("polygon", {
|
|
24935
24877
|
style: {
|
|
24936
24878
|
fill: backgroundColor
|
|
@@ -24943,13 +24885,13 @@ class Explanation extends React.Component {
|
|
|
24943
24885
|
// an anchor tag (if rendered in a modal) or a Wonder Blocks
|
|
24944
24886
|
// link component in lesson page, see: `article-page.jsx`.
|
|
24945
24887
|
linkContainer = /*#__PURE__*/React.createElement("div", {
|
|
24946
|
-
className: css(styles$
|
|
24888
|
+
className: css(styles$o.linkContainer, styles$o.articleLink)
|
|
24947
24889
|
}, /*#__PURE__*/React.createElement(Link, {
|
|
24948
|
-
className: css(styles$
|
|
24890
|
+
className: css(styles$o.explanationLink)
|
|
24949
24891
|
// HACK(michaelpolyak): WB Link doesn't passthrough
|
|
24950
24892
|
// class name.
|
|
24951
24893
|
,
|
|
24952
|
-
style: styles$
|
|
24894
|
+
style: styles$o.explanationLink,
|
|
24953
24895
|
href: href,
|
|
24954
24896
|
onClick: onClick,
|
|
24955
24897
|
role: "button",
|
|
@@ -24959,9 +24901,9 @@ class Explanation extends React.Component {
|
|
|
24959
24901
|
// NOTE: For exercises, the baseElements `Link` is an
|
|
24960
24902
|
// anchor tag, see: `perseus-api.jsx`.
|
|
24961
24903
|
linkContainer = /*#__PURE__*/React.createElement("div", {
|
|
24962
|
-
className: css(styles$
|
|
24904
|
+
className: css(styles$o.linkContainer, styles$o.exerciseLink)
|
|
24963
24905
|
}, /*#__PURE__*/React.createElement(Link, {
|
|
24964
|
-
className: css(styles$
|
|
24906
|
+
className: css(styles$o.explanationLink),
|
|
24965
24907
|
href: href,
|
|
24966
24908
|
onClick: onClick,
|
|
24967
24909
|
role: "button",
|
|
@@ -24969,11 +24911,11 @@ class Explanation extends React.Component {
|
|
|
24969
24911
|
}, `[${linkAnchor}]`));
|
|
24970
24912
|
}
|
|
24971
24913
|
}
|
|
24972
|
-
const expandedStyle = isMobile ? styles$
|
|
24914
|
+
const expandedStyle = isMobile ? styles$o.contentExpandedMobile : styles$o.contentExpanded;
|
|
24973
24915
|
return /*#__PURE__*/React.createElement("div", {
|
|
24974
|
-
className: css(styles$
|
|
24916
|
+
className: css(styles$o.container)
|
|
24975
24917
|
}, linkContainer, this.state.expanded && /*#__PURE__*/React.createElement("div", {
|
|
24976
|
-
className: css(styles$
|
|
24918
|
+
className: css(styles$o.content, isMobile && styles$o.contentMobile, this.state.expanded && expandedStyle)
|
|
24977
24919
|
// eslint-disable-next-line react/no-string-refs
|
|
24978
24920
|
,
|
|
24979
24921
|
ref: "content"
|
|
@@ -24997,7 +24939,7 @@ const verticalContentPadding = 10;
|
|
|
24997
24939
|
const arrowWidth = 30;
|
|
24998
24940
|
const arrowHeight = 14;
|
|
24999
24941
|
const backgroundColor = gray95;
|
|
25000
|
-
const styles$
|
|
24942
|
+
const styles$o = StyleSheet.create({
|
|
25001
24943
|
container: {
|
|
25002
24944
|
display: "inline",
|
|
25003
24945
|
position: "relative"
|
|
@@ -25102,15 +25044,15 @@ class GradedGroupAnswerBar extends React.Component {
|
|
|
25102
25044
|
onCheckAnswer,
|
|
25103
25045
|
onNextQuestion
|
|
25104
25046
|
} = this.props;
|
|
25105
|
-
const answerBarStyle = _extends({}, styles$
|
|
25047
|
+
const answerBarStyle = _extends({}, styles$n.answerBar, {
|
|
25106
25048
|
backgroundColor: answerBarState === "CORRECT" ? Color.offWhite : "white",
|
|
25107
25049
|
// Center the "Correct!" message only when there's no next question
|
|
25108
25050
|
justifyContent: answerBarState === "CORRECT" && !onNextQuestion ? "center" : "space-between"
|
|
25109
25051
|
});
|
|
25110
25052
|
const message = answerBarState === "INCORRECT" ? /*#__PURE__*/React.createElement("span", {
|
|
25111
|
-
style: styles$
|
|
25053
|
+
style: styles$n.text
|
|
25112
25054
|
}, /*#__PURE__*/React.createElement("span", {
|
|
25113
|
-
style: styles$
|
|
25055
|
+
style: styles$n.tryAgainIcon
|
|
25114
25056
|
}, /*#__PURE__*/React.createElement(InlineIcon, iconTryAgain)), /*#__PURE__*/React.createElement("span", {
|
|
25115
25057
|
style: {
|
|
25116
25058
|
marginLeft: 8
|
|
@@ -25129,7 +25071,7 @@ class GradedGroupAnswerBar extends React.Component {
|
|
|
25129
25071
|
return /*#__PURE__*/React.createElement("div", {
|
|
25130
25072
|
style: answerBarStyle
|
|
25131
25073
|
}, /*#__PURE__*/React.createElement("span", {
|
|
25132
|
-
style: styles$
|
|
25074
|
+
style: styles$n.text
|
|
25133
25075
|
}, /*#__PURE__*/React.createElement("span", {
|
|
25134
25076
|
style: {
|
|
25135
25077
|
fontSize: 28,
|
|
@@ -25151,7 +25093,7 @@ class GradedGroupAnswerBar extends React.Component {
|
|
|
25151
25093
|
}
|
|
25152
25094
|
}
|
|
25153
25095
|
const fontSize = 17;
|
|
25154
|
-
const styles$
|
|
25096
|
+
const styles$n = {
|
|
25155
25097
|
answerBar: {
|
|
25156
25098
|
display: "flex",
|
|
25157
25099
|
alignItems: "center",
|
|
@@ -25337,7 +25279,7 @@ class GradedGroup extends React.Component {
|
|
|
25337
25279
|
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
25338
25280
|
gradeStatus = i18n._("Incorrect");
|
|
25339
25281
|
}
|
|
25340
|
-
const mobileClass = this.props.inGradedGroupSet ? css(styles$
|
|
25282
|
+
const mobileClass = this.props.inGradedGroupSet ? css(styles$m.gradedGroupInSet) : css(styles$m.gradedGroup);
|
|
25341
25283
|
const classes = classNames({
|
|
25342
25284
|
[mobileClass]: apiOptions.isMobile,
|
|
25343
25285
|
"perseus-graded-group": true,
|
|
@@ -25356,7 +25298,7 @@ class GradedGroup extends React.Component {
|
|
|
25356
25298
|
return /*#__PURE__*/React.createElement("div", {
|
|
25357
25299
|
className: classes
|
|
25358
25300
|
}, !!this.props.title && /*#__PURE__*/React.createElement("div", {
|
|
25359
|
-
className: css(styles$
|
|
25301
|
+
className: css(styles$m.title)
|
|
25360
25302
|
}, this.props.title), /*#__PURE__*/React.createElement(Renderer, _extends({}, this.props, {
|
|
25361
25303
|
// eslint-disable-next-line react/no-string-refs
|
|
25362
25304
|
ref: "renderer",
|
|
@@ -25388,7 +25330,7 @@ class GradedGroup extends React.Component {
|
|
|
25388
25330
|
}, i18n._("Next question")), this.props.hint && this.props.hint.content && (this.state.showHint ? /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
|
|
25389
25331
|
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
|
|
25390
25332
|
tabIndex: "0",
|
|
25391
|
-
className: css(styles$
|
|
25333
|
+
className: css(styles$m.explanationTitle),
|
|
25392
25334
|
onClick: () => this.setState({
|
|
25393
25335
|
showHint: false
|
|
25394
25336
|
}),
|
|
@@ -25420,7 +25362,7 @@ class GradedGroup extends React.Component {
|
|
|
25420
25362
|
showHint: true
|
|
25421
25363
|
});
|
|
25422
25364
|
},
|
|
25423
|
-
className: css(styles$
|
|
25365
|
+
className: css(styles$m.showHintLink)
|
|
25424
25366
|
}, i18n._("Explain"))), apiOptions.isMobile && answerBarState !== "HIDDEN" && /*#__PURE__*/React.createElement(GradedGroupAnswerBar, {
|
|
25425
25367
|
apiOptions: apiOptions,
|
|
25426
25368
|
answerBarState: answerBarState,
|
|
@@ -25441,7 +25383,7 @@ GradedGroup.defaultProps = {
|
|
|
25441
25383
|
const traverseChildWidgets$3 = function traverseChildWidgets(props, traverseRenderer) {
|
|
25442
25384
|
return _.extend({}, props, traverseRenderer(props));
|
|
25443
25385
|
};
|
|
25444
|
-
const styles$
|
|
25386
|
+
const styles$m = StyleSheet.create({
|
|
25445
25387
|
gradedGroupInSet: {
|
|
25446
25388
|
// Reset a few desktop-only styles that come from graded-group.less
|
|
25447
25389
|
marginLeft: 0,
|
|
@@ -25514,18 +25456,18 @@ class Indicators extends React.Component {
|
|
|
25514
25456
|
return /*#__PURE__*/React.createElement("ul", {
|
|
25515
25457
|
// reduntantly add class name for use in .less files--
|
|
25516
25458
|
// the styles object key gets hashed
|
|
25517
|
-
className: classNames(css(styles$
|
|
25459
|
+
className: classNames(css(styles$l.indicatorContainer), "indicatorContainer")
|
|
25518
25460
|
}, this.props.gradedGroups.map(({
|
|
25519
25461
|
title
|
|
25520
25462
|
}, i) => /*#__PURE__*/React.createElement("li", {
|
|
25521
|
-
className: css(styles$
|
|
25463
|
+
className: css(styles$l.indicator),
|
|
25522
25464
|
key: title
|
|
25523
25465
|
}, /*#__PURE__*/React.createElement(Clickable, {
|
|
25524
25466
|
role: "button",
|
|
25525
25467
|
"aria-label": i18n._("Skip to %(title)s", {
|
|
25526
25468
|
title
|
|
25527
25469
|
}),
|
|
25528
|
-
style: styles$
|
|
25470
|
+
style: styles$l.indicatorButton,
|
|
25529
25471
|
onClick: () => this.props.onChangeCurrentGroup(i),
|
|
25530
25472
|
onKeyDown: e => this.handleKeyDown(e, i)
|
|
25531
25473
|
}, ({
|
|
@@ -25533,9 +25475,9 @@ class Indicators extends React.Component {
|
|
|
25533
25475
|
focused,
|
|
25534
25476
|
pressed
|
|
25535
25477
|
}) => /*#__PURE__*/React.createElement(View, {
|
|
25536
|
-
style: [styles$
|
|
25478
|
+
style: [styles$l.indicatorDot, (hovered || focused || pressed) && styles$l.indicatorDotFocused]
|
|
25537
25479
|
}, i === this.props.currentGroup && /*#__PURE__*/React.createElement(View, {
|
|
25538
|
-
style: styles$
|
|
25480
|
+
style: styles$l.indicatorDotActive
|
|
25539
25481
|
}, /*#__PURE__*/React.createElement("span", {
|
|
25540
25482
|
className: css(a11y.srOnly)
|
|
25541
25483
|
}, i18n._("Current"))))))));
|
|
@@ -25601,7 +25543,7 @@ class GradedGroupSet extends React.Component {
|
|
|
25601
25543
|
} = getDependencies();
|
|
25602
25544
|
if (JIPT.useJIPT && this.props.gradedGroups.length > 1) {
|
|
25603
25545
|
return /*#__PURE__*/React.createElement("div", {
|
|
25604
|
-
className: css(styles$
|
|
25546
|
+
className: css(styles$l.container)
|
|
25605
25547
|
}, this.props.gradedGroups.map((gradedGroup, i) => {
|
|
25606
25548
|
return (
|
|
25607
25549
|
/*#__PURE__*/
|
|
@@ -25624,13 +25566,13 @@ class GradedGroupSet extends React.Component {
|
|
|
25624
25566
|
const numGroups = this.props.gradedGroups.length;
|
|
25625
25567
|
const handleNextQuestion = this.state.currentGroup < numGroups - 1 ? this.handleNextQuestion : null;
|
|
25626
25568
|
return /*#__PURE__*/React.createElement("div", {
|
|
25627
|
-
className: css(styles$
|
|
25569
|
+
className: css(styles$l.container)
|
|
25628
25570
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25629
|
-
className: css(styles$
|
|
25571
|
+
className: css(styles$l.top)
|
|
25630
25572
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25631
|
-
className: css(styles$
|
|
25573
|
+
className: css(styles$l.title)
|
|
25632
25574
|
}, currentGroup.title), /*#__PURE__*/React.createElement("div", {
|
|
25633
|
-
className: css(styles$
|
|
25575
|
+
className: css(styles$l.spacer)
|
|
25634
25576
|
}), /*#__PURE__*/React.createElement(Indicators, {
|
|
25635
25577
|
currentGroup: this.state.currentGroup,
|
|
25636
25578
|
gradedGroups: this.props.gradedGroups,
|
|
@@ -25672,7 +25614,7 @@ var GradedGroupSet$1 = {
|
|
|
25672
25614
|
tracking: "all",
|
|
25673
25615
|
isLintable: true
|
|
25674
25616
|
};
|
|
25675
|
-
const styles$
|
|
25617
|
+
const styles$l = StyleSheet.create({
|
|
25676
25618
|
top: {
|
|
25677
25619
|
display: "flex",
|
|
25678
25620
|
flexDirection: "row"
|
|
@@ -25777,7 +25719,7 @@ class ButtonGroup extends React.Component {
|
|
|
25777
25719
|
id: "" + i,
|
|
25778
25720
|
ref: "button" + i,
|
|
25779
25721
|
key: "" + i,
|
|
25780
|
-
className: css(styles$
|
|
25722
|
+
className: css(styles$k.buttonStyle, button.value === value && styles$k.selectedStyle),
|
|
25781
25723
|
onClick: () => this.toggleSelect(button.value)
|
|
25782
25724
|
}, button.content || "" + button.value);
|
|
25783
25725
|
});
|
|
@@ -25794,7 +25736,7 @@ ButtonGroup.defaultProps = {
|
|
|
25794
25736
|
value: null,
|
|
25795
25737
|
allowEmpty: true
|
|
25796
25738
|
};
|
|
25797
|
-
const styles$
|
|
25739
|
+
const styles$k = StyleSheet.create({
|
|
25798
25740
|
buttonStyle: {
|
|
25799
25741
|
backgroundColor: "white",
|
|
25800
25742
|
border: "1px solid #ccc",
|
|
@@ -31078,7 +31020,7 @@ const HideAnswersToggle = props => {
|
|
|
31078
31020
|
const switchId = idFactory.get("hide-answers-toggle");
|
|
31079
31021
|
const labelId = idFactory.get("hide-answers-label");
|
|
31080
31022
|
return /*#__PURE__*/React.createElement(View, {
|
|
31081
|
-
style: styles$
|
|
31023
|
+
style: styles$j.switchWrapper
|
|
31082
31024
|
}, /*#__PURE__*/React.createElement(Switch, {
|
|
31083
31025
|
id: switchId,
|
|
31084
31026
|
checked: props.areAnswersHidden,
|
|
@@ -31090,7 +31032,7 @@ const HideAnswersToggle = props => {
|
|
|
31090
31032
|
tag: "label"
|
|
31091
31033
|
}, strings.hideAnswersToggleLabel));
|
|
31092
31034
|
};
|
|
31093
|
-
const styles$
|
|
31035
|
+
const styles$j = StyleSheet.create({
|
|
31094
31036
|
switchWrapper: {
|
|
31095
31037
|
display: "flex",
|
|
31096
31038
|
flexDirection: "row",
|
|
@@ -31143,13 +31085,13 @@ const AnswerPill = props => {
|
|
|
31143
31085
|
id: idFactory.get("perseus-label-image-widget-answer-pill"),
|
|
31144
31086
|
onClick: correct ? undefined : onClick,
|
|
31145
31087
|
ref: ref,
|
|
31146
|
-
style: [style, popperStyle, styles$
|
|
31088
|
+
style: [style, popperStyle, styles$i.pill, correct && styles$i.correct, incorrect && styles$i.incorrect, (focused || hovered) && BringToFront]
|
|
31147
31089
|
}, /*#__PURE__*/React.createElement(Renderer, {
|
|
31148
31090
|
content: answerString,
|
|
31149
31091
|
inline: true
|
|
31150
31092
|
})));
|
|
31151
31093
|
};
|
|
31152
|
-
const styles$
|
|
31094
|
+
const styles$i = StyleSheet.create({
|
|
31153
31095
|
correct: {
|
|
31154
31096
|
// WB green darkened by 18%
|
|
31155
31097
|
backgroundColor: "#00880b"
|
|
@@ -31202,23 +31144,23 @@ class Marker extends React.Component {
|
|
|
31202
31144
|
icon: iconNull
|
|
31203
31145
|
};
|
|
31204
31146
|
if (showCorrectness) {
|
|
31205
|
-
iconStyles = [styles$
|
|
31147
|
+
iconStyles = [styles$h.markerGraded, showCorrectness === "correct" ? styles$h.markerCorrect : styles$h.markerIncorrect, isOpen && styles$h.markerSelected];
|
|
31206
31148
|
args = _extends({}, args, {
|
|
31207
31149
|
icon: showCorrectness === "correct" ? iconCheck : iconMinus
|
|
31208
31150
|
});
|
|
31209
31151
|
} else if (selectedAnswers && selectedAnswers.length > 0) {
|
|
31210
|
-
iconStyles = [styles$
|
|
31152
|
+
iconStyles = [styles$h.markerFilled, isOpen && styles$h.markerSelected];
|
|
31211
31153
|
} else if (isOpen) {
|
|
31212
|
-
iconStyles = [styles$
|
|
31154
|
+
iconStyles = [styles$h.markerSelected];
|
|
31213
31155
|
args = _extends({}, args, {
|
|
31214
31156
|
icon: iconChevronDown,
|
|
31215
31157
|
size: 8
|
|
31216
31158
|
});
|
|
31217
31159
|
} else if (showPulsate) {
|
|
31218
|
-
iconStyles = [styles$
|
|
31160
|
+
iconStyles = [styles$h.markerPulsateBase, shouldReduceMotion() ? showPulsate && styles$h.markerUnfilledPulsateOnce : showPulsate && styles$h.markerUnfilledPulsateInfinite];
|
|
31219
31161
|
}
|
|
31220
31162
|
return /*#__PURE__*/React.createElement(View, {
|
|
31221
|
-
style: [styles$
|
|
31163
|
+
style: [styles$h.markerIcon, iconStyles],
|
|
31222
31164
|
ref: node => this._icon = node
|
|
31223
31165
|
}, /*#__PURE__*/React.createElement(Icon, args));
|
|
31224
31166
|
}
|
|
@@ -31240,7 +31182,7 @@ class Marker extends React.Component {
|
|
|
31240
31182
|
const markerDisabled = showCorrectness === "correct";
|
|
31241
31183
|
const active = hovered || focused;
|
|
31242
31184
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
|
|
31243
|
-
style: [styles$
|
|
31185
|
+
style: [styles$h.marker, active && !markerDisabled && styles$h.markerActive]
|
|
31244
31186
|
// already translated in: /widgets/graded-group.tsx
|
|
31245
31187
|
,
|
|
31246
31188
|
"aria-label": markerDisabled ? i18n._("Correct!") : label
|
|
@@ -31258,7 +31200,7 @@ class Marker extends React.Component {
|
|
|
31258
31200
|
Marker.defaultProps = {
|
|
31259
31201
|
selected: []
|
|
31260
31202
|
};
|
|
31261
|
-
const styles$
|
|
31203
|
+
const styles$h = StyleSheet.create({
|
|
31262
31204
|
marker: {
|
|
31263
31205
|
position: "absolute",
|
|
31264
31206
|
backgroundColor: Color.white,
|
|
@@ -31828,13 +31770,13 @@ class LabelImage extends React.Component {
|
|
|
31828
31770
|
const promptString = isMobile ? multipleAnswers ? i18n._("Tap each dot on the image to select all answers that apply.") : i18n._("Tap each dot on the image to select an answer.") : multipleAnswers ? i18n._("Click each dot on the image to select all answers that apply.") : i18n._("Click each dot on the image to select an answer.");
|
|
31829
31771
|
const choicesString = i18n._("Choices:");
|
|
31830
31772
|
return /*#__PURE__*/React.createElement("div", {
|
|
31831
|
-
className: classNames("perseus-label-image-widget-instructions", css(styles$
|
|
31773
|
+
className: classNames("perseus-label-image-widget-instructions", css(styles$g.instructions))
|
|
31832
31774
|
}, /*#__PURE__*/React.createElement("div", {
|
|
31833
|
-
className: css(styles$
|
|
31775
|
+
className: css(styles$g.instructionsCaption)
|
|
31834
31776
|
}, promptString, " ", !hideChoices && choicesString), !hideChoices && /*#__PURE__*/React.createElement("div", {
|
|
31835
|
-
className: css(styles$
|
|
31777
|
+
className: css(styles$g.instructionsChoices)
|
|
31836
31778
|
}, choices.map((choice, index) => /*#__PURE__*/React.createElement("div", {
|
|
31837
|
-
className: css(styles$
|
|
31779
|
+
className: css(styles$g.instructionsChoice),
|
|
31838
31780
|
key: index
|
|
31839
31781
|
}, /*#__PURE__*/React.createElement(Renderer, {
|
|
31840
31782
|
content: choice
|
|
@@ -31851,20 +31793,20 @@ class LabelImage extends React.Component {
|
|
|
31851
31793
|
activeMarkerIndex
|
|
31852
31794
|
} = this.state;
|
|
31853
31795
|
return /*#__PURE__*/React.createElement("div", null, this.renderInstructions(), /*#__PURE__*/React.createElement("div", {
|
|
31854
|
-
className: css(styles$
|
|
31796
|
+
className: css(styles$g.markersCanvas),
|
|
31855
31797
|
style: {
|
|
31856
31798
|
maxWidth: imageWidth,
|
|
31857
31799
|
maxHeight: imageHeight
|
|
31858
31800
|
}
|
|
31859
31801
|
}, /*#__PURE__*/React.createElement("div", {
|
|
31860
|
-
className: css(styles$
|
|
31802
|
+
className: css(styles$g.imageContainer,
|
|
31861
31803
|
// Ensure image interaction is disabled while answer
|
|
31862
31804
|
// choices popup is visible. This addresses specific
|
|
31863
31805
|
// case where user may click on question image to
|
|
31864
31806
|
// dismiss the popup. If the image is larger in size
|
|
31865
31807
|
// than its rendered in the widget, this would
|
|
31866
31808
|
// result in a zoom of the image.
|
|
31867
|
-
activeMarkerIndex !== -1 && styles$
|
|
31809
|
+
activeMarkerIndex !== -1 && styles$g.imageInteractionDisabled)
|
|
31868
31810
|
}, /*#__PURE__*/React.createElement(context$1.Consumer, null, ({
|
|
31869
31811
|
setAssetStatus
|
|
31870
31812
|
}) => /*#__PURE__*/React.createElement(SvgImage, {
|
|
@@ -31888,7 +31830,7 @@ class LabelImage extends React.Component {
|
|
|
31888
31830
|
}));
|
|
31889
31831
|
}
|
|
31890
31832
|
}
|
|
31891
|
-
const styles$
|
|
31833
|
+
const styles$g = StyleSheet.create({
|
|
31892
31834
|
instructions: {
|
|
31893
31835
|
paddingBottom: 16
|
|
31894
31836
|
},
|
|
@@ -32245,7 +32187,7 @@ class Placeholder extends React.Component {
|
|
|
32245
32187
|
const {
|
|
32246
32188
|
layout
|
|
32247
32189
|
} = this.props;
|
|
32248
|
-
const className = css(styles$
|
|
32190
|
+
const className = css(styles$f.card, styles$f.placeholder, layout === Layout.HORIZONTAL && styles$f.horizontalCard);
|
|
32249
32191
|
const style = {
|
|
32250
32192
|
width: this.props.width,
|
|
32251
32193
|
height: this.props.height
|
|
@@ -32428,7 +32370,7 @@ class Draggable extends React.Component {
|
|
|
32428
32370
|
// We need to keep backwards compatbility with rules specified directly
|
|
32429
32371
|
// in CSS. Hence the hacky tacking on of manual classNames.
|
|
32430
32372
|
// See sortable.less for details.
|
|
32431
|
-
let className = css(styles$
|
|
32373
|
+
let className = css(styles$f.card, styles$f.draggable, layout === Layout.HORIZONTAL && styles$f.horizontalCard, layout === Layout.VERTICAL && styles$f.verticalCard, type === ItemState.DRAGGING && styles$f.dragging, type === ItemState.DISABLED && styles$f.disabled, !includePadding && styles$f.unpaddedCard) + " " + ClassNames.INTERACTIVE + " perseus-sortable-draggable";
|
|
32432
32374
|
if (!includePadding) {
|
|
32433
32375
|
className += " perseus-sortable-draggable-unpadded";
|
|
32434
32376
|
}
|
|
@@ -32635,7 +32577,7 @@ class Sortable extends React.Component {
|
|
|
32635
32577
|
} = this.props;
|
|
32636
32578
|
// We need to keep backwards compatbility with rules specified directly
|
|
32637
32579
|
// in CSS. See sortable.less for details.
|
|
32638
|
-
const className = css(styles$
|
|
32580
|
+
const className = css(styles$f.sortable) + " perseus-sortable";
|
|
32639
32581
|
const syncWidth = ((_this$props$constrain = this.props.constraints) == null ? void 0 : _this$props$constrain.width) || layout === Layout.VERTICAL;
|
|
32640
32582
|
const syncHeight = ((_this$props$constrain2 = this.props.constraints) == null ? void 0 : _this$props$constrain2.height) || layout === Layout.HORIZONTAL;
|
|
32641
32583
|
_.each(this.state.items, function (item, i, items) {
|
|
@@ -32877,7 +32819,7 @@ Sortable.defaultProps = {
|
|
|
32877
32819
|
linterContext: PerseusLinter.linterContextDefault,
|
|
32878
32820
|
waitForTexRendererToLoad: true
|
|
32879
32821
|
};
|
|
32880
|
-
const styles$
|
|
32822
|
+
const styles$f = StyleSheet.create({
|
|
32881
32823
|
sortable: {
|
|
32882
32824
|
boxSizing: "border-box",
|
|
32883
32825
|
float: "left",
|
|
@@ -33039,23 +32981,23 @@ class Matcher extends React.Component {
|
|
|
33039
32981
|
};
|
|
33040
32982
|
const cellMarginPx = this.props.apiOptions.isMobile ? 8 : 5;
|
|
33041
32983
|
return /*#__PURE__*/React.createElement("table", {
|
|
33042
|
-
className: css(styles$
|
|
32984
|
+
className: css(styles$e.widget) + " " + HACKY_CSS_CLASSNAME
|
|
33043
32985
|
}, /*#__PURE__*/React.createElement("tbody", null, showLabels && /*#__PURE__*/React.createElement("tr", {
|
|
33044
|
-
className: css(styles$
|
|
32986
|
+
className: css(styles$e.row)
|
|
33045
32987
|
}, /*#__PURE__*/React.createElement("th", {
|
|
33046
|
-
className: css(styles$
|
|
32988
|
+
className: css(styles$e.column, styles$e.columnLabel)
|
|
33047
32989
|
}, /*#__PURE__*/React.createElement(Renderer, {
|
|
33048
32990
|
content: this.props.labels[0] || "...",
|
|
33049
32991
|
linterContext: this.props.linterContext
|
|
33050
32992
|
})), /*#__PURE__*/React.createElement("th", {
|
|
33051
|
-
className: css(styles$
|
|
32993
|
+
className: css(styles$e.column, styles$e.columnRight, styles$e.columnLabel)
|
|
33052
32994
|
}, /*#__PURE__*/React.createElement(Renderer, {
|
|
33053
32995
|
content: this.props.labels[1] || "...",
|
|
33054
32996
|
linterContext: this.props.linterContext
|
|
33055
32997
|
}))), /*#__PURE__*/React.createElement("tr", {
|
|
33056
|
-
className: css(styles$
|
|
32998
|
+
className: css(styles$e.row)
|
|
33057
32999
|
}, /*#__PURE__*/React.createElement("td", {
|
|
33058
|
-
className: css(styles$
|
|
33000
|
+
className: css(styles$e.column)
|
|
33059
33001
|
}, /*#__PURE__*/React.createElement(Sortable, {
|
|
33060
33002
|
options: left,
|
|
33061
33003
|
layout: Layout.VERTICAL,
|
|
@@ -33070,7 +33012,7 @@ class Matcher extends React.Component {
|
|
|
33070
33012
|
,
|
|
33071
33013
|
ref: "left"
|
|
33072
33014
|
})), /*#__PURE__*/React.createElement("td", {
|
|
33073
|
-
className: css(styles$
|
|
33015
|
+
className: css(styles$e.column, styles$e.columnRight)
|
|
33074
33016
|
}, /*#__PURE__*/React.createElement(Sortable
|
|
33075
33017
|
// @ts-expect-error - TS2322 - Type 'readonly unknown[]' is not assignable to type 'readonly string[]'.
|
|
33076
33018
|
, {
|
|
@@ -33123,7 +33065,7 @@ _.extend(Matcher, {
|
|
|
33123
33065
|
});
|
|
33124
33066
|
const padding = 5;
|
|
33125
33067
|
const border = "1px solid #444";
|
|
33126
|
-
const styles$
|
|
33068
|
+
const styles$e = StyleSheet.create({
|
|
33127
33069
|
widget: {
|
|
33128
33070
|
paddingTop: padding,
|
|
33129
33071
|
maxWidth: "100%",
|
|
@@ -33990,9 +33932,9 @@ function drawText(ctx, item) {
|
|
|
33990
33932
|
if (item.value === null) {
|
|
33991
33933
|
return;
|
|
33992
33934
|
}
|
|
33993
|
-
ctx.fillStyle = styles$
|
|
33994
|
-
ctx.font = styles$
|
|
33995
|
-
ctx.fillText(item.value, item.pos[0] - styles$
|
|
33935
|
+
ctx.fillStyle = styles$d.fgColor;
|
|
33936
|
+
ctx.font = styles$d.font;
|
|
33937
|
+
ctx.fillText(item.value, item.pos[0] - styles$d.fontSizePx / 2 + 1, item.pos[1] + styles$d.fontSizePx / 2);
|
|
33996
33938
|
}
|
|
33997
33939
|
|
|
33998
33940
|
/**
|
|
@@ -34013,16 +33955,16 @@ function drawText(ctx, item) {
|
|
|
34013
33955
|
function drawDoubleLine(ctx, item) {
|
|
34014
33956
|
// Outer line that forms both of the bond lines.
|
|
34015
33957
|
let path = new Path2D();
|
|
34016
|
-
ctx.lineWidth = 5 * styles$
|
|
34017
|
-
ctx.strokeStyle = styles$
|
|
33958
|
+
ctx.lineWidth = 5 * styles$d.lineWidth;
|
|
33959
|
+
ctx.strokeStyle = styles$d.fgColor;
|
|
34018
33960
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
34019
33961
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
34020
33962
|
ctx.stroke(path);
|
|
34021
33963
|
|
|
34022
33964
|
// Inner white line that separates the two bond lines.
|
|
34023
33965
|
path = new Path2D();
|
|
34024
|
-
ctx.lineWidth = 3 * styles$
|
|
34025
|
-
ctx.strokeStyle = styles$
|
|
33966
|
+
ctx.lineWidth = 3 * styles$d.lineWidth;
|
|
33967
|
+
ctx.strokeStyle = styles$d.bgColor;
|
|
34026
33968
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
34027
33969
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
34028
33970
|
ctx.stroke(path);
|
|
@@ -34049,16 +33991,16 @@ function drawTripleLine(ctx, item) {
|
|
|
34049
33991
|
|
|
34050
33992
|
// Outer line that will form the two outer bond lines.
|
|
34051
33993
|
let path = new Path2D();
|
|
34052
|
-
ctx.lineWidth = 7 * styles$
|
|
34053
|
-
ctx.strokeStyle = styles$
|
|
33994
|
+
ctx.lineWidth = 7 * styles$d.lineWidth;
|
|
33995
|
+
ctx.strokeStyle = styles$d.fgColor;
|
|
34054
33996
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
34055
33997
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
34056
33998
|
ctx.stroke(path);
|
|
34057
33999
|
|
|
34058
34000
|
// Middle white line that separates the bonds
|
|
34059
34001
|
path = new Path2D();
|
|
34060
|
-
ctx.lineWidth = 5 * styles$
|
|
34061
|
-
ctx.strokeStyle = styles$
|
|
34002
|
+
ctx.lineWidth = 5 * styles$d.lineWidth;
|
|
34003
|
+
ctx.strokeStyle = styles$d.bgColor;
|
|
34062
34004
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
34063
34005
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
34064
34006
|
ctx.stroke(path);
|
|
@@ -34080,8 +34022,8 @@ function drawTripleLine(ctx, item) {
|
|
|
34080
34022
|
*/
|
|
34081
34023
|
function drawLine(ctx, item) {
|
|
34082
34024
|
const path = new Path2D();
|
|
34083
|
-
ctx.lineWidth = styles$
|
|
34084
|
-
ctx.strokeStyle = styles$
|
|
34025
|
+
ctx.lineWidth = styles$d.lineWidth;
|
|
34026
|
+
ctx.strokeStyle = styles$d.fgColor;
|
|
34085
34027
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
34086
34028
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
34087
34029
|
ctx.stroke(path);
|
|
@@ -34133,7 +34075,7 @@ function compareElements(item0, item1) {
|
|
|
34133
34075
|
function draw(ctx, items) {
|
|
34134
34076
|
items.sort(compareElements).forEach(drawItem(ctx));
|
|
34135
34077
|
}
|
|
34136
|
-
const styles$
|
|
34078
|
+
const styles$d = {
|
|
34137
34079
|
bgColor: "rgb(255, 255, 255)",
|
|
34138
34080
|
fgColor: "rgb(0, 0, 0)",
|
|
34139
34081
|
fontSizePx: 12,
|
|
@@ -36695,7 +36637,7 @@ class HighlightRenderer extends React.PureComponent {
|
|
|
36695
36637
|
const rects = this.state.cachedHighlightRects;
|
|
36696
36638
|
return /*#__PURE__*/React.createElement("div", null, rects.map((rect, index) => /*#__PURE__*/React.createElement("div", {
|
|
36697
36639
|
key: index,
|
|
36698
|
-
className: css(styles$
|
|
36640
|
+
className: css(styles$c.highlightRect),
|
|
36699
36641
|
style: {
|
|
36700
36642
|
// NOTE(mdr): We apply `position: absolute` here
|
|
36701
36643
|
// rather than in Aphrodite styles, because
|
|
@@ -36714,7 +36656,7 @@ class HighlightRenderer extends React.PureComponent {
|
|
|
36714
36656
|
})));
|
|
36715
36657
|
}
|
|
36716
36658
|
}
|
|
36717
|
-
const styles$
|
|
36659
|
+
const styles$c = StyleSheet.create({
|
|
36718
36660
|
highlightRect: {
|
|
36719
36661
|
background: "#fffabe" // highlighter yellow :)
|
|
36720
36662
|
}
|
|
@@ -36795,7 +36737,7 @@ class HighlightTooltip extends React.PureComponent {
|
|
|
36795
36737
|
// TooltipContent wouldn't let me overwrite
|
|
36796
36738
|
// user-select and onClick
|
|
36797
36739
|
const content = /*#__PURE__*/React.createElement("div", {
|
|
36798
|
-
className: css(styles$
|
|
36740
|
+
className: css(styles$b.tooltipLabel),
|
|
36799
36741
|
onClick: this.props.onClick
|
|
36800
36742
|
}, this.props.label);
|
|
36801
36743
|
const style = {
|
|
@@ -36815,7 +36757,7 @@ class HighlightTooltip extends React.PureComponent {
|
|
|
36815
36757
|
}, /*#__PURE__*/React.createElement("div", null)));
|
|
36816
36758
|
}
|
|
36817
36759
|
}
|
|
36818
|
-
const styles$
|
|
36760
|
+
const styles$b = StyleSheet.create({
|
|
36819
36761
|
tooltipLabel: {
|
|
36820
36762
|
// Unlike most tooltip contents, we don't want this label to be
|
|
36821
36763
|
// selectable. Selecting it is not only unhelpful, but dangerous: if
|
|
@@ -37367,7 +37309,7 @@ class HighlightableContent extends React.PureComponent {
|
|
|
37367
37309
|
// starting point: https://phabricator.khanacademy.org/D35623?id=170698
|
|
37368
37310
|
const buildHighlight = r => this._buildHighlight(r);
|
|
37369
37311
|
return /*#__PURE__*/React.createElement("div", {
|
|
37370
|
-
className: css(styles$
|
|
37312
|
+
className: css(styles$a.container),
|
|
37371
37313
|
ref: container => this._container = container
|
|
37372
37314
|
}, /*#__PURE__*/React.createElement("div", null, this.props.enabled && this._container && this._content && /*#__PURE__*/React.createElement(HighlightingUI, {
|
|
37373
37315
|
buildHighlight: buildHighlight,
|
|
@@ -37388,14 +37330,14 @@ class HighlightableContent extends React.PureComponent {
|
|
|
37388
37330
|
onAddHighlight: this._handleAddHighlight,
|
|
37389
37331
|
onRemoveHighlight: this._handleRemoveHighlight
|
|
37390
37332
|
})), /*#__PURE__*/React.createElement("div", {
|
|
37391
|
-
className: css(styles$
|
|
37333
|
+
className: css(styles$a.content),
|
|
37392
37334
|
ref: content => this._content = content
|
|
37393
37335
|
}, /*#__PURE__*/React.createElement(WordIndexer, {
|
|
37394
37336
|
onWordsUpdate: this._handleWordsUpdate
|
|
37395
37337
|
}, this.props.children)));
|
|
37396
37338
|
}
|
|
37397
37339
|
}
|
|
37398
|
-
const styles$
|
|
37340
|
+
const styles$a = StyleSheet.create({
|
|
37399
37341
|
// We render content with z-index 1, and highlights with z-index 0, so that
|
|
37400
37342
|
// content will receive the browser's native pointer events. (Highlights
|
|
37401
37343
|
// have their own magic code to manage hover detection, despite being
|
|
@@ -37795,7 +37737,7 @@ class LineHeightMeasurer extends React.Component {
|
|
|
37795
37737
|
}
|
|
37796
37738
|
render() {
|
|
37797
37739
|
return /*#__PURE__*/React.createElement("div", {
|
|
37798
|
-
className: css(styles$
|
|
37740
|
+
className: css(styles$9.measurer),
|
|
37799
37741
|
"aria-hidden": "true"
|
|
37800
37742
|
}, /*#__PURE__*/React.createElement("div", {
|
|
37801
37743
|
ref: ref => this._line = ref,
|
|
@@ -37803,7 +37745,7 @@ class LineHeightMeasurer extends React.Component {
|
|
|
37803
37745
|
}, "Line Height Measurement"));
|
|
37804
37746
|
}
|
|
37805
37747
|
}
|
|
37806
|
-
const styles$
|
|
37748
|
+
const styles$9 = StyleSheet.create({
|
|
37807
37749
|
measurer: {
|
|
37808
37750
|
position: "absolute",
|
|
37809
37751
|
top: 0,
|
|
@@ -39093,6 +39035,52 @@ var Plotter$1 = {
|
|
|
39093
39035
|
staticTransform: staticTransform
|
|
39094
39036
|
};
|
|
39095
39037
|
|
|
39038
|
+
/**
|
|
39039
|
+
* This widget is for embedding Khan Academy Python programs.
|
|
39040
|
+
*/
|
|
39041
|
+
function getUrlFromProgramID(programID) {
|
|
39042
|
+
const path = `/python-program/${programID}/embedded`;
|
|
39043
|
+
return toAbsoluteUrl(path);
|
|
39044
|
+
}
|
|
39045
|
+
/* This renders the program in an iframe. */
|
|
39046
|
+
class PythonProgram extends React.Component {
|
|
39047
|
+
render() {
|
|
39048
|
+
const url = getUrlFromProgramID(this.props.programID);
|
|
39049
|
+
const iframeStyle = {
|
|
39050
|
+
height: this.props.height,
|
|
39051
|
+
width: "100%"
|
|
39052
|
+
};
|
|
39053
|
+
const sandboxOptions = ["allow-popups", "allow-same-origin", "allow-scripts", "allow-top-navigation"].join(" ");
|
|
39054
|
+
|
|
39055
|
+
// We sandbox the iframe so that we allowlist only the functionality
|
|
39056
|
+
// that we need. This makes it a bit safer in case some content
|
|
39057
|
+
// creator "went wild".
|
|
39058
|
+
// http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
|
|
39059
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
39060
|
+
style: styles$8.container
|
|
39061
|
+
}, /*#__PURE__*/React.createElement("iframe", {
|
|
39062
|
+
sandbox: sandboxOptions,
|
|
39063
|
+
src: url,
|
|
39064
|
+
style: iframeStyle,
|
|
39065
|
+
allowFullScreen: true
|
|
39066
|
+
}));
|
|
39067
|
+
}
|
|
39068
|
+
}
|
|
39069
|
+
PythonProgram.defaultProps = {
|
|
39070
|
+
height: 400
|
|
39071
|
+
};
|
|
39072
|
+
const styles$8 = StyleSheet.create({
|
|
39073
|
+
container: {
|
|
39074
|
+
margin: "auto",
|
|
39075
|
+
width: "100%"
|
|
39076
|
+
}
|
|
39077
|
+
});
|
|
39078
|
+
var PythonProgram$1 = {
|
|
39079
|
+
name: "python-program",
|
|
39080
|
+
displayName: "Python Program",
|
|
39081
|
+
widget: PythonProgram
|
|
39082
|
+
};
|
|
39083
|
+
|
|
39096
39084
|
class Separator extends React.Component {
|
|
39097
39085
|
constructor(...args) {
|
|
39098
39086
|
super(...args);
|
|
@@ -41528,7 +41516,7 @@ var Video$1 = {
|
|
|
41528
41516
|
};
|
|
41529
41517
|
|
|
41530
41518
|
/* eslint-disable import/no-named-as-default */
|
|
41531
|
-
var extraWidgets = [Categorizer$1, CSProgram$1, Dropdown$1, Explanation$1, Definition$1, Grapher$1, GradedGroup$1, GradedGroupSet$1, Group$1, Iframe$1, Image$1, Interactive, InteractiveGraph$1, LabelImage$1, LightsPuzzle$1, Matrix$1, Matcher$1, Measurer$1, Molecule$1, NumberLine$1, Orderer$1, Passage$1, PassageRef$1, PassageRefTarget$1, Plotter$1, ReactionDiagram, Sequence$1, Simulator$1, Sorter$1, Table$1, Unit, Video$1, DeprecatedStandin$1];
|
|
41519
|
+
var extraWidgets = [Categorizer$1, CSProgram$1, Dropdown$1, Explanation$1, Definition$1, Grapher$1, GradedGroup$1, GradedGroupSet$1, Group$1, Iframe$1, Image$1, Interactive, InteractiveGraph$1, LabelImage$1, LightsPuzzle$1, Matrix$1, Matcher$1, Measurer$1, Molecule$1, NumberLine$1, Orderer$1, Passage$1, PassageRef$1, PassageRefTarget$1, Plotter$1, PythonProgram$1, ReactionDiagram, Sequence$1, Simulator$1, Sorter$1, Table$1, Unit, Video$1, DeprecatedStandin$1];
|
|
41532
41520
|
|
|
41533
41521
|
/**
|
|
41534
41522
|
* This should be called by all clients, specifying whether extra widgets are
|
|
@@ -41568,7 +41556,7 @@ const init = function init(options) {
|
|
|
41568
41556
|
|
|
41569
41557
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41570
41558
|
const libName = "@khanacademy/perseus";
|
|
41571
|
-
const libVersion = "19.1
|
|
41559
|
+
const libVersion = "19.2.1";
|
|
41572
41560
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41573
41561
|
|
|
41574
41562
|
const apiVersion = {
|
|
@@ -43014,6 +43002,8 @@ const ItemExtras = [
|
|
|
43014
43002
|
|
|
43015
43003
|
// prettier-ignore
|
|
43016
43004
|
|
|
43005
|
+
// prettier-ignore
|
|
43006
|
+
|
|
43017
43007
|
//prettier-ignore
|
|
43018
43008
|
|
|
43019
43009
|
// A background image applied to various widgets.
|